首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >android共享库中.so.12文件的不满意链接

android共享库中.so.12文件的不满意链接
EN

Stack Overflow用户
提问于 2014-11-01 15:29:04
回答 1查看 2.1K关注 0票数 2

我正在为Android开发libexif。我使用以下交叉编译脚本:

代码语言:javascript
复制
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 (符号链接)
  • libexif.so.12 (看起来像一个符号链接,但内容是大二进制)
  • libexif.so.12.3.3 (实际二进制)

我已将最后一个文件重命名为libexif.so,并根据该网站上的一些建议删除了两个符号链接。然后我想用我的应用程序构建它,并使用以下Android.mk,其中libexif_native是我的c文件,它使用libexif库

代码语言:javascript
复制
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)

这是正确的编译,但是当我在我的手机上以调试模式运行它时,我会得到以下错误:

代码语言:javascript
复制
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

代码语言:javascript
复制
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文件,以及如何传递它吗?我尝试过一些天真的调整,但无法找到如何使这一工作。

非常感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-01 23:05:14

libexif.so是标准安卓发行版的一部分。如果您不依赖于最新版本的某些特殊特性,您可能会发现/system/lib/libexif.so对您来说是好的。您可以将libexif-native.so与系统库链接起来,而不是构建库并解决所有问题(参见下面):只需从设备中提取库:

代码语言:javascript
复制
> adb pull /system/lib/libexif.so /somepath

然后插入

代码语言:javascript
复制
LOCAL_LDLIBS += /somepath/libexif.so

进入您的Android.mk。请注意,您将看到

Android.mk:警告:jni/android.mk:.:链接器标志中的非系统库: /somepath/libexif.so

在这种特殊情况下,您可以安全地忽略此警告。

你这样避免麻烦

Linux库的Android端口的一个典型问题是,后者为SONAME使用版本后缀,而Android不支持这种后缀。这有一个很好的理由:在Android上,库不是在系统范围内安装的,它们总是应用程序包的一部分,所以版本标记是不必要的。但这种不一致并不能让Android开发者的生活更轻松。

简单的解决方案是在https://stackoverflow.com/questions/23155401/how-to-modify-librtmp-makefile-to-remove-version-suffix中提出的:去掉生成文件中的某个地方的-Wl,--soname=...。不幸的是,这个技巧不适用于NDK r9d或r10c。

但是您可以为./configure指定额外的./configure。以下是命令:

代码语言:javascript
复制
./configure LDFLAGS=-Wl,soname=libexif.so <other parameters>
make
mv /arch-arm/lib/libexif.so.12.3.3 /arch-arm/lib/libexif.so

请注意,您还需要以正确的顺序显式地从Java加载依赖库。例如,静态构造函数将类似于:

代码语言:javascript
复制
static {
    System.load("/data/data/your.package.name/lib/libexif.so");
    System.loadLibrary("exif-native");
}

必须指定libexif.so的完整路径,否则将加载来自/system/lib的库。

Alternatively,您应该重命名库

代码语言:javascript
复制
./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代码可能更干净了:

代码语言:javascript
复制
    System.loadLibrary("exif.12.3.3");
    System.loadLibrary("exif-native");

这是Android.mk的相关片段

代码语言:javascript
复制
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安装后将其解压缩到已知的路径中,然后使用

代码语言:javascript
复制
    System.load("/known/path/libexif.so.12");
    System.loadLibrary("exif-native");

遗憾的是,Android /install对libs/armeabi文件夹中的文件执行过滤,只允许模式lib<whatever>.so

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26690779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档