先看下ffmpeg的例子,fmpeg的编译输出中libavcodec库有三个文件,分别如下:
libavcodec.so # linkname
libavcodec.so.58 # soname
libavcodec.so.58.134.100 # realname
libavcodec.so.58.134.100这个名字中,58是主版本号,134是副版本号,100是发行版本号,ls -l可以看到linkname
和soname
的文件是指向realname
的。
所以,Linux中共享库的命名规则是这样的:
lib<name>.so.<major>.<minor>.<release>
- major:主版本号
- minor:副版本号
- release:发行版本号
每个动态库有一个包含了真正的库代码的文件名,通常被称为库的 real name ,命名格式通常为lib<name>.so.<major>.<minor>.<release>
每个动态库都有一个以lib为前缀且以.so.major
为结尾的被称为 so name,so name命名格式通常为libxxx.so.major
,如前面的libavcodec.so.58
就是libavcodec的so name。使用 readelf -d 可以读取出来这个动态库的so name。
依赖了共享库的模块后,链接器只认不带任何版本号的共享库名, 称作linker name
。
libavcodec在编译完成后linker name文件和soname文件都是指向real name的符号文件:
$ ls -l libavcodec*
libavcodec.so -> libavcodec.so.58.134.100
libavcodec.so.58 -> libavcodec.so.58.134.100
libavcodec.so.58.134.100
readelf -d
可以查看库的soname:
$ readelf -d libavcodec.so
Dynamic section at offset 0x7a43e8 contains 40 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libswresample.so.3]
0x00000001 (NEEDED) Shared library: [libavutil.so.56]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [liblzma.so.5]
0x00000001 (NEEDED) Shared library: [libz.so.1]
0x00000001 (NEEDED) Shared library: [libtheoraenc.so.1]
0x00000001 (NEEDED) Shared library: [libtheoradec.so.1]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld-linux-armhf.so.3]
0x0000000e (SONAME) Library soname: [libavcodec.so.58]