nmxprime
nmxprime

Reputation: 1506

Android ndk link failed on libgnustl_shared.so

i have compiled ffmpeg with libstagefright

In the last, while linking i got undefined references using below

$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -soname libffsft1.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffsft1.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lstdc++ -lx264 -lmedia -lutils  -lstagefright -lbinder --warn-once  --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/$CPU/libgcc.a

Refering this i modified as below

$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname libffsft1.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffsft1.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog -lstdc++ -lx264 -lmedia -lutils  -lstagefright -lbinder --warn-once  --dynamic-linker=/system/bin/linker $NDK/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/$CPU/libgcc.a

where

CPU=armv7-a
PREFIX=./android/$CPU
NDK=~/Android/android-ndk-r7c
PLATFORM=$NDK/platforms/android-9/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86

Now i got the .so file, but when using it in Android, i got

03-11 03:26:35.760: E/AndroidRuntime(24036):    at dalvik.system.NativeStart.main(Native Method)
03-11 03:26:35.760: E/AndroidRuntime(24036): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1892]:  1908 could not load needed library 'libgnustl_shared.so' for 'libffsft1.so' (load_library[1094]: Library 'libgnustl_shared.so' not found)
03-11 03:26:35.760: E/AndroidRuntime(24036):    at java.lang.Runtime.loadLibrary(Runtime.java:370)
03-11 03:26:35.760: E/AndroidRuntime(24036):    at java.lang.System.loadLibrary(System.java:535)

So should i copy the required library and use a System.loadlibrary to load it? or do am i doing it in wrong way?


For your reference, i add the undefied references i got while not linking with $NDK/sources/cxx-stl/gnu-libstdc++/libs/armeabi-v7a/libgnustl_shared.so

libavcodec/libavcodec.a(libstagefright.o):In function `std::_Rb_tree_const_iterator<std::pair<long long const, TimeStamp> >::operator--()':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:274: undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base const*)'
libavcodec/libavcodec.a(libstagefright.o): In function `std::_Rb_tree<long long, std::pair<long long const, TimeStamp>, std::_Select1st<std::pair<long long const, TimeStamp> >, std::less<long long>, std::allocator<std::pair<long long const, TimeStamp> > >::_M_insert_(std::_Rb_tree_node_base const*, std::_Rb_tree_node_base const*, std::pair<long long const, TimeStamp> const&)':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:923: undefined reference to `std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
libavcodec/libavcodec.a(libstagefright.o): In function `std::_Rb_tree_const_iterator<std::pair<long long const, TimeStamp> >::operator++()':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:259: undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base const*)'
libavcodec/libavcodec.a(libstagefright.o): In function `std::_Rb_tree_iterator<std::pair<long long const, TimeStamp> >::operator++(int)':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:192: undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base*)'
libavcodec/libavcodec.a(libstagefright.o): In function `std::_Rb_tree<long long, std::pair<long long const, TimeStamp>, std::_Select1st<std::pair<long long const, TimeStamp> >, std::less<long long>, std::allocator<std::pair<long long const, TimeStamp> > >::erase(std::_Rb_tree_iterator<std::pair<long long const, TimeStamp> >)':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:1387: undefined reference to `std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
libavcodec/libavcodec.a(libstagefright.o): In function `std::_Rb_tree_iterator<std::pair<long long const, TimeStamp> >::operator--()':/home/Android/android-ndk-r7c/sources/cxx-stl/gnu-libstdc++/include/bits/stl_tree.h:199: undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base*)'

Upvotes: 3

Views: 7140

Answers (2)

Zam
Zam

Reputation: 6956

Have you ever tried the following?

Add below code to android's Application.mk from jni folder:

  • jni/Application.mk

    APP_STL     := gnustl_shared
    
  • src/{your package}

    System.loadLibrary("gnustl_shared");
    

If the Application.mk does not exist, you should create one yourself.

Upvotes: 3

ph0b
ph0b

Reputation: 14473

yes, as you linked your lib to a shared library, you need to copy it and use System.loadLibrary() to load it before yours, this is the right way to do it. You could also link libgnustl_static.a statically instead so you don't need to copy the shared library and load it at runtime.

Upvotes: 1

Related Questions