gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 01:16:30 25 4
gpt4 key购买 nike

我正在为 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(符号链接(symbolic link))
  • libexif.so.12(看起来像符号链接(symbolic link),但内容是大二进制文件)
  • libexif.so.12.3.3(实际二进制文件)

我已将最后一个文件重命名为 libexif.so 并根据本网站上的一些建议删除了两个符号链接(symbolic link)。然后我想用我的应用程序构建它并使用以下 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)

编译正确,但是当我在手机上以 Debug模式运行它时,出现此错误:

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 文件以及如何传递它吗?我尝试了一些简单的调整,但不知道如何实现这一点。

非常感谢

最佳答案

图书馆 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: WARNING:jni/Android.mk:...: non-system libraries in linker flags: /somepath/libexif.so

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

这样可以避免的麻烦

Linux 库的 Android 移植的一个典型问题是,后者使用 SONAME 的版本后缀,而 Android NDK 不支持此类后缀。这是有充分理由的:在 Android 上,库不是在系统范围内安装的,它们始终是应用程序包的一部分,因此版本标记是不必要的。但这种不一致并没有让 Android 开发者的生活变得更轻松。

How to modify librtmp Makefile to remove version suffix? 中建议了简单的解决方案:摆脱-Wl,--soname=...在你的 Makefile 中的某个地方。不幸的是,这个技巧不适用于 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 显式加载依赖库。 IE。静态构造函数将如下所示:

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 .

关于android-ndk - Android 共享库中 .so.12 文件的链接不满意,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26690779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com