Android NDK 链接共享库 libxxx.so.ver 而不是 libxxx.so
Android NDK links shared libraries libxxx.so.ver instead of libxxx.so
我使用 ndk-build 编译了我自己的共享库,它依赖于外部共享库(ffmpeg 和 x264)。我定义了外部库,如 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)
并为所有需要的 ABI 安装了外部共享库:
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)
在我的库的 Android.mk 中,我添加了对这个外部库的引用:
LOCAL_SHARED_LIBRARIES += libx264
项目构建良好,外部库已复制到 lib/$(TARGET_ARCH_ABI):
lib
- armeabi
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
- armeabi-v7a
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
而不是 device/simulator。但是,当我使用 System.loadLibrary("mylibrary");
在应用程序中加载我的库时,出现错误:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libx264.so.148" not found
at java.lang.Runtime.loadLibrary(Runtime.java:372)
当我用
检查我的图书馆时
arm-linux-androideabi-readelf -d libs/armeabi-v7a/libmylibrary.so
我明白了:
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
为什么我的 libmylibrary.so 中引用了 libx264.so.148、libavcodec.so.57 等而不是 libx264.so、libavcodec.so 等符合预期吗?
链接器查看库的 soname,而不是文件名。你可以要求./configure
生成没有版本后缀的sonames
我使用 ndk-build 编译了我自己的共享库,它依赖于外部共享库(ffmpeg 和 x264)。我定义了外部库,如 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)
并为所有需要的 ABI 安装了外部共享库:
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)
在我的库的 Android.mk 中,我添加了对这个外部库的引用:
LOCAL_SHARED_LIBRARIES += libx264
项目构建良好,外部库已复制到 lib/$(TARGET_ARCH_ABI):
lib
- armeabi
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
- armeabi-v7a
- - libavcodec.so
- - libavutil.so
- - libswscale.so
- - libx264.so
而不是 device/simulator。但是,当我使用 System.loadLibrary("mylibrary");
在应用程序中加载我的库时,出现错误:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libx264.so.148" not found
at java.lang.Runtime.loadLibrary(Runtime.java:372)
当我用
检查我的图书馆时arm-linux-androideabi-readelf -d libs/armeabi-v7a/libmylibrary.so
我明白了:
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
为什么我的 libmylibrary.so 中引用了 libx264.so.148、libavcodec.so.57 等而不是 libx264.so、libavcodec.so 等符合预期吗?
链接器查看库的 soname,而不是文件名。你可以要求./configure
生成没有版本后缀的sonames