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

14,187

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

Share:
14,187
Martin Foot
Author by

Martin Foot

Martin is a software engineer living in London with interests in software development, electronics, biology, evolution, and photography.

Updated on June 04, 2022

Comments

  • Martin Foot
    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, 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?

  • Martin Foot
    Martin Foot over 12 years
    Unfortunately this doesn't help as I'm not using ndk-build. I'm using CMake to compile all my sources.
  • Martin Foot
    Martin Foot over 12 years
    Thanks 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
    mynameisjohnj about 5 years
    This 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)