Undefined symbols for Android shared library in Unity - android

Build of a c++ library for armeabi-v7a using standalone toolchain is successful.
However, when loaded in Unity I get missing symbol error:
05-11 17:05:32.029 12064 12082 D Unity : Unable to load library '/data/app/com.xxx.yyy.app-geDNMNRtyT09WKhCcElqhg==/lib/arm/lib***.so', native render plugin support disabled: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSsD1Ev" referenced by "/data/app/com.xxx.yyy.app-geDNMNRtyT09WKhCcElqhg==/lib/arm/lib***.so"...
which is std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string().
When checked compiled library with nm, I see this symbol indeed undefined:
$ nm lib***.so
U _ZNSsD1Ev
I also can see that the library depends on shared libstdc++.so:
$ readelf -d build/lib/lib***.so
...
0x00000001 (NEEDED) Shared library: [libsqlite3.so]
0x00000001 (NEEDED) Shared library: [libopenssl.so]
0x00000001 (NEEDED) Shared library: [libndn-cpp.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libOpenSLES.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
...
even though I setup autotools with -static-libstdc++:
CFLAGS="-isystem $TOOLCHAIN/include/c++/4.9.x/ --sysroot=$TOOLCHAIN/sysroot -I$TOOLCHAIN/sysroot/usr/include -I$TOOLCHAIN/include"
CPPFLAGS="-isystem $TOOLCHAIN/include/c++/4.9.x/ --sysroot=$TOOLCHAIN/sysroot -I$TOOLCHAIN/sysroot/usr/include -I$TOOLCHAIN/include -DWEBRTC_POSIX -DBOOST_ASIO_DISABLE_STD_CHRONO $CPPFLAGS -DWEBRTC_POSIX -DBOOST_ASIO_DISABLE_STD_CHRONO -g -O0"
CXXFLAGS="$CXXFLAGS -DWEBRTC_POSIX -DBOOST_ASIO_DISABLE_STD_CHRONO -g -O0"
LDFLAGS="-static-libstdc++ -L$TOOLCHAIN/sysroot/usr/lib -L$TOOLCHAIN/arm-linux-androideabi/lib -L$TOOLCHAIN/arm-linux-androideabi/lib/armv7-a -lOpenSLES -lm -lsqlite3 -lopenssl"
What's interesting, is that when I search toolchain's libraries, the missing symbol shows up only in libgnustl_shared.so:
$ nm $TOOLCHAIN/arm-linux-androideabi/lib/armv7-a/libgnustl_shared.so | grep "_ZNSsD1Ev"
00096568 W _ZNSsD1Ev
Not quite sure why is this happening, as there is no (obvious) dependency on libgnustl_shared.so as far as I can tell.

Related

Reduce opencv4 dynamic lib .so size

I'm trying to reduce .so file size for an android app, but when I recompile the dynamic library my app crashes with this code
java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat() (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__).
I'm also tried to recompile from src, but for some reason, when I add modify the root CMakeLists.txt file (line 153 at this time), the compilation fails because doesn't find a file from samples.
Here is my command to recompile .so from static libraries for arm64
$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ -fpic --sysroot=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -target aarch64-linux-android21 -shared -Xlinker -soname=libopencv_java4.so -o libopencv_java4.so -Xlinker --no-as-needed -Xlinker --whole-archive -Xlinker libcpufeatures.a -Xlinker libIlmImf.a -Xlinker liblibjasper.a -Xlinker liblibjpeg-turbo.a -Xlinker liblibpng.a -Xlinker liblibprotobuf.a -Xlinker liblibtiff.a -Xlinker liblibwebp.a -Xlinker libquirc.a -Xlinker libtbb.a -Xlinker libtegra_hal.a -Xlinker libopencv_imgcodecs.a -Xlinker libopencv_imgproc.a -Xlinker libopencv_core.a -Xlinker --no-whole-archive -nostdlib++ -llog -ljnigraphics -landroid -lmediandk -lz
generated .so info
Dynamic section at offset 0x9fabc8 contains 33 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [libmediandk.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000000e (SONAME) Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY) 0x9e4948
0x000000000000001b (INIT_ARRAYSZ) 216 (bytes)
0x000000000000001a (FINI_ARRAY) 0x9e4a20
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x0000000000000004 (HASH) 0x1c8
0x000000006ffffef5 (GNU_HASH) 0x5378
0x0000000000000005 (STRTAB) 0x1d230
0x0000000000000006 (SYMTAB) 0xa8d0
0x000000000000000a (STRSZ) 121597 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0xa0ae18
0x0000000000000002 (PLTRELSZ) 27888 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0xb0260
0x0000000000000007 (RELA) 0x3c658
0x0000000000000008 (RELASZ) 474120 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x3c5f8
0x000000006fffffff (VERNEEDNUM) 3
0x000000006ffffff0 (VERSYM) 0x3ad2e
0x000000006ffffff9 (RELACOUNT) 16950
0x0000000000000000 (NULL) 0x0
original .so info
Dynamic section at offset 0x116d898 contains 32 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libjnigraphics.so]
0x0000000000000001 (NEEDED) Shared library: [libz.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [libmediandk.so]
0x000000000000000e (SONAME) Library soname: [libopencv_java4.so]
0x0000000000000019 (INIT_ARRAY) 0x11378f0
0x000000000000001b (INIT_ARRAYSZ) 384 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1137a70
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x0000000000000004 (HASH) 0x228
0x0000000000000005 (STRTAB) 0x3b328
0x0000000000000006 (SYMTAB) 0xc018
0x000000000000000a (STRSZ) 372415 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x117dad8
0x0000000000000002 (PLTRELSZ) 49488 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x161668
0x0000000000000007 (RELA) 0x9a138
0x0000000000000008 (RELASZ) 816432 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x000000006ffffffe (VERNEED) 0x9a0d8
0x000000006fffffff (VERNEEDNUM) 3
0x000000006ffffff0 (VERSYM) 0x961e8
0x000000006ffffff9 (RELACOUNT) 26157
0x0000000000000000 (NULL) 0x0
Ok, finally I reduced the size of opencv via build_sdk.py script, just added BUILD_LIST="core,imgproc,imgcodecs,java", to the cmake_vars dictionary in build_library function, also I'm disabled the INSTALL_ANDROID_EXAMPLES to "OFF", and passed the --no_samples_build flag as command line option

Loading C library in Android

I have little to no understanding how low-level programming languages work, so please bear with me.
I need to load compiled C (.so file) library into android 6.0+ (SdkVersion: 23+)
Using:
static {
System.loadLibrary("dsdrv");
}
I get an error:
FATAL EXCEPTION: main
Process: com.logicants.scanner3, PID: 11415
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.logicants.scanner3-1/lib/arm/libdsdrv.so" has unexpected e_machine: 3
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.logicants.scanner3.MainActivity.<clinit>(MainActivity.java:13)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1072)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2478)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1499)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5765)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:683)
I did some digging on the internet and found this: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-runtime
"On previous versions of Android, if your app requested the system to load a shared library with text relocations, the system displayed a warning but still allowed the library to be loaded. Beginning in this release, the system rejects this library if your app's target SDK version is 23 or higher. To help you detect if a library failed to load, your app should log the dlopen(3) failure, and include the problem description text that the dlerror(3) call returns. To learn more about handling text relocations, see this guide."
So, basically it fails due to: TEXTREL
readelf -a dsdrv.so | grep TEXTREL
Does not return anything
readelf -d dsdrv.so
Returns:
Dynamic section at offset 0x5bd28 contains 24 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0xd3bc
0x0000000d (FINI) 0x4aec8
0x6ffffef5 (GNU_HASH) 0xd4
0x00000005 (STRTAB) 0x4f30
0x00000006 (SYMTAB) 0x1930
0x0000000a (STRSZ) 24307 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x5d154
0x00000002 (PLTRELSZ) 2304 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0xcabc
0x00000011 (REL) 0xb5e4
0x00000012 (RELSZ) 5336 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0xb4e4
0x6fffffff (VERNEEDNUM) 5
0x6ffffff0 (VERSYM) 0xae24
0x6ffffffa (RELCOUNT) 44
0x00000000 (NULL) 0x0
So, I'm assuming it fails due to one of the Shared libraries.
I do not have source code of the library just the compiled *.so file.
How can I resolve this? Is it possible to decompile *.so file and recompile it again, so it would not use TEXTREL.

java.lang.UnsatisfiedLinkError: dlopen failed: libavcodec-57.so has unexpected e_machine: 40

I'm trying to use FFmpeg 3.1.3 in the Android app.
The 'libavcodec-57.so' is loaded in the main activity, as the following:
static {
LogUtil.e("DEVICE ARCH", System.getProperty("os.arch"));
System.loadLibrary("avutil-55");
System.loadLibrary("avcodec-57");
}
And the logcat gives me: (time is not important)
E/DEVICE ARCH: armv7l
D/dalvikvm: Trying to load lib /data/app-lib/<package_name>-1/libavutil-55.so 0x4d11fe10
D/houdini: [5955] Loading library(version: 4.1.1a_y.45536 RELEASE)... successfully.
D/dalvikvm: Added shared lib /data/app-lib/<package_name>-1/libavutil-55.so 0x4d11fe10
D/dalvikvm: No JNI_OnLoad found in /data/app-lib/<package_name>-1/libavutil-55.so 0x4d11fe10, skipping init
D/dalvikvm: Trying to load lib /data/app-lib/<package_name>-1/libavcodec-57.so 0x4d11fe10
D/houdini: [5955] Unsupported feature (ID:0x10600ccf).
D/houdini: [5955] Open Native Library /data/app-lib/<package_name>-1/libavcodec-57.so failed.
E/dalvikvm: Houdini dlopen("/data/app-lib/<package_name>-1/libavcodec-57.so") failed: Cannot load ARM library
W/dalvikvm: Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lapp/Activity/MainActivity;
W/dalvikvm: Class init failed in newInstance call (Lapp/Activity/MainActivity;)
D/AndroidRuntime: Shutting down VM
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x4c810160)
W/TDLog: UncaughtException in Thread main
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app-lib/<package_name>-1/libavcodec-57.so" has unexpected e_machine: 40
at java.lang.Runtime.loadLibrary(Runtime.java:364)
at java.lang.System.loadLibrary(System.java:526)
at <package_name>.Activity.MainActivity.<clinit>(MainActivity.java:128)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2141)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2273)
at android.app.ActivityThread.access$800(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1236)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
at dalvik.system.NativeStart.main(Native Method)
It says that the device's arch is ARM. The libavcodec-57.so is failed to load and the e_machine: 40 indicates the expected arch is also ARM (see the ELF header doc).
Besides, both libavutil-55.so and libavcodec-57.so are located in the same directory.
The solution is to load all of the needed libraries by libavcodec-57.so before loading it.
Execute readelf -d libavcodec-57.so | grep NEEDED will get which libraries it need:
0x00000001 (NEEDED) Shared library: [libswresample-2.so]
0x00000001 (NEEDED) Shared library: [libavutil-55.so]
0x00000001 (NEEDED) Shared library: [libx264-148.so]
0x00000001 (NEEDED) Shared library: [libfaac.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libz.so]
0x00000001 (NEEDED) Shared library: [libc.so]
Except the built-in libraries libm, libz and libc, all of the needed libraries should be loaded before libavcodec-57.so. So the Java code changes like this:
static {
System.loadLibrary("faac");
System.loadLibrary("x264-148");
System.loadLibrary("avutil-55");
System.loadLibrary("swresample-2"); // need x264 and avutil
System.loadLibrary("avcodec-57"); // need all of the above
}

Android NDK links shared libraries libxxx.so.ver instead of libxxx.so

I've compiled my own shared library which depends on external shared libraries (ffmpeg and x264) using ndk-build. I've defined external libraries as it is described in documentation:
LOCAL_PATH := $(my-root-dir)/external_libs
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libavcodec.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libavutil.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libswscale.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := x264
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/lib/libx264.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)
and have installed external shared libraries for all needed ABIs:
external_libs
- armeabi
- - include
- - lib
- - - libavcodec.so -> libavcodec.so.57.24.101
- - - libavcodec.so.57 -> libavcodec.so.57.24.101
- - - libavcodec.so.57.24.101
- - - libavutil.so -> libavutil.so.55.16.101
- - - libavutil.so.55 -> libavutil.so.55.16.101
- - - libavutil.so.55.16.101
- - - libswresample.so -> libswresample.so.2.0.101
- - - libswresample.so.2 -> libswresample.so.2.0.101
- - - libswresample.so.2.0.101
- - - libswscale.so -> libswscale.so.4.0.100
- - - libswscale.so.4 -> libswscale.so.4.0.100
- - - libswscale.so.4.0.100
- - - libx264.so -> libx264.so.148
- - - libx264.so.148
- armeabi-v7a
- - include
- - lib
- - - libavcodec.so -> libavcodec.so.57.24.101
- - - libavcodec.so.57 -> libavcodec.so.57.24.101
- - - libavcodec.so.57.24.101
- - - libavutil.so -> libavutil.so.55.16.101
- - - libavutil.so.55 -> libavutil.so.55.16.101
- - - libavutil.so.55.16.101
... (etc)
In my library's Android.mk I've added reference to this external libraries:
LOCAL_SHARED_LIBRARIES += libx264
Project has builded just fine, external libraries have been copied to the lib/$(TARGET_ARCH_ABI):
lib
- armeabi
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
- armeabi-v7a
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
and than to device/simulator. But when I load my library in application with System.loadLibrary("mylibrary"); I get error:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libx264.so.148" not found
at java.lang.Runtime.loadLibrary(Runtime.java:372)
When I inspect my library with
arm-linux-androideabi-readelf -d libs/armeabi-v7a/libmylibrary.so
I get this:
Dynamic section at offset 0x12d34c contains 42 entries:
Tag Type Name/Value
0x00000003 (PLTGOT) 0x12eb00
0x00000002 (PLTRELSZ) 2536 (bytes)
0x00000017 (JMPREL) 0x3a264
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x352ac
0x00000012 (RELSZ) 20408 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 2546
0x00000006 (SYMTAB) 0x148
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x10c58
0x0000000a (STRSZ) 106907 (bytes)
0x00000004 (HASH) 0x2adf4
0x00000001 (NEEDED) Shared library: [libx264.so.148]
0x00000001 (NEEDED) Shared library: [libavcodec.so.57]
0x00000001 (NEEDED) Shared library: [libswscale.so.4]
0x00000001 (NEEDED) Shared library: [libavutil.so.55]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x0000000e (SONAME) Library soname: [libmylibrary.so]
0x0000001a (FINI_ARRAY) 0x12d77c
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000019 (INIT_ARRAY) 0x12e344
0x0000001b (INIT_ARRAYSZ) 8 (bytes)
0x00000016 (TEXTREL) 0x0
0x00000010 (SYMBOLIC) 0x0
0x0000001e (FLAGS) SYMBOLIC TEXTREL BIND_NOW
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffff0 (VERSYM) 0x330cc
0x6ffffffc (VERDEF) 0x35230
0x6ffffffd (VERDEFNUM) 1
0x6ffffffe (VERNEED) 0x3524c
0x6fffffff (VERNEEDNUM) 3
0x00000000 (NULL) 0x0
Why are there references in my libmylibrary.so to libx264.so.148, libavcodec.so.57, etc and not to libx264.so, libavcodec.so, etc as expected?
The linker looks at the soname of libraries, not the file names. You can ask ./configure to generate sonames without version suffix

Can not load shared libraries because major number is given as a part of the library dependency

I have been creating a set of shared libraries to run on an android phone. When I try to load them in they are failing and it looks to me as if the libraries that my shared library depends on have been named with their major number.
I should explain that I am not using the ndk-* commands, only the ndk toolchain with the usual configure scripts.
As a simple example, though the rest of my libs are doing the same. I have build libtiff with a dependency on libjpeg. If I do a readelf on libtiff I get this.
$ /c/android/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/windows/bin/arm-eabi-readelf.exe -d libs/armeabi/libtiff.so
Dynamic section at offset 0x79988 contains 25 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libjpeg.so.8]
0x00000001 (NEEDED) Shared library: [libz.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libtiff.so.3]
0x00000010 (SYMBOLIC) 0x0
0x0000000f (RPATH) Library rpath: [c:/Users/whadden/workspace/jni_debug/jpeg-8c/.libs:C:/MinGW/ms
s/1.0/local/lib]
0x00000004 (HASH) 0xb4
0x00000005 (STRTAB) 0x1f54
0x00000006 (SYMTAB) 0xa24
0x0000000a (STRSZ) 5195 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x7aa70
0x00000002 (PLTRELSZ) 768 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x4110
0x00000011 (REL) 0x3668
0x00000012 (RELSZ) 2728 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x3648
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x33a0
0x6ffffffa (RELCOUNT) 339
0x00000000 (NULL) 0x0
As you can see I would have expected to see libjpeg named as libjpeg.so not libjpeg.so.8. As this is being deployed to an android phone I do not think I can create symbolic links to resolve this issue, and I don't think I should be anyway.
When I try to root cause the issue by doing a test link with the phone's system libs I get
$ /cygdrive/c/android/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/window
s/bin/arm-eabi-ld libtiff.so -rpath=.
C:\android\android-ndk-r5b\toolchains\arm-eabi-4.4.0\prebuilt\windows\bin\arm-eabi-ld.exe: warning: libjpeg.so.8, needed
by libtiff.so, not found (try using -rpath or -rpath-link)
C:\android\android-ndk-r5b\toolchains\arm-eabi-4.4.0\prebuilt\windows\bin\arm-eabi-ld.exe: warning: cannot find entry sy
mbol _start; defaulting to 00008260
libtiff.so: undefined reference to `__aeabi_ui2f#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_CreateCompress#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_i2f#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_std_error#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_write_raw_data#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_set_defaults#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_finish_decompress#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_set_colorspace#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_suppress_tables#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_fdiv#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_read_header#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_write_tables#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_fsub#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_abort#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_set_quality#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_read_scanlines#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_resync_to_restart#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_destroy#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_f2iz#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_start_decompress#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_fadd#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_start_compress#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_write_scanlines#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_read_raw_data#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_CreateDecompress#LIBJPEG_8.0'
libtiff.so: undefined reference to `__aeabi_fmul#LIBJPEG_8.0'
libtiff.so: undefined reference to `jpeg_finish_compress#LIBJPEG_8.0'
Which indicates that libjpeg has not been found, yet if I rename libjpeg to libjpeg.so.8 then I get none of these errors.
So should I
a) fix the build so that there are no major number referenced in the shared libs, and more importantly how do I do that?
b) named the build libraries with their major numbers on the file system? ( I presume this is wrong )
/edit
An example of the command line being used for a .o is
libtool: compile: arm-linux-androideabi-gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I/c/Users/whadden/workspace/jni/jpeg-8c -I/c/Users/whadden/workspace/jni/tiff-3.9.5/libtiff -O3 -mandroid -nostdlib -I/c/Users/whadden/workspace/jni/jpeg-8c -I/c/Users/whadden/workspace/jni/tiff-3.9.5/libtiff -Wall -W -MT tif_getimage.lo -MD -MP -MF .deps/tif_getimage.Tpo -c tif_getimage.c -fPIC -DPIC -o .libs/tif_getimage.o
As an aside I have just moved to the new NDK R6
Thanks
Wil
I should explain that I am not using the ndk-* commands, only the ndk toolchain with the usual configure scripts.
It's possible that although your configuration script is generating something that uses the ndk compiler, it's actually building for some properties auto-detected from the environment of your development machine, where for example libjpeg.so.8 might be correct.
You will likely need to either fix the configure script or manually edit the makefiles, you might even be able to do so with sed.
Finally I found a link explaining my own problem and it looks like a limitation of android. Static linking here we come
http://comments.gmane.org/gmane.comp.handhelds.android.ndk/11819

Categories

Resources