Linux下动态链接库相关杂记(讨论稿)

Linux下动态链接库相关杂记(讨论稿)

目录

Linux下动态链接库相关杂记(讨论稿)

SO-Name规则

一般共享库的安装位置

共享库的查找过程

在链接时指定动态库的搜索位置(需要讨论)


SO-Name规则

根据Linux下SO文件的命名对则,libkkk.x.y.z中,如果x相同,那么这个库的高y可以兼容这个库的低y情况。所以Linux有专门的工具可以处理这样的情况,也就是使用

一个符号链接,指向同一个库同x最高y的动态库实例(用x区分彼此)。例如下面FFMPEG中libavcodec库的链接文件及原本的库文件。Linux这样的动态库机制也建议在日常使用代码的时候遵循。

为了查找方便,Linux下维护SO-Name的ldconfig程序会生成一个/etc/ld.so.cache文件作为SO-name的缓存,方便查找。

一般共享库的安装位置

1.1 /lib:这个地方存放了一些重要的基础库,例如启动时使用的库或者/bin或者/sbin下程序需要的库。最重要的,动态链接器放在这里。

在我的机器上,64位链接器就放在/lib下,32位的链接器放在/lib32下面。

1.2 /usr/lib和/usr/local/lib:前者放一些对于系统不那么关键,但是可能是开发时使用的库。后者是第三方程序运行时候的库。但是在我的发行版(Arch)上面,/usr/local/lib下面空空如也,所有的库全部堆到了/usr/lib下面。从我个人感觉,这俩的划分也不是很明确,所以我把这俩合成一个条目了。但是在搜索动态库的过程中,这个顺序需要注意。

共享库的查找过程

首先明确,我认为这个搜索过程就是指运行时动态链接器的搜索位置。

在编译共享库的时候,会指定其依赖的共享库 。保存在.dynamic中的DT_NEED类型的表项中。下图是FFMPEG的libavcodec库使用readelf获取到的其依赖项目。

可以发现,表项中全部是文件名,也就是相对路径。如果是绝对路径,那么就直接装载。对于相对路径,具体的查找路径为/lib、/usr/lib和/etc/ld.so.conf(里面可能会include其他文件)中指定的路径中找。

使用LD_LIBRARY_PATH临时改变动态库的搜索路径。加上这个之后,我们可以知道动态库的最终搜索路径:

首先搜索LD_LIBRARY_PATH制定路径

其次ld.so.cache中缓存的内容

最后/usr/lib以及之后的/lib

在链接时指定动态库的搜索位置(需要讨论)

我的理解是这样的:动态链接既然是推迟到了运行时再进行链接,那么编译和装载实际上被分成了两个部分进行:在编译时保留的“存根”表示这个符号是一个动态链接

符号(要不然谁知道是不是忘了定义?)。在保留“存根”的过程中,需要指定一次位置,这个位置的指定是要靠-L这个参数来指定的。如果这一次没有指定,链接直接失败。

因为有符号是没有决议的。

假设目前存在三个文件:link.cc(在link目录下),link2.cc以及最终定义了main函数的test.cc。link2.cc需要依赖link目录下的link.cc。首先编译link.cc,生成了liblink.so。

这一步不会有问题,因为link.cc没有依赖其它.cc文件。

在编译link2.cc这个文件的时候出现了问题:liblink.so这个文件找不到了。按照之前所说,link目录并不在当前动态库搜索路径中,所以自然也就找不到。

这样,链接的过程就可以进行下去了。但是使用ldd命令发现,liblink.so处于no found状态,也就是说,运行时动态链接器还是没有找到这个文件。

这说明,-L命令是在编译留"存根"时使用的路径,而在运行时,动态链接器需要另一个命令来找到并装载这个其所需要的库。这个指定命令,就是通过-rpath来完成的。

链接期的rpath信息要怎么传递给运行时的动态链接器,肯定是需要记录相关信息的。使用readlelf命令读取liblink2.so的.dynamic段,发现多出了一个信息,也就是rpath。

有了rpath,就像使用了LD_LIBRARY_PATH变量一样,指明了动态库的搜索路径。

现在两个基础库有了,可以i编译test.cc。有一个问题:既然我们在编译liblink2.so的时候,传入了rpath,那么动态链接器可以读入liblink2.so然后发现liblink.so其实在link目录下,从而自动去链接吗?

在编译test.cc的时候并没有刻意去链接link目录下的动态库,但是可以发现,liblink.so还是被正确的装载了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值