Android's GNU STL shared library can't be found with System.loadLibrary

4

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, and androidactivity.cpp which contains the JNI glue and calls the test function from Driver.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 on libstdc++, libm, libc and libdl, and as far as I know all of these except libstdc++ are available on the device as per android-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?

android
stl
android-ndk
asked on Stack Overflow Jan 3, 2012 by Martin Foot • edited Jan 10, 2012 by Martin Foot

6 Answers

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");
    //.......
}
answered on Stack Overflow Dec 2, 2012 by Max
1

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

answered on Stack Overflow Feb 8, 2013 by user2054803
0

You probably need to add it in your Application.mk as well. The project you linked did this at least.

answered on Stack Overflow Jan 4, 2012 by Lennart
0

I believe you'll need to package the appropriate libgnustl_shared.so's (one for each ABI you intend to work with) in your APK libs/*. What this means exactly to your custom CMake build system I can't tell you.

APKs are just zip files -- you can open up yours and ensure it's present where expected.

answered on Stack Overflow Jan 9, 2012 by NuSkooler
0

You show the G++ commands that cmake generated. They look OK. But the linker produced the libMathTest.so based on the system STL library. Actually, it's a mixture of system STL and gnustl (some references to the latter probably came from cxx-stl/gnu-libstdc++/include).

It would help if you echo the actual command behind

Linking CXX shared library ../../android/libs/armeabi/libMathTest.so

But maybe your application can be satisfied with the system STL library? One important advantage is that libstdc++.so is preinstalled on all devices, just like libm.

answered on Stack Overflow Dec 3, 2012 by Alex Cohn
-2

I met the same problem, however I made a large build with 6 shared libraries, all depend on libgnustl_shared.so, and I made two abi builds: armeabi and armeabi-v7a All shared libraries were manually copied to the libs/(abi-name)/, inclusive libgnustl-shared.so. I made the System.load( "gnustl_shared" ) at the first place, but whenever the android activity tried to load lib, it excepted and said gnustl_shared not found. I tried with Androip-8, android-9 and android-14, all have the same error.

_HERE THE ANDROID.MK_   

MYTOP_DIR        := $(call my-dir)   
LOCAL_PATH       :=  $(MYTOP_DIR)  
include $(CLEAR_VARS)  

NDK_ROOT         := /home/workspace/android-ndk-r7  
RUNTIME_STL_PATH :=$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++  

# name of the module to be built  
LOCAL_MODULE := MyMediaPlayer  
LOCAL_SRC_FILES := MyMediaPlayer.cpp  
LOCAL_C_INCLUDES   := $(LOCAL_PATH)/libMediaClient/include  

# rule definition  
LOCAL_CPP_EXTENSION := .cxx .cpp .cc  
LOCAL_CFLAGS        += -I$(RUNTIME_STL_PATH)/include  
LOCAL_CFLAGS        += -I$(RUNTIME_STL_PATH)/libs/$(TARGET_ARCH_ABI)/include  
LOCAL_LDLIBS        += -llog  
LOCAL_LDLIBS        += -landroid  
LOCAL_LDLIBS        += -L$(RUNTIME_STL_PATH)/libs/$(TARGET_ARCH_ABI)  
LOCAL_LDLIBS        += -lgnustl_shared  
LOCAL_LDLIBS        += -L$(LOCAL_PATH)/libMediaClient/lib/android/$(TARGET_ARCH_ABI)  
LOCAL_LDLIBS        += -lMediaClient  
LOCAL_LDLIBS        += -ltools  
include $(BUILD_SHARED_LIBRARY)


_HERE THE APPLICATION.MK_  

APP_ABI             := armeabi armeabi-v7a
APP_STL             := gnustl_shared  # this doesn't make any sense
APP_MODULES         := MyMediaPlayer

I could understand if exception occurs by loading my own libs, but here the libgnustil_shared did come from ndk, what wrong here!!!

Steven

answered on Stack Overflow Apr 11, 2012 by Steven • edited Apr 15, 2012 by Steven

User contributions licensed under CC BY-SA 3.0