动态链接库的三个名字

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
lrwxrwxrwx 1 root root      30 Aug  1 15:59 /usr/local/lib/libopencv_xfeatures2d.so.3.4 -> libopencv_xfeatures2d.so.3.4.2
-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 soname0x000000000000000e (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的依赖

1.

blindfind@blindfind:~/gitlab/test$ ldd mainlinux-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 NEEDED0x0000000000000001 (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 soname0x000000000000000e (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 mainlinux-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
4
blindfind@blindfind:~/gitlab/test$

main执行成功,而且ldd查看以后,发现libtest.so自动被添加了进来,因为libtestuser.so依赖libtest.so

Linux 中动态链接库的版本号以及ldconfig相关推荐

  1. linux中动态链接库用扩展名,Linux操作系统下动态库的生成及链接方法是什么?...

    Linux下动态库文件的扩展名为".so"(Shared Object).按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号).这样,线程函数库被称作l ...

  2. bazel 链接第三方动态库_C语言学习篇(31)——linux中制作动态链接库

    引言 前面我们讲解了什么是函数库(函数库就是一些事先写好的函数集合),函数库有什么作用(可以打包我们的编写的源代码,供他人使用,同时源码不可见,保护了自己的知识产权)以及函数库有2种提供方式:静态链接 ...

  3. linux 查oracle版本号,查看linux中oracle版本号的方法总结

    在Linux系统下,我们通过以下的方法可以查看到Oracle的版本号.下面由学习啦小编整理了查看linux中oracle版本号的方法总结,希望对你有帮助. 查看linux中oracle版本号的方法总结 ...

  4. Linux与Windows中动态链接库的分析与对比

    摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...

  5. 浅谈Linux中ldconfig和ldd的用法

    ldd 查看程序依赖库 ldd 作用:用来查看程式运行所需的共享库,常用来解决程式因缺少某个库文件而不能运行的一些问题. 示例:查看test程序运行所依赖的库: /opt/app/todeav1/te ...

  6. linux中ldconfig的使用介绍

    linux中ldconfig的使用介绍 ldconfig是一个动态链接库管理命令,其目的为了让动态链接库为系统所共享. ldconfig的主要用途: 默认搜寻/lilb和/usr/lib,以及配置文件 ...

  7. ldconfig mysql_浅谈Linux中ldconfig和ldd的用法

    ldd 查看程序依赖库 ldd 作用:用来查看程式运行所需的共享库,常用来解决程式因缺少某个库文件而不能运行的一些问题. 示例:查看test程序运行所依赖的库: /opt/app/todeav1/te ...

  8. LINUX系统中动态链接库的创建与使用

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀 的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不 同,它里面的函数并不是执行程序本身的 ...

  9. linux动态库ppt,LINUX系统中动态链接库创建与使用补充_区块链白皮书代写|市场计划书项目PPT设计_Tbleg...

    区块链白皮书代写 大家都知道,在WINDOWS系统中有很多动态链接库(以.DLL为后缀文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面函数并不是执行程 ...

  10. LINUX系统中动态链接库的创建和使用

    大家都知道,在windows系统中有非常多的动态链接库(以.dll为后缀的文件,dll即dynamic link library).这种动态链接库,和静态函数库不同,他里面的函数并不是执行程式本身的一 ...

最新文章

  1. 一.Linq to JSON是用来干什么的?
  2. 李雷和韩梅梅的一次转账事务–事务系统概述
  3. VTK:PolyData之Stripper
  4. 剑指offer之礼物的最大值
  5. redis 中文API说明
  6. ZeroClipboard实现复制
  7. 2010年一些零散的总结4
  8. 常用传感器讲解四--水位传感器(water sensor)
  9. Visio画图如何保存高质量图片供论文使用
  10. 抠图软件哪个好用又免费?快来看看这几款软件
  11. 编译和push services.jar的方法
  12. 思维 POJ - 2361 Tic Tac Toe
  13. C语言程序设计精髓(MOOC第12周 )题
  14. Codeforces Round #643 (Div. 2) C. Count Triangles 题解(思维)
  15. 从数据结构及汇编角度深入学习go语言
  16. 安卓盒子 魔百盒311-1a YST 刷Armbian系统刷机教程
  17. 非计算机专业学生计算机基础知识和应用能力,全国高校非计算机专业学生计算机基础知识和应用能力等级考试大纲...
  18. perl Carp模块使用举例(转)
  19. postgresql 安装 配置远程访问 PostgreSQL WAL日志解析工具: wal2json cdc数据同步方案
  20. Android CMake 编译so库

热门文章

  1. stranssen矩阵乘法公式简易记法
  2. extmail mysql数据库 重启_linux下安装和配置extmail
  3. 物联那点事儿之自制网络温湿度计(arduino+点灯科技篇)
  4. 智方8000系文具进销存管理系统 华军软件网
  5. vs2003 常见问题及处理
  6. ACM入门之新手入门
  7. 项目——网络对战五子棋(Web-Gobang)
  8. linux qt qpa linuxfb,Linux qt qt.qpa.plugin: Could not load the Qt platform plugin xcb error解决方...
  9. 阿里云大学>【Python学习路线】Python语言基础自测考试 - 初级难度 | 包过关系列
  10. 服务器显示阵列卡升级,dell r730服务器更换阵列卡后报错,弹出黑框