ldconfig的作用 & 编译时动态的链接问题

参考
1.linux共享库的版本控制和使用 http://lovewubo.github.io/shared_library#
2.知乎 gcc编译过程、gcc命令参数、静态库和动态库搜索路径

1.ld是干什么的

    ld是GNU binutils工具集中的一个,是众多Linkers(链接器)的一种。完成的功能自然也就是链接器的基本功能:把各种目标文件和库文件链接起来,并重定向它们的数据,完成符号解析。

2.动态链接库的命名规则
real name

在 Linux 中,共享库文件的real name为 libname.so.x.y.z。
其中,lib 是共享库文件的固定前缀,而后面的 x、y、z 分别是主版本号、次版本号和发布版本号,name是函数库的名字。

  1. 主版本号不同的共享库是不能相互兼容的。
  2. 如果主版本号相同,而次版本号有升级,表示这个共享库有新接口的添加,但是同时所有老的接口和行为表现都保持不变,是向后兼容的。
  3. 如果主次版本号都相同,只有发布版本号不同,则表示只有 Bug 修复和性能优化,对外的接口和表现都完全相同。
soname (short name)

仅仅有主版本号信息,例如libname.so.x,x为主版本号。在启动ldconfig时被创建,是个符号链接,指向ldconfig运行时,主版本相同的最新的real name 动态共享函数库(sharied library)。

linkname

没有任何版本号信息,即libname.so。link name文件在函数库被安装的时候建立,指向soname 或real name。最好是指向so name。为什么嘞?这样可以在编译的时候自动使用兼容的最新版本的动态共享库。

3. ldconfig

    ldconfig 在每次系统启动时会默认执行,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如,lib*.so*,命名后面会涉及),进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。

       当安装动态库的时候,会把具有real name的真正库文件放在一些特定的路径下(如/usr/local/lib,/usr/lib等),并且创建link name指向real name或soname(如果有的话)。
       安装完后,需要运行ldconfig 命令,该命令会搜索 /etc/ld.so.conf文件中的路径,寻找real name文件,并创建命名为soname的符号链接指向real name,(注意,ldconfig不会做关于link name的任何事情),然后创建 /etc/ld.so.cache文件。
       在运行程序的时候(注意,不是在编译的时候,编译的时候不会使用ld.so.cache文件),ld.so会去一系列路径中寻找运行程序需要的动态库,其中包括去ld.so.cache文件中寻找。

soname 自动更新
       假设有一个函数库liba.so.1.1.0,此时会有一个soname文件(liba.so.1)指向该函数库(liba.so.1.1.0),若再安装一个更新的共享库(liba.so.1.2.0),运行ldconfig,会将soname文件(liba.so.1)指向新的共享库(liba.so.1.2.0),因为只要主版本号不变,老接口就不会改变,这样会让soname永远指向最新的兼容的动态库。

上面说最好让link name指向soname,因为这样做,在编译的时候就可以自动选择最新的动态函数库。为什么嘞?每次编译的时候,ld找的是link name,如果link name指向的是real name,那么就永远只能使用这个real name的文件了。但是,如果指向soname,因为soname永远指向最新兼容库,就可以使得在编译时使用的库是最新的兼容库。

1. 静态链接库搜索路径顺序:

ld会去找gcc命令中的参数-L
环境变量LIBRARY_PATH
默认路径/lib、/usr/lib、/usr/local/lib
LIBRARY_PATH和LD_LIBRARY_PATH区别与使用:

开发时,设置LIBRARY_PATH,以便gcc能够找到编译时需要的动态链接库。
发布时,设置LD_LIBRARY_PATH,以便程序加载运行时能够自动找到需要的动态链接库。

2.动态链接时、执行时搜索路径顺序:

(1)程序运行时,ld.so搜索动态共享库顺序

  1. ELF可执行文件中动态段DT_PATH指定;
  2. gcc加入连接参数“-Wl,-rpath”指定动态库搜索路径,多个路径之间用冒号分隔;
  3. 环境变量LD_LIBRARY_PATH指定路径;
  4. /etc/ld.so.cache中缓存的动态库路径。通过配置文件/etc/ld.so.conf增删路径(修改后需要运行ldconfig命令);
  5. /lib/
  6. /usr/lib/

(2) 程序编译时,ld搜索动态链接库的路径顺序

  1. 编译目标代码时指定的动态库搜索路径;
  2. 环境变量LIBRARY_PATH指定的动态库搜索路径;
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径;/etc/ld/so.conf第一行有个引用命令:include ld.so.conf.d/*.conf;
    因此最优雅的方式是在ls.so.conf.d目录下创建一个自己的程序依赖的配置文件,配置文件内容为程序依赖的动态库路径,一个路径一行;最后ldconfig更新配置文件;
  4. 默认动态库搜索路径/lib/
  5. 默认动态库搜索路径/usr/lib/
3.与动态库链接相关的命令

1)ld是gcc的链接程序;
2)ldd是查看可执行文件中所依赖的库,eg:ldd a.out;
3)ldconfig用来更新/etc/ld.so.conf文件;
4)nm查看.so库中的函数名字,标记是T的就是动态库里面生成的名字;eg:nm -C test|grep static //在程序文本段查找static

4.动态库路径设置方法

LD_LIBRARY_PATH环境变量指定,也可以放到.bashrv中固化下来,可也以放到当前用户的.bashrc只对当前用户有效;

如果启用ls.so.cache的话,系统会在/etc/ld.so.cache中存储所有可引用的动态链接库。这个文件内容可以通过/etc/ls.so.conf来指定;这是比较固定的机制,对全局用户有效;设置后需要root调用ldconfig刷新;

默认的标准库路径,如果是64位,还包括/lib64/、/usr/lib64/
如果只想对某个特定程序起作用,可以在编译时指定搜索路径。gcc的 -Wl和-rpath参数;

/usr/local/lib/和/usr/local/lib64/不在标准路径之列

    soname

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值