Android export with "custom build" enabled fails to find native .so libraries

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By NarcoticV

(Note: edited to have a minimal example)

Hi everyone!

It seems that the Android “Use custom build” template is not compatible with including .so libraries - or at least not with those included in the “godot_ovrmobile” addon for Oculus Quest 2.

Minimal example: I started an empty project and following the steps from https://docs.godotengine.org/en/stable/tutorials/vr/developing_for_oculus_quest.html. After those steps, doing a remote run on the Quest works fine.

Then, in export settings, I checked “Use Custom Build” and installed the build template. Doing a remote run again, everything seems to build fine and I can deploy on the Quest. However, the app doesn’t start. When remote debug is enabled, the following errors appear to be happening at run-time:

E 0:00:00.221   open_dynamic_library: Can't open dynamic library: libgodot_ovrmobile.so, error: dlopen failed: library "libgodot_ovrmobile.so" not found.
C++ Error   Condition "!p_library_handle" is true. Returned: ERR_CANT_OPEN
C++ Source  platform/android/os_android.cpp:228 @ open_dynamic_library()

E 0:00:00.305   open_dynamic_library: Can't open dynamic library: libgodot_ovrmobile.so, error: dlopen failed: library "libgodot_ovrmobile.so" not found.
C++ Error   Condition "!p_library_handle" is true. Returned: ERR_CANT_OPEN
C++ Source  platform/android/os_android.cpp:228 @ open_dynamic_library()

E 0:00:00.305   get_symbol: No valid library handle, can't get symbol from GDNative object
C++ Source  modules/gdnative/gdnative.cpp:502 @ get_symbol()

E 0:00:00.305   init_library: No nativescript_init in "res://addons/godot_ovrmobile/libs/arm64-v8a/libgodot_ovrmobile.so" found
C++ Source  modules/gdnative/nativescript/nativescript.cpp:1479 @ init_library()

upon inspecting the generated .apk, I can see that the .so has been bundled in /assets/addons/godot_ovrmobile/libs/arm64-v8a/. However, with the default export, it is located in the /libs folder in the APK, which I guess is where it should be.

I don’t know whether this is a bug or not, but either way I also don’t know how to fix the build template to include the .so in the proper place. Can anyone help me out with this?

Cheers!

:bust_in_silhouette: Reply From: NarcoticV

OK, so I have found a solution to this, although I am still not sure whether this is supposed to require manual edits to the build template:

in the generated build template’s “build.gradle” file, found the entries for “jniLibs” and added the paths to the godot_ovrmobile libs folder there. The packager then grabs the libraries within and puts them under “lib” in the APK, making them loadable.

The following shows where to add it (omitted a lot of other keys in there):

android {
  sourceSets {
    debug.jniLibs.srcDirs = [
        'libs/debug',
        '../../addons/godot_ovrmobile/libs'
    ]
    release.jniLibs.srcDirs = [
        'libs/release',
        '../../addons/godot_ovrmobile/libs'
    ]

My question still remains whether this is supposed to be such a manual process.

I too faced such issues.
I built my .so for x64(mistake) but I was wondering why so isnt working on android platform. Did some research.
Executes arm specific commands:

    1944  aarch64-linux-android30-clang++ -fPIC -c src/entry.cpp src/Player.cpp -g -O3 - 
     std=c++17 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen - 
     Igodot-cpp/godot-headers
 1945  aarch64-linux-android30-clang++ -o libarmv7.so -shared entry.o Player.o -Lgodot-cpp/bin -lgodot-cpp.android.debug.arm64v8
 1946  cd godot-cpp
 1947  scons platform=android generate_bindings=yes android_arch=arm64v8 android_api_level=30 -j8
 1948  vi SConstruct
 1949  scons platform=android generate_bindings=yes android_arch=arm64v8 android_api_level=30 -j8
 1950  cd ..
 1951  aarch64-linux-android30-clang++ -fPIC -c src/entry.cpp src/Player.cpp -g -O3 -std=c++17 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot-headers
 1952  aarch64-linux-android30-clang++ -o libarmv7.so -shared entry.o Player.o -Lgodot-cpp/bin -lgodot-cpp.android.debug.arm64v8
 1953  cd project/
 1954  mv ../libarmv7.so ./gdnative/linux/libdodgethecreeps.so

And I was so happy to finally see my spirit rotating on my android.

rishin458 | 2022-01-26 00:11

@NarcoticV, I ran into this issue as well, and you help guide me to a solution. I’m not android project expert, but it looks like the generated build.gradle already has a default path setup for you. Based on yoru post, “libs/debug” and “libs/release” is the default path.

Initially I dragged my .so file in there, but it still wasn’t packaging it up in the “lib” folder of apk. It turns out you also have to add another folder for the type of arm build you are doing, then it will pick it up and pack it correctly. For example, if you are building for armeabi-v7a, add your .so file like so:

libs/debug/armeabi-v7a/randomLib.so
libs/release/armeabi-v7a/randomLib.so

This is why your ‘…/…/addons/godot_ovrmobile/libs’ path works because it has this extra folder. Refer to this output in your initial post.

“res://addons/godot_ovrmobile/libs/arm64-v8a/libgodot_ovrmobile.so”

Note the extra “arm64-v8a”

I’m not sure why Godot does’t automatically copy it here based on the library directories set up in the library UI tool set for the default builds. It might be a bug or maybe they just want to give you complete control. At any rate, I will add the copy logic to my build scripts to automate this.

On a side note the abiFilters is probably also considered as well when appending “armeabi-v7a” or “arm64-v8a” to the “libs/debug” or “libs/release”, so make sure that is correct. This is the default generated setting:

android {
defaultConfig {
ndk {
String export_abi_list = getExportedEnabledABIs()
abiFilters export_abi_list
}
}
}

if you follow the function “getExportedEnabledABIs” into “config.gradle”, it creates the filter for “armeabi-v71”, “arm64-v8a”, and other arm build types.

sanjodev | 2022-01-29 02:03