Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading multiple Shared Libraries at run time does not work in Android

I am using cmake to create my Shared Libraries in Android Studio. The Libraries build and link correctly and I am able to see all my Libraries in the Apk under lib/armeabi-v7a.

The libraries are linked as follows:

  • Lib1
    • Lib2
      • Lib3
        • Lib4
        • Lib5

I have loaded my Lib1 by making a call to System.loadLibrary("lib1");

I am able to make calls to Lib1, but as soon as Lib1 tries to access Lib2, I get a propagated message saying Lib2 was not loaded.

I then figured I had to load the other libs, so I made the following calls but ended up with the same propagated message "Lib2 not loaded".

System.loadLibrary("lib5");
System.loadLibrary("lib4");
System.loadLibrary("lib3");
System.loadLibrary("lib2");
System.loadLibrary("lib1");

Why would Lib1 be failing to call Lib2? Are additional shared libs unpacked in a location that is causing the library load to fail?

I would like to note that I had my libs loading correctly before switching to use cmake. I believe I was previously manually compiling my libs and storing them in the /jniLibs and /assets directories in my Android Studio project, but that was a while ago so my memory is not clear on the details.

like image 588
Brendan Cordingley Avatar asked Oct 11 '17 23:10

Brendan Cordingley


1 Answers

Since your change appears to be taking effect, I'll guess this isn't some accident like putting the binaries in the wrong place. (I myself have sometimes uploaded to jniLibs/armeabi-v7a then realized I was testing the 64-bit APK that relies on jniLibs/arm64-v8a. Or the other way around when installing a dual-architecture apk on a 32-bit Android device.)

I guess we can rule out an unresolved symbol at load time as well, because it'll typically tell you about that in adb logcat

I recall when seeing this problem in the past it usually turned out to be an issue of lib2's soname. While PC Linux may work with something like liblib2.so.1, Android seems to require that all sonames end in .so

To check the soname on lib2, run readelf -a liblib2.so. If it appears incorrect as I've described, redo your NDK build and ensure that -Wl,-soname,liblib2.so is added at link time.

Furthermore, run readelf -a liblib1.so and make sure its reference to liblib2.so uses the new soname e.g. (NEEDED) Shared Library: [liblib2.so]. You may need to re-link liblib1.so as well.

I would like to note that I had my libs loading correctly before switching to use cmake.

I'll assume CMake was used for the NDK stage of the build and not Java, which could explain a change in the soname.

Note: It's a bit confusing that you put an additional "lib" in each library's given names. It might have been easier to communicate had you used an example that did System.loadLibrary("1"), System.loadLibrary("2")

like image 62
jdonald Avatar answered Oct 07 '22 02:10

jdonald