动态库名称
Linux上的shared library有三个名字,分别是:
real name
对应文件名称,由主版本号+小版本号+build号组成。比如 libmath.so.1.1.1234
,lib
是Linux
库的约定前缀,math
是共享库名字,so
是共享库的后缀名,1.1.1234
的是共享库的版本号。
主版本号,代表当前动态库的版本,如果共享库的接口发生变化,那么这个版本号就要加1;
后面的两个版本号(小版本号和 build号)是用来指示库的更新迭代号,表示在接口没有改变的情况下,由于需求发生变化等因素,开发的新代码。
so name
运行可执行文件,在加载共享库的时候,应该使用的文件名。其格式为lib + math + .so + (主版本号)
。其只包含主版本号。可以通过readelf -d
命令查看:
msp@msp-OptiPlex-5040:/home/zpp/test$ readelf -d libtest.so.0.0.0 | grep soname
0x000000000000000e (SONAME) Library soname: [libtest.so.0]
so name
需要在编译时指定:
gcc -fPIC -o test.o -c test.c
gcc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.0 test.o
其中libtest.so.0
是so name
, libtest.so.0.0.0
是real name
。
link name
是专门为应用程序在编译时的链接阶段而用的名字。这个名字就是lib + math +.so
,比如libmath.so
。是不带任何版本信息的。
例子
#libtest.so是linkname不带版本号 在可执行文件编译链接的时候使用
lrwxrwxrwx 1 root root 12 10月 25 14:16 libtest.so -> libtest.so.0
#libtest.so.0是soname带主版本号 可执行文件运行加载时使用
lrwxrwxrwx 1 root root 16 10月 25 14:09 libtest.so.0 -> libtest.so.0.0.0
#libtest.so.0.0.1是realname 实际加载的动态库文件
-rwxr-xr-x 1 root root 8120 10月 25 14:08 libtest.so.0.0.0
lrwxrwxrwx 1 root root 16 10月 25 14:13 libtest.so.1 -> libtest.so.1.0.0
-rwxr-xr-x 1 root root 8208 10月 25 14:13 libtest.so.1.0.0
-rwxr-xr-x 1 root root 8600 10月 25 14:16 main
-rw-r--r-- 1 root root 86 10月 25 13:54 main.c
-rw-r--r-- 1 root root 1384 10月 25 13:54 main.o
-rw-r--r-- 1 root root 225 10月 25 14:13 test.c
-rw-r--r-- 1 root root 87 10月 25 14:12 test.h
-rw-r--r-- 1 root root 1896 10月 25 14:13 test.o
其中libtest.so
和libtest.so.0
都是软链接,通过如下方式创建:
ln -s libtest.so.0.0.0 libtest.so.0
ln -s libtest.so.0 libtest.so
使用软链接主要时比较节省磁盘空间,也可以直接将实际的动态库文件拷贝两份,分别重命令为对应的linkname
和soname
。
在可以行文件编译链接动态库时,先通过linkname
找到最终找到real name
,并且把其中的soname
提取出来,写在应用程序自己的文件头的共享库字段里面。
当应用程序运行时,就会通过soname
,结合动态链接程序(ld.so)
,在给定的路径下加载real name
的共享库。
网友评论