Alexander Ushakov
Alexander Ushakov

Reputation: 5397

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?

Upvotes: 0

Views: 1262

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57183

The linker looks at the soname of libraries, not the file names. You can ask ./configure to generate sonames without version suffix

Upvotes: 1

Related Questions