Okay, so I am trying to get the most basic SFML hello world program working. I don't have any experience with Android development so I downloaded Android Studio (2024.2.2) and I can get their project templates to work, they execute on my phone, I can debug them, etc.
So this is my setup:
New project -> Game Activity (C++)
Language: Java
Min SDK: API 30 (Android 11)
Build config language: Kotlin DSL
C++ standard: Toolchain default
In gradle.build.kts, I've bumped cmake to version 3.28.1
My CMakeLists.txt, has been adapted from the official example:
cmake_minimum_required ( VERSION 3.28.1 )
include ( CPM.cmake )
project("myapp")
CPMAddPackage ( "gh:SFML/SFML#3.0.0" )
add_library(${PROJECT_NAME} SHARED
main.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE SFML::Graphics android log)
# The ANativeActivity_onCreate function from SFML::Main needs to be exposed in
# our libsfml-example.so file so that is can be loaded at runtime.
target_link_libraries(${PROJECT_NAME} PUBLIC
-Wl,--whole-archive
SFML::Main
-Wl,--no-whole-archive
)
Note that I'd like to build from source as I don't know what NDK is. I'd like to have as minimal build as possible.
Main.cpp:
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <android/native_activity.h>
#include <jni.h>
#include <SFML/System/NativeActivity.hpp>
int main(int argc, char *argv[])
{
sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");
window.setFramerateLimit(30);
const sf::Texture texture; // didn't get to "loading resources part yet"
sf::Sprite image(texture);
image.setPosition(sf::Vector2f(window.getSize()) / 2.f);
image.setOrigin(sf::Vector2f(texture.getSize()) / 2.f);
while (window.isOpen())
{
while (const auto event = window.pollEvent())
{
if (event->is<sf::Event::Closed>()) window.close();
}
window.clear();
window.draw(image);
window.display();
}
}
Everything compiles fine, but when I try to execute the application, it immediately crashes. It succeeds in loading the shared library but I get the following exception:
Process: com.example.myapp, PID: 22349
java.lang.UnsatisfiedLinkError: No implementation found for long com.google.androidgamesdk.GameActivity.initializeNativeCode(java.lang.String, java.lang.String, java.lang.String, android.content.res.AssetManager, byte[]) (tried Java_com_google_androidgamesdk_GameActivity_initializeNativeCode and Java_com_google_androidgamesdk_GameActivity_initializeNativeCode__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Landroid_content_res_AssetManager_2_3B) - is the library loaded, e.g. System.loadLibrary?
at com.google.androidgamesdk.GameActivity.initializeNativeCode(Native Method)
at com.google.androidgamesdk.GameActivity.onCreate(GameActivity.java:271)
at android.app.Activity.performCreate(Activity.java:8732)
at android.app.Activity.performCreate(Activity.java:8710)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3880)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4042)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2548)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loopOnce(Looper.java:242)
at android.os.Looper.loop(Looper.java:362)
at android.app.ActivityThread.main(ActivityThread.java:8407)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:992)
I assume it means the appropriate functions are missing in the shared library, but I can't figure out what's missing. I even tried setting the following, based on the advice from developer.android.com migration guide:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
Can anybody help?