依赖
查看 so
依赖的 so
curl -OL "https://dl.google.com/android/maven2/com/google/ar/core/1.38.0/core-1.38.0.aar"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 353k 100 353k 0 0 500k 0 --:--:-- --:--:-- --:--:-- 504k
unzip -d core-1.38.0 core-1.38.0.aar "jni/arm*"
readelf -d core-1.38.0/jni/arm64-v8a/libarcore_sdk_jni.so
Dynamic section at offset 0x17018 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libarcore_sdk_c.so]
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x000000000000000e (SONAME) Library soname: [libarcore_sdk_jni.so]
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x0000000000000007 (RELA) 0x7d80
0x0000000000000008 (RELASZ) 192 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 8
0x0000000000000017 (JMPREL) 0x7e40
0x0000000000000002 (PLTRELSZ) 432 (bytes)
0x0000000000000003 (PLTGOT) 0x17230
0x0000000000000014 (PLTREL) RELA
0x0000000000000006 (SYMTAB) 0x2f0
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x35b4
0x000000000000000a (STRSZ) 18376 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x23d8
0x0000000000000004 (HASH) 0x2bbc
0x000000000000001a (FINI_ARRAY) 0x17008
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x000000006ffffff0 (VERSYM) 0x20c0
0x000000006ffffffc (VERDEF) 0x233c
0x000000006ffffffd (VERDEFNUM) 2
0x000000006ffffffe (VERNEED) 0x2374
0x000000006fffffff (VERNEEDNUM) 3
0x0000000000000000 (NULL) 0x0
readelf -d core-1.38.0/jni/arm64-v8a/libarcore_sdk_c.so
Dynamic section at offset 0x10018 contains 30 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libandroid.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x000000000000000e (SONAME) Library soname: [libarcore_sdk_c.so]
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW
0x0000000000000007 (RELA) 0x5e40
0x0000000000000008 (RELASZ) 168 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffff9 (RELACOUNT) 7
0x0000000000000017 (JMPREL) 0x5ee8
0x0000000000000002 (PLTRELSZ) 264 (bytes)
0x0000000000000003 (PLTGOT) 0x10210
0x0000000000000014 (PLTREL) RELA
0x0000000000000006 (SYMTAB) 0x2f0
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000005 (STRTAB) 0x3854
0x000000000000000a (STRSZ) 9706 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x2570
0x0000000000000004 (HASH) 0x2dd4
0x000000000000001a (FINI_ARRAY) 0x10008
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x000000006ffffff0 (VERSYM) 0x2258
0x000000006ffffffc (VERDEF) 0x24f8
0x000000006ffffffd (VERDEFNUM) 2
0x000000006ffffffe (VERNEED) 0x2530
0x000000006fffffff (VERNEEDNUM) 2
0x0000000000000000 (NULL) 0x0
libarcore_sdk_jni.so
NEEDED
libarcore_sdk_c.so
和其它Android
系统库(libandroid.so
,liblog.so
等),libarcore_sdk_c.so
除了系统库之外不依赖其它so
。
将这样的依赖信息用 Graphviz Dot
语言 描述出来,如下:
libarcore_sdk_jni.dot
digraph libarcore_sdk_jni {
libarcore_sdk_jni [label="libarcore_sdk_jni.so"]
libandroid [label="libandroid.so"]
liblog [label="liblog.so"]
libc [label="libc.so"]
libm [label="libm.so"]
libdl [label="libdl.so"]
libarcore_sdk_jni -> { libarcore_sdk_c libandroid liblog libc libm libdl }
libarcore_sdk_c [label="libarcore_sdk_c.so"]
libandroid [label="libandroid.so"]
liblog [label="liblog.so"]
libc [label="libc.so"]
libm [label="libm.so"]
libdl [label="libdl.so"]
libarcore_sdk_c -> { libandroid liblog libc libm libdl }
}
可以得到libarcore_sdk_jni.so
的 so
依赖 DAG
(有向无环图):
http://www.webgraphviz.com/
http://magjac.com/graphviz-visual-editor/
ps. 有部分 so
的 Vendor
会将 .dynamic Section
的名字给删掉,导致readelf -d
读不了,可以使用 readelf -d -–use-dynamic
查看 so 的 Build ID
file core-1.38.0/jni/arm64-v8a/libarcore_sdk_jni.so
core-1.38.0/jni/arm64-v8a/libarcore_sdk_jni.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=c6cb00844756c8d0504c8c15dd4340bc, stripped
BuildID[md5/uuid]=c6cb00844756c8d0504c8c15dd4340bc
,这个就是该so
的唯一编码Build ID
该Build ID
其实是放在so
的 .note.gnu.build-id NOTE Section
中,通过启用linker
的 --build-id
选项生成。
readelf --hex-dump=.note.gnu.build-id core-1.38.0/jni/arm64-v8a/libarcore_sdk_jni.so
Hex dump of section '.note.gnu.build-id':
0x000002d0 04000000 10000000 03000000 474e5500 ............GNU.
0x000002e0 c6cb0084 4756c8d0 504c8c15 dd4340bc ....GV..PL...C@.
Android NDK
会自动添加编译参数-Wl,--build-id
,用于给最终生成的so
带上 Build ID
:
string(APPEND _ANDROID_NDK_INIT_LDFLAGS " -Wl,--build-id=sha1")
详见:https://android.googlesource.com/platform/ndk/+/refs/heads/main/build/cmake/flags.cmake#46
ps. 这个 Build ID
一般是用来给调试器(如lldb
)识别 so debug
符号表用的。通常情况下,带 debug info
的未被 stripped
的 so
和已经被 stripped so
的 Build ID
是一样的。