我正在为Android构建libexif。我使用以下交叉编译脚本:
PLATFORM_PREFIX=/home/tishu/Documents/osx-wks/GC/Thdl/jni/libexif-0.6.21/arch-arm/
NDK_PATH=/home/tishu/Documents/android-ndk-r8e/
NDK_PLATFORM=android-14
rmdir $PLATFORM_PREFIX
mkdir $PLATFORM_PREFIX
$NDK_PATH/build/tools/make-standalone-toolchain.sh --system=linux-x86_64 --platform=$NDK_PLATFORM --install-dir=$PLATFORM_PREFIX
PATH=$PLATFORM_PREFIX/bin:$PATH
./configure --host=arm-linux-androideabi --prefix=$PLATFORM_PREFIX --enable-static
make clean
make install
输出在lib文件夹中提供3个.so文件
我已将最后一个文件重命名为libexif.so,并根据本网站上的一些建议删除了两个符号链接。然后我想用我的应用程序构建它并使用以下Android.mk,其中libexif_native是我使用libexif库的c文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libexif
LOCAL_SRC_FILES := libexif-0.6.21/arch-arm/lib/libexif.so
LOCAL_EXPORT_C_INCLUDES := libexif-0.6.21/arch-arm/include
LOCAL_EXPORT_LDLIBS := libexif-0.6.21/arch-arm/lib/libexif.so
LOCAL_PRELINK_MODULE := true
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_ALLOW_UNDEFINED_SYMBOLS=false
LOCAL_MODULE := libexif_native
LOCAL_SRC_FILES := libexif_native1.1.4.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libexif-0.6.21/arch-arm/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_SHARED_LIBRARY := libexif
LOCAL_LDLIBS := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/libexif-0.6.21/arch-arm/lib/libexif.so
include $(BUILD_SHARED_LIBRARY)
这个编译正确,但是当我在调试模式下在手机上运行时,我收到此错误:
11-01 15:05:06.919: E/AndroidRuntime(5638): FATAL EXCEPTION: main
11-01 15:05:06.919: E/AndroidRuntime(5638): java.lang.UnsatisfiedLinkError: dlopen failed: could not load library "libexif.so.12" needed by "libexif_native.so"; caused by library "libexif.so.12" not found
然后我尝试了这个修改过的Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libexif
LOCAL_SRC_FILES := libexif-0.6.21/arch-arm/lib/libexif.so
LOCAL_EXPORT_C_INCLUDES := libexif-0.6.21/arch-arm/include
LOCAL_EXPORT_LDLIBS := libexif-0.6.21/arch-arm/lib/libexif.so
LOCAL_EXPORT_LDLIBS := libexif-0.6.21/arch-arm/lib/libexif.so.12
LOCAL_PRELINK_MODULE := true
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_ALLOW_UNDEFINED_SYMBOLS=false
LOCAL_MODULE := libexif_native
LOCAL_SRC_FILES := libexif_native1.1.4.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libexif-0.6.21/arch-arm/include
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_SHARED_LIBRARY := libexif
LOCAL_LDLIBS := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/libexif-0.6.21/arch-arm/lib/libexif.so.12 -lm $(LOCAL_PATH)/libexif-0.6.21/arch-arm/lib/libexif.so.12
include $(BUILD_SHARED_LIBRARY)
没有更多的运气。
任何人都知道它为什么要查找.12文件以及如何传递它?我尝试了一些天真的调整,但无法找到如何使这项工作。
非常感谢
答案 0 :(得分:3)
库 libexif.so
是标准Android发行版的一部分。如果您不依赖于最新版本的某些特殊功能,您可能会发现/system/lib/libexif.so
对您来说没问题。您可以将libexif-native.so
与系统库链接起来,而不是构建库并解决所有问题(见下文):只需从设备中拉出库:
> adb pull /system/lib/libexif.so /somepath
然后插入
LOCAL_LDLIBS += /somepath/libexif.so
进入 Android.mk 。请注意,您将看到
Android NDK:警告:jni / Android.mk:...:链接器标志中的非系统库:/somepath/libexif.so
在这种特殊情况下,您可以放心地忽略此警告。
这是Linux库的Android端口的典型问题,后者使用SONAME的版本后缀,而Android NDK不支持此类后缀。有一个很好的理由:在Android上,库不是在系统范围内安装的,它们始终是应用程序包的一部分,因此不需要版本标记。但这种不一致并不能使Android开发者和#生活更轻松。
How to modify librtmp Makefile to remove version suffix? 中提出了直截了当的解决方案:在Makefile中的某个地方摆脱-Wl,--soname=...
。不幸的是,这个技巧不适用于NDK r9d或r10c。
但您可以为LDFLAGS
指定额外的./configure
。这是命令:
./configure LDFLAGS=-Wl,soname=libexif.so <other parameters>
make
mv /arch-arm/lib/libexif.so.12.3.3 /arch-arm/lib/libexif.so
请注意,您还需要以正确的顺序从Java显式加载依赖库。即静态构造函数看起来像:
static {
System.load("/data/data/your.package.name/lib/libexif.so");
System.loadLibrary("exif-native");
}
您必须指定libexif.so
的完整路径,否则将加载/system/lib
中的库。
或者 ,您应该重命名库
./configure LDFLAGS=-Wl,soname=libexif.12.3.3.so <other parameters>
make
mv /arch-arm/lib/libexif.so.12.3.3 /arch-arm/lib/libexif.12.3.3.so
现在您的Java代码可能更清晰:
System.loadLibrary("exif.12.3.3");
System.loadLibrary("exif-native");
以下是 Android.mk 的相关片段:
LOCAL_MODULE := libexif
LOCAL_SRC_FILES := libexif-0.6.21/arch-arm/lib/libexif.12.3.3.so
LOCAL_EXPORT_C_INCLUDES := libexif-0.6.21/arch-arm/include
include $(PREBUILT_SHARED_LIBRARY)
实际上 ,我从不敢尝试的一个技巧可能是将文件libexif.so.12
手动打包到assets
文件夹中,然后将其解压缩在安装APK之后到某个已知路径,然后使用
System.load("/known/path/libexif.so.12");
System.loadLibrary("exif-native");
很遗憾,Android pack / install框架会对libs/armeabi
文件夹中的文件进行过滤,只允许使用模式lib<whatever>.so
。