Android's GNU STL shared library can't be found with System.loadLibrary
Solution 1
well, you need to load gnustl_shared before your own libraries, something like this :
static {
System.loadLibrary("gnustl_shared");
System.loadLibrary("myNativeLib1");
System.loadLibrary("myNativeLib2");
//.......
}
Solution 2
In my case the gnustl_shared library is really not on the device (running Android 2.3.6). When I link the gnustl statically , the NDK app runs fine on the device. my 2 cents
Martin Foot
Martin is a software engineer living in London with interests in software development, electronics, biology, evolution, and photography.
Updated on June 04, 2022Comments
-
Martin Foot almost 2 years
I've compiled a shared library with android-cmake and the NDK against libstdc++, and as per android-ndk-r7/docs/CPLUSPLUS-SUPPORT.html I'm trying to load gnustl_shared before loading my library:
static { System.loadLibrary("gnustl_shared"); System.loadLibrary("MathTest"); }
I can see this being done for instance here but I get an exception:
01-03 20:02:42.307: E/AndroidRuntime(569): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load gnustl_shared: findLibrary returned null
If I don't load gnustl_shared, it fails with this exception:
01-03 20:03:04.667: E/AndroidRuntime(603): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: reloc_library[1311]: 33 cannot locate '_ZNSo3putEc'...
I have tested on API levels 8 and 9 with the same issue. What am I doing wrong? I assume that the symbol it's looking for in the last exception is related to the STL and that loading it would solve the problem. Is this the case?
Edit: I've now included the STL library as suggested by answers. The compile line that CMake produces is this (note that my project has three files,
mother.c
(a copy of George Marsaliga's Mother of All Random Number Generator available here),Driver.cpp
which contains functions to test different math libraries and print out the function runtimes, andandroidactivity.cpp
which contains the JNI glue and calls the test function fromDriver.cpp
. The verbose Makefile output generated by CMake is as follows. I'm not sure if this is useful information but[ 33%] Building CXX object CMakeFiles/MathTest.dir/src/Driver.cpp.o /Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing -Wno-variadic-macros -Wextra -pedantic -g0 -O2 -fPIC -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B -o CMakeFiles/MathTest.dir/src/Driver.cpp.o -c /Users/martin/Repositories/MathTest/src/Driver.cpp "/Applications/CMake 2.8-4.app/Contents/bin/cmake" -E cmake_progress_report /Users/martin/Repositories/MathTest/build/android/CMakeFiles 2 [ 66%] Building C object CMakeFiles/MathTest.dir/src/mother.c.o /Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-gcc -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -O3 -DNDEBUG -fPIC -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -I/Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B -o CMakeFiles/MathTest.dir/src/mother.c.o -c /Users/martin/Repositories/MathTest/src/mother.c "/Applications/CMake 2.8-4.app/Contents/bin/cmake" -E cmake_progress_report /Users/martin/Repositories/MathTest/build/android/CMakeFiles 3 [100%] Building CXX object CMakeFiles/MathTest.dir/src/androidactivity.cpp.o /Users/martin/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-g++ -DMathTest_EXPORTS -D__STDC_INT64__ --sysroot=/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm -fPIC -DANDROID -Wno-psabi -fsigned-char -mthumb -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing -Wno-variadic-macros -Wextra -pedantic -g0 -O2 -fPIC -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/include -isystem /Users/martin/Android/android-ndk-r7/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include -I/Users/martin/Repositories/MathTest/lib/cml-1_0_2 -I/Users/martin/Repositories/MathTest/lib/eigen-eigen-13a11181fc5a -I/Users/martin/Repositories/MathTest/lib/glm-0.9.3.B -o CMakeFiles/MathTest.dir/src/androidactivity.cpp.o -c /Users/martin/Repositories/MathTest/src/androidactivity.cpp Linking CXX shared library ../../android/libs/armeabi/libMathTest.so
readelf
shows that my library depends onlibstdc++
,libm
,libc
andlibdl
, and as far as I know all of these exceptlibstdc++
are available on the device as perandroid-ndk-r7/docs/STABLE-APIS.html
.Martin-Foots-MacBook-Pro:android martin$ ~/Android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86/bin/arm-linux-androideabi-readelf -d ../../android/libs/armeabi/libMathTest.so Dynamic section at offset 0x14b0 contains 25 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x0000000e (SONAME) Library soname: [libMathTest.so] 0x00000010 (SYMBOLIC) 0x0 0x00000019 (INIT_ARRAY) 0x9498 0x0000001b (INIT_ARRAYSZ) 12 (bytes) 0x0000001a (FINI_ARRAY) 0x94a4 0x0000001c (FINI_ARRAYSZ) 12 (bytes) 0x00000004 (HASH) 0xd4 0x00000005 (STRTAB) 0x544 0x00000006 (SYMTAB) 0x234 0x0000000a (STRSZ) 1033 (bytes) 0x0000000b (SYMENT) 16 (bytes) 0x00000003 (PLTGOT) 0x9598 0x00000002 (PLTRELSZ) 136 (bytes) 0x00000014 (PLTREL) REL 0x00000017 (JMPREL) 0x990 0x00000011 (REL) 0x950 0x00000012 (RELSZ) 64 (bytes) 0x00000013 (RELENT) 8 (bytes) 0x00000016 (TEXTREL) 0x0 0x6ffffffa (RELCOUNT) 4 0x00000000 (NULL) 0x0
Does this information help? Is there a way I can tell where the unfound symbol comes from?
-
Martin Foot over 12 yearsUnfortunately this doesn't help as I'm not using ndk-build. I'm using CMake to compile all my sources.
-
Martin Foot over 12 yearsThanks for the information, I can successfully load the STL libraries in Android now, but I still get the same exception when trying to load my own library. I will investigate more and update my post with more information.
-
mynameisjohnj about 5 yearsThis was the answer for me - I'm using NVIDIA's android codeworks and when I compile with Clang I need to use LLVM libc++ static (same with GCC and GNU libstd++ Static in the properties menu)