java.lang.unsatisfiedLinkError lib not found :(failed to link mylib.so) - android

i've successfully cross compiled a c++ library to the android plateform using the android ndk standalone toolchain.
i've created a new android application project into Eclipse with a jni dolder and Android.mk file and when i do an ndk-build the building goes well and it adds mylib.so to libs/armeabi folder
The problem is when i do a System.loadLibrary("mylibname");
i get the following error in the logcat:
Unable to dlopen(/data/data/com.oussama.firsttry/lib/libdash.so): Cannot load library: link_image[1995]: failed to link libdash.so
that cause a java.lang.UnsatisfiedLinkError: my lib not found**.
There must be a library that my lib depends on and the emulator can't load it so i've done a readelf -d mylib.so and here is the result:
Dynamic section at offset 0x1617c4 contains 26 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libdash.so]
0x00000010 (SYMBOLIC) 0x0
0x0000000f (RPATH) Library rpath: [/home/oussama064/libdash/libdash/../../neededLibs]
0x00000019 (INIT_ARRAY) 0x157268
0x0000001b (INIT_ARRAYSZ) 172 (bytes)
0x0000001a (FINI_ARRAY) 0x157314
0x0000001c (FINI_ARRAYSZ) 8 (bytes)
0x00000004 (HASH) 0xf4
0x00000005 (STRTAB) 0x10f58
0x00000006 (SYMTAB) 0x50b8
0x0000000a (STRSZ) 134112 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x1618b4
0x00000002 (PLTRELSZ) 1096 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x40dd8
0x00000011 (REL) 0x31b38
0x00000012 (RELSZ) 62112 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x00000018 (BIND_NOW)
0x6ffffffb (FLAGS_1) Flags: NOW
0x6ffffffa (RELCOUNT) 7738
0x00000000 (NULL) 0x0
Here is my Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) LOCAL_MODULE := libcurl LOCAL_SRC_FILES :=
../../../../neededLibs/libcurl.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS) LOCAL_MODULE := libxml LOCAL_SRC_FILES :=
../../../../neededLibs/libxml2.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS) LOCAL_MODULE := libz LOCAL_SRC_FILES :=
../../../../neededLibs/libz.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS) LOCAL_MODULE := m LOCAL_SRC_FILES :=
libm.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS)
LOCAL_MODULE := dl LOCAL_SRC_FILES := libdl.so
include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE
:= c LOCAL_SRC_FILES := libc.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := d LOCAL_SRC_FILES := libdash.so
LOCAL_SHARED_LIBRARIES := c m dl
LOCAL_STATIC_LIBRARIES := libz libxml libcurl include
$(PREBUILT_SHARED_LIBRARY)
i'am really stuck now and i can't figure out what is the missing library
When i do an ndk-build V=1 -B i get the following result:
rm -f /home/oussama064/Android/workspace/FirstTry/libs/armeabi/lib*.so
/home/oussama064/Android/workspace/FirstTry/libs/armeabi-v7a/lib*.so
/home/oussama064/Android/workspace/FirstTry/libs/mips/lib*.so
/home/oussama064/Android/workspace/FirstTry/libs/x86/lib*.so
rm -f /home/oussama064/Android/workspace/FirstTry/libs/armeabi/gdbserver
/home/oussama064/Android/workspace/FirstTry/libs/armeabi-v7a/gdbserver
/home/oussama064/Android/workspace/FirstTry/libs/mips/gdbserver
/home/oussama064/Android/workspace/FirstTry/libs/x86/gdbserver
rm -f /home/oussama064/Android/workspace/FirstTry/libs/armeabi/gdb.setup
/home/oussama064/Android/workspace/FirstTry/libs/armeabi-v7a/gdb.setup
/home/oussama064/Android/workspace/FirstTry/libs/mips/gdb.setup
/home/oussama064/Android/workspace/FirstTry/libs/x86/gdb.setup
make: Circular obj/local/armeabi/libm.so <- obj/local/armeabi/libm.so dependency
dropped.
make: Circular obj/local/armeabi/libm.so <- obj/local/armeabi/libc.so dependency
dropped.
make: Circular obj/local/armeabi/libdl.so <- obj/local/armeabi/libm.so dependency
dropped.
make: Circular obj/local/armeabi/libdl.so <- obj/local/armeabi/libc.so dependency
dropped.
make: Circular obj/local/armeabi/libdl.so <- obj/local/armeabi/libdl.so dependency
dropped.
Prebuilt : libdl.so <= /home/oussama064/Android/workspace/FirstTry/jni/
cp -f /home/oussama064/Android/workspace/FirstTry/jni/libdl.so
obj/local/armeabi/libdl.so
Prebuilt : libm.so <= /home/oussama064/Android/workspace/FirstTry/jni/
cp -f /home/oussama064/Android/workspace/FirstTry/jni/libm.so obj/local/armeabi/libm.so
make: Circular obj/local/armeabi/libc.so <- obj/local/armeabi/libc.so dependency dropped.
Prebuilt : libc.so <= /home/oussama064/Android/workspace/FirstTry/jni/
cp -f /home/oussama064/Android/workspace/FirstTry/jni/libc.so obj/local/armeabi/libc.so
Install : libc.so =>
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libc.so
install -p ./obj/local/armeabi/libc.so
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libc.so
/home/oussama064/NDK/android-ndk-r8d/toolchains/arm-linux-androideabi-
4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-strip --strip-unneeded
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libc.so
Prebuilt : libxml2.a <=
/home/oussama064/Android/workspace/FirstTry/jni/../../../../neededLibs/
cp -f
/home/oussama064/Android/workspace/FirstTry/jni/../../../../neededLibs/libxml2.a
obj/local/armeabi/libxml2.a
Prebuilt : libcurl.a <=
/home/oussama064/Android/workspace/FirstTry/jni/../../../../neededLibs/
cp -f
/home/oussama064/Android/workspace/FirstTry/jni/../../../../neededLibs/libcurl.a
obj/local/armeabi/libcurl.a
Prebuilt : libdash.so <= /home/oussama064/Android/workspace/FirstTry/jni/
cp -f /home/oussama064/Android/workspace/FirstTry/jni/libdash.so
obj/local/armeabi/libdash.so
Install : libdash.so =>
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdash.so
install -p ./obj/local/armeabi/libdash.so
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdash.so
/home/oussama064/NDK/android-ndk-r8d/toolchains/arm-linux-androideabi-
4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-strip --strip-unneeded
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdash.so
Install : libdl.so =>
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdl.so
install -p ./obj/local/armeabi/libdl.so
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdl.so
/home/oussama064/NDK/android-ndk-r8d/toolchains/arm-linux-androideabi-
4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-strip --strip-unneeded
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libdl.so
Install : libm.so =>
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libm.so
install -p ./obj/local/armeabi/libm.so
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libm.so
/home/oussama064/NDK/android-ndk-r8d/toolchains/arm-linux-androideabi-
4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-strip --strip-unneeded
/home/oussama064/Android/workspace/FirstTry/libs/armeabi/libm.so
I would be thankfull if any one can help me.

You should use the system versions of libm, libc and libdl shared libraries,
LOCAL_LDLIBS := -lm -ldl
If you can't, link them statically.

Related

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

Using gstreamer plugins bad in android

I am trying to show h264 encodes streams inside an android application using the GStreamer SDK and Android NDK.
My Android.mk looks like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := App
LOCAL_SRC_FILES := App.cpp
LOCAL_SHARED_LIBRARIES := gstreamer_android
LOCAL_LDLIBS := -llog -landroid
include $(BUILD_SHARED_LIBRARY)
ifndef GSTREAMER_ROOT
ifndef GSTREAMER_ROOT_ANDROID
$(error GSTREAMER_ROOT_ANDROID is not defined!)
endif
GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)
endif
GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/
include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) $(GSTREAMER_PLUGINS_SYS) $(GSTREAMER_PLUGINS_EFFECTS) $(GSTREAMER_PLUGINS_NET)
GSTREAMER_EXTRA_DEPS := gstreamer-video-1.0
include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk
Beacause of missing plugins-bad I get the following error:
priv_gst_parse_yyparse no element "h264parse"
My pipe looks like the following:
udpsrc address=192.168.0.1 port=5000 ! application/x-rtp, encoding-name=H264, payload=96 ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink
So how can I include the gstreamer-plugins-bad into android build?
Try adding this line instead the one you have:
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) $(GSTREAMER_PLUGINS_PLAYBACK) $(GSTREAMER_PLUGINS_CODECS) $(GSTREAMER_PLUGINS_NET) $(GSTREAMER_PLUGINS_SYS) $(GSTREAMER_PLUGINS_CODECS_RESTRICTED)
Specifically this one should do the job $(GSTREAMER_PLUGINS_CODECS_RESTRICTED)
You can add this line :
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) $(GSTREAMER_PLUGINS_PLAYBACK) $(GSTREAMER_PLUGINS_CODECS) $(GSTREAMER_PLUGINS_NET) $(GSTREAMER_PLUGINS_SYS) $(GSTREAMER_PLUGINS_CODECS_RESTRICTED) $(GSTREAMER_PLUGINS_EFFECTS)
in your path : app/jni/Android.mk

Android NDK & FFMPEG : findLibrary returned null

I am using this to build ffmpeg on ndk:
roman10's android ndk r9d - ffmpeg tutorial
The link shows how to compile, but its not clear how to use it. Can anybody guide me? Thanks.
After ndk-build from my project root i was able to generate .so files inside libs/armeabi and obj/local/armeabi.. Now I am getting findLibrary returned null?? What to do now?
java.lang.UnsatisfiedLinkError: Couldn't load libavutil from loader dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.palak.androidffmpegroman-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.palak.androidffmpegroman-2, /vendor/lib, /system/lib]]]: findLibrary returned null
at java.lang.Runtime.loadLibrary(Runtime.java:358)
at java.lang.System.loadLibrary(System.java:526)
at com.palak.androidffmpegroman.MainActivity.<clinit>(MainActivity.java:175)
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:2101)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
my project structure:
My build_android.sh
#!/bin/bash
NDK=$HOME/NDK/android-ndk-r10d
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86
function build_one
{
sudo ./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}
CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm"
build_one
I am using Ndk r10, ffmpeg 2.5.4, ubuntu x86.
Edit: Android.mk
LOCAL_PATH:= /home/palak/NDK/ffmpeg-2.5.4/android/arm
include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= lib/libavcodec-56.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat
LOCAL_SRC_FILES:= lib/libavformat-56.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale
LOCAL_SRC_FILES:= lib/libswscale-3.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavutil
LOCAL_SRC_FILES:= lib/libavutil-54.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter
LOCAL_SRC_FILES:= lib/libavfilter-5.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libswresample
LOCAL_SRC_FILES:= lib/libswresample-1.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
Android.mk under jni folder:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tutorial01
LOCAL_SRC_FILES := tutorial01.c
LOCAL_LDLIBS := -llog -ljnigraphics -lz
LOCAL_SHARED_LIBRARIES := avformat avcodec swscale avutil
include $(BUILD_SHARED_LIBRARY)
$(call import-module,ffmpeg-2.5.4/android/arm)
LOCAL_MODULE:= libavutil
-->
LOCAL_MODULE:= avutil # libavutil.so
example (used to work):
https://github.com/18446744073709551615/reDroid/blob/master/jni/Android.mk
UPDATE:
Once again: you do not need the lib prefixes in library names; LOCAL_MODULE:= avutil will give you libavutil.so
At second, what parameter do you pass to loadLibrary()? Again, it should be "avutil" for libavutil.so.
If you have problems, the best way is to start with the hello-jni example in the NDK (your-ndk-dir/samples/hello-jni/)
/* this is used to load the 'hello-jni' library on application
* startup. The library has already been unpacked into
* /data/data/com.example.hellojni/lib/libhello-jni.so <== !!!!!!!!!!!!!
* at installation time by the package manager.
*/
static {
System.loadLibrary("hello-jni");
}
Once the example compiles and runs, you may add your libraries to it and have your stuff work.
You use name libavutil to refer to libavutil-54.so during ndk-build. This is fine, but the runtime lib is still called libavutil-54.so. Moreover, your other modules, including tutorial01, know it by this name, so renaming it in libs/armeabi will also be wrong.
You need something like
static {
System.loadLibrary("avutil-54");
System.loadLibrary("avcodec-56");
System.loadLibrary("avformat-56");
System.loadLibrary("swscale-3");
System.loadLibrary("tutorial01");
}
In recent version of Android, the system will automatically resolve the local external references, so it's enough to call
static {
System.loadLibrary("tutorial01");
}
Replace your
LOCAL_SHARED_LIBRARIES := avformat avcodec swscale avutil
with
LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libavfilter libswresample
in Android.mk in your Jni folder.
And Load the libraries like below
static {
System.loadLibrary("avutil-54");
System.loadLibrary("avcodec-56");
System.loadLibrary("avformat-56");
System.loadLibrary("swscale-3");
System.loadLibrary("avfilter-5");
System.loadLibrary("swresample-1");
System.loadLibrary("tutorial01");
}
Are you sure that you are using a phone with an armeabi processor? Add the armeabiv7 in the Application.mk file and it will compile the required files for armeabiv7 phones in the libs folder.
APP_ABI := armeabi armeabi-v7a x86
This should work.

Linker error: undefined reference to `EVP_cast5_ecb'

I'm trying to compile openssl with cast support but I instead get this error:
SharedLibrary : libcrypto.so
./obj/local/armeabi/objs/crypto/evp/c_allc.o: In function `OpenSSL_add_all_ciphers':
~/testandroid/libssl/jni/crypto/evp/c_allc.c:143: undefined reference to `EVP_cast5_ecb'
~/testandroid/libssl/jni/crypto/evp/c_allc.c:144: undefined reference to `EVP_cast5_cfb64'
~/testandroid/libssl/jni/crypto/evp/c_allc.c:145: undefined reference to `EVP_cast5_ofb'
~/testandroid/libssl/jni/crypto/evp/c_allc.c:146: undefined reference to `EVP_cast5_cbc'
./obj/local/armeabi/objs/crypto/evp/e_old.o: In function `EVP_cast5_cfb':
~/testandroid/libssl/jni/crypto/evp/e_old.c:104: undefined reference to `EVP_cast5_cfb64'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libcrypto.so] Error 1
EVP_cast5_ecb and friends are all defined in ~/testandroid/libssl/jni/crypto/evp/evp.h and in ~/testandroid/libssl/jni/include/evp.h
#ifndef OPENSSL_NO_CAST
const EVP_CIPHER *EVP_cast5_ecb(void);
const EVP_CIPHER *EVP_cast5_cbc(void);
const EVP_CIPHER *EVP_cast5_cfb64(void);
# define EVP_cast5_cfb EVP_cast5_cfb64
const EVP_CIPHER *EVP_cast5_ofb(void);
#endif
In crypto/Android.mk
local_src_files := \
evp/c_allc.c \
evp/e_old.c \
# And a whole bunch of other c files
local_c_includes := \
$(APP_PROJECT_PATH) \
$(APP_PROJECT_PATH)/crypto/asn1 \
$(APP_PROJECT_PATH)/crypto/evp \ # evp.h is located here
$(APP_PROJECT_PATH)/include \
$(APP_PROJECT_PATH)/include/openssl # Another evp.h is also located here
include $(CLEAR_VARS)
include $(LOCAL_PATH)/../android-config.mk
ifeq ($(TARGET_ARCH),arm)
LOCAL_NDK_VERSION := 5
LOCAL_SDK_VERSION := 9
# Use the NDK prebuilt libz and libdl.
LOCAL_LDFLAGS += -lz -ldl
else
LOCAL_SHARED_LIBRARIES += libz libdl
endif
LOCAL_SRC_FILES += $(local_src_files)
LOCAL_CFLAGS += $(local_c_flags)
LOCAL_C_INCLUDES += $(local_c_includes)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libcrypto
include $(BUILD_SHARED_LIBRARY)
I'm probably missing something very trivial here, since I'm new to Android and C in general, so be nice :)
EDIT: I saw that there is a Makefile for cast. I'm guessing there is a whole load of linking magic going on at the very bottom of the original Makefile. How would I do something equivalent for Android?
#
# OpenSSL/crypto/cast/Makefile
#
DIR= cast
TOP= ../..
CC= cc
CPP= $(CC) -E
INCLUDES=
CFLAG=-g
MAKEFILE= Makefile
AR= ar r
CAST_ENC=c_enc.o
CFLAGS= $(INCLUDES) $(CFLAG)
ASFLAGS= $(INCLUDES) $(ASFLAG)
AFLAGS= $(ASFLAGS)
GENERAL=Makefile
TEST=casttest.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC=c_skey.c c_ecb.c c_enc.c c_cfb64.c c_ofb64.c
LIBOBJ=c_skey.o c_ecb.o $(CAST_ENC) c_cfb64.o c_ofb64.o
SRC= $(LIBSRC)
EXHEADER= cast.h
HEADER= cast_s.h cast_lcl.h $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
top:
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
all: lib
lib: $(LIBOBJ)
$(AR) $(LIB) $(LIBOBJ)
$(RANLIB) $(LIB) || echo Never mind.
#touch lib
cast-586.s: asm/cast-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
$(PERL) asm/cast-586.pl $(PERLASM_SCHEME) $(CLAGS) $(PROCESSOR) > $#
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
links:
#$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
#$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
#$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
install:
#[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
#headerlist="$(EXHEADER)"; for i in $$headerlist ; \
do \
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
done;
tags:
ctags $(SRC)
tests:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
depend:
#[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
dclean:
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.
c_cfb64.o: ../../e_os.h ../../include/openssl/cast.h
c_cfb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_cfb64.o: c_cfb64.c cast_lcl.h
c_ecb.o: ../../e_os.h ../../include/openssl/cast.h
c_ecb.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_ecb.o: ../../include/openssl/opensslv.h c_ecb.c cast_lcl.h
c_enc.o: ../../e_os.h ../../include/openssl/cast.h
c_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_enc.o: c_enc.c cast_lcl.h
c_ofb64.o: ../../e_os.h ../../include/openssl/cast.h
c_ofb64.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_ofb64.o: c_ofb64.c cast_lcl.h
c_skey.o: ../../e_os.h ../../include/openssl/cast.h
c_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
c_skey.o: c_skey.c cast_lcl.h cast_s.h

UnsatisfiedLInkError Linking to FFMPEG with NDK

I compiled FFMPEG for android using bambuser's files. The compile runs fine. No errors.
I also made sure to change the package name in build.sh. However, once I try to link to the files, the phone throws an UnsatisfiedLinkError. This is the Androkd.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
MY_LIB_PATH := ffmpeg-android/build/ffmpeg/armeabi/lib
LOCAL_MODULE := bambuser-libavcore
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcore.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavformat
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavformat.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavcodec
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavcodec.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavdevice
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavdevice.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavfilter
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavfilter.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavutil
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libavutil.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libswscale
LOCAL_SRC_FILES := $(MY_LIB_PATH)/libswscale.so
include $(PREBUILT_SHARED_LIBRARY)
#local_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libtest_jni
LOCAL_SRC_FILES := libtest/video.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/ffmpeg-android/ffmpeg
LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH) -L$(LOCAL_PATH)/ffmpeg-android/build/ffmpeg/armeabi/lib/ -lavformat -lavcodec -lavdevice -lavfilter -lavutil -lswscale -llog -lz -lm
#dl -lgcc
include $(BUILD_SHARED_LIBRARY)
Video.c is dead simple:
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
void Java_com_bukabros_videolivewallpaper_Opengl2Renderer_loadNthFrame3
(JNIEnv * env, jobject this, jstring fileName) {
jboolean isCopy;
const char * szLogThis = (*env)->GetStringUTFChars(env, fileName, &isCopy);
__android_log_print(ANDROID_LOG_DEBUG, "NDK: ", "NDK:LC: [%s]", szLogThis);
}
Tne corresponding Java code is also simple:
private native void loadNthFrame3(String fileName);
static {
System.loadLibrary("libtest_jni");
}
But I get this error:
E/AndroidRuntime(11489): FATAL EXCEPTION: main
E/AndroidRuntime(11489): java.lang.ExceptionInInitializerError
E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper$CubeEngine.<init>(VideoLiveWallpaper.java:147)
E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.VideoLiveWallpaper.onCreateEngine(VideoLiveWallpaper.java:120)
E/AndroidRuntime(11489): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:814)
E/AndroidRuntime(11489): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:61)
E/AndroidRuntime(11489): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(11489): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(11489): at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime(11489): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(11489): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
E/AndroidRuntime(11489): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
E/AndroidRuntime(11489): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(11489): Caused by: java.lang.UnsatisfiedLinkError: Library libtest_jni not found
E/AndroidRuntime(11489): at java.lang.Runtime.loadLibrary(Runtime.java:461)
E/AndroidRuntime(11489): at java.lang.System.loadLibrary(System.java:557)
E/AndroidRuntime(11489): at com.bukabros.videolivewallpaper.Opengl2Renderer.<clinit>(Opengl2Renderer.java:389)
E/AndroidRuntime(11489): ... 12 more
I tried manually loading the prebuilt shared libraries (the bambuser files) in Java (using System.loadLibrary) but then it tells me that the files are not found.
If it helps, here's the output of readelf:
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavformat.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavcodec.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavdevice.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavfilter.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libavutil.so]
0x00000001 (NEEDED) Shared library: [/data/data/com.bukabros.videolivewallpaper/lib/libswscale.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libz.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x0000000e (SONAME) Library soname: [libtest_jni.so]
0x00000010 (SYMBOLIC) 0x0
0x00000004 (HASH) 0xd4
0x00000005 (STRTAB) 0x250
0x00000006 (SYMTAB) 0x130
0x0000000a (STRSZ) 712 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x174c
0x00000002 (PLTRELSZ) 32 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x55c
0x6ffffffe (VERNEED) 0x53c
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x518
0x00000000 (NULL) 0x0
Oh yeah. I'm using ndk r5.
Looks like I found the answer. The problem is that when you load the library in Java (System.loadLibrary), you can NOT use the "lib" prefix. I also had to manually load the ffmpeg libraries in Java. The moral of the story is that you should always read the docs and don't give up:-) Here's the correct code:
static {
System.loadLibrary("avcore");
System.loadLibrary("avformat");
System.loadLibrary("avcodec");
System.loadLibrary("avdevice");
System.loadLibrary("avfilter");
System.loadLibrary("avutil");
System.loadLibrary("swscale");
System.loadLibrary("test_jni");
}

Categories

Resources