- A+
动态链接库的三个名字
1. realname, 真正的名字,一般情况下如果你有版本,应该在后面加上lib[libraryname].so.[version] eg: libtest.so.1.0.0
2. soname, 在编译动态库的时候指定的名字,这个名字将会被添加到动态库的头部,通过readelf -d 可以查看, 这个名字是可以没有的。一般为lib[libraryname].so.i 或 lib[libraryname].so.i.i.
3. linkname, 可执行文件在加载动态库的时候查找的名字,lib[libraryname].so, 后面没有版本号,若soname存在,最后动态库连接到的是soname,若soname不存在,而linkname直接软连接到真正的库名称上面, 可执行文件就将linkname当作soname.
lrwxrwxrwx 1 root root 28 Aug 1 15:59 /usr/local/lib/libopencv_xfeatures2d.so -> libopencv_xfeatures2d.so.3.4
-rw-r--r-- 1 root root 3090824 Aug 1 22:07 /usr/local/lib/libopencv_xfeatures2d.so.3.4.2
上面的例子就阐述了opencv的连接关系 libopencv_xfeatures2d.so 是linkname, 是编译可执行文件的时候查找的名字,
libopencv_xfeatures2d.so.3.4 是 soname, 这个名字也被嵌入在libopencv_xfeatures2d.so.3.4.2头部,我们通过readelf -d 查看一下
readelf -d /usr/local/lib/libopencv_xfeatures2d.so.3.4.2 | grep soname
0x000000000000000e (SONAME) Library soname: [libopencv_xfeatures2d.so.3.4]
这样的做法允许了动态库真正的realname更新的时候(小版本更新,原有接口不变), soname本身的名字不需要改变,linkname一直不需要改变,而linkname软连接的soname对象也不需要改变,只需要改变soname软连接的realname动态库就可以了
1. 可以通过手动改变软连接
2. 可以通过执行ldconfig操作,前提是动态库路径在xx.conf文件中, 或者在LD_LIBRARY_PATH中
若两个realname在头部有同样的soname,ldconfig会选取版本更高的进行软连接。
libtestuser.so libtestuser.so.1.0 libtestuser.so.1.0.0
假设现在有这三个文件,分别是我们前面所说的三个linkname, soname, realname,
现在有一个main.cpp, 依赖这个动态库,编译它
注意我已经在/etc/ld.so.conf.d/xx.conf里面添加了这里的路径并且更新了ldconfig,这样linker才能查找到这个库。
g++ main.cpp -o main -L./build -ltestuser
通过两种方式查看一下main的依赖
blindfind@blindfind:~/gitlab/test$ ldd main linux-vdso.so.1 => (0x00007ffd9c98f000) libtestuser.so.1.0 => /home/blindfind/gitlab/test/build/libtestuser.so.1.0 (0x00007f380cd1b000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f380ca0c000)
2.
readelf -d main | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libtestuser.so.1.0]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
可以看见实际上依赖找的是soname,而soname是嵌入在真正的动态库里面的。
再说明一下动态库依赖动态库的问题
如果liba.so 依赖 libb.so, 而main依赖liba.so, 如何做到编译main的时候不指定libb.so的路径?
虽然编译动态库并不需要指定依赖路径,但是这时候指定可以不再main编译的时候再次指定liba依赖的动态库了
blindfind@blindfind:~/gitlab/test$ g++ -shared -fPIC -Wl,-soname,libtestuser.so.1 -o libtestuser.so.1.0.0 testUser.cpp -L. -ltest
blindfind@blindfind:~/gitlab/test$ ls
build CMakeLists.txt libtest.so libtest.so.1 libtest.so.1.0.1 libtestuser.so.1.0.0 main main.cpp test.cpp test.h testmore test.o testUser.cpp testUser.h
blindfind@blindfind:~/gitlab/test$ ldd libtestuser.so.1.0.0
linux-vdso.so.1 => (0x00007ffc9d3e2000)
libtest.so.1 (0x00007ffae2802000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ffae24d5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffae210a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ffae1e02000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffae2c08000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ffae1bec000)
这时候进行指定,可以看见libtestuser依赖了libtest
看一下libtestuser的soname.
readelf -d libtestuser.so.1.0.0 | grep soname 0x000000000000000e (SONAME) Library soname: [libtestuser.so.1]
执行ldconfig,可以看见多了libtestuser.so.1 的软连接,这是通过查看libtestuser.so.1.0.0 的soname决定的
blindfind@blindfind:~/gitlab/test$ sudo ldconfig
[sudo] password for blindfind:
blindfind@blindfind:~/gitlab/test$ ls
build CMakeLists.txt libtest.so libtest.so.1 libtest.so.1.0.1 libtestuser.so.1 libtestuser.so.1.0.0 main main.cpp test.cpp test.h testmore test.o testUser.cpp testUser.h
然后编译main函数,不指定libtest.so,光指定libtestuser.so, 别忘了先添加linkname的软连接 ln -s libtesetuser.so.1 libtestuser.so
blindfind@blindfind:~/gitlab/test$ g++ main.cpp -o main -L. -ltestuser
blindfind@blindfind:~/gitlab/test$ ldd main
linux-vdso.so.1 => (0x00007ffe03917000)
libtestuser.so.1 (0x00007f86d92e1000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f86d8fb4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f86d8be9000)
libtest.so.1 (0x00007f86d89e7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f86d86df000)
/lib64/ld-linux-x86-64.so.2 (0x00007f86d94e5000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f86d84c8000)
blindfind@blindfind:~/gitlab/test$ ./main
blindfind@blindfind:~/gitlab/test$
main执行成功,而且ldd查看以后,发现libtest.so自动被添加了进来,因为libtestuser.so依赖libtest.so
- 安卓客户端下载
- 微信扫一扫
- 微信公众号
- 微信公众号扫一扫