程序员的自我修养 chapeter 8 Linux共享库(.so)的组织

15 篇文章 0 订阅

共享库版本

readelf -d 是dump .dynamic字段的意思

  • readelf -x=< number | name >
    可以指定dump相应的.name的section

reference

reference1 比较全面,还讲了没找到库时的常用解决方法

  • 如果要链接libm.so.2.1.6( 数学库 )

    • 直接 gcc xx.c -lm [ 前提是 math必须在/lib /usr/lib /usr/local/lib三个路径下 ]
    • 如果不在上述三个目录是找不到的 所以用-L参数指定目录 ,紧跟在L之后即可
      • gcc xx.c -L/aaa/bbb/ccc -ltest ( libtest.so在/aaa/bbb/ccc这个目录下 )
  • 自动生成链接参数

    • xxxx-config,一般放在/usr/bin
    • gcc test.cc `xxxx-config --libs --cflags` 可以使用xxxx-config里面的lib和cflags配置 (详见reference1)
  • -l参数默认是寻找动态共享库(.so),找不到的情况下找静态库(.a)

    • 如果想要强制使用静态链接 , 就要加上-static参数,这样一来就会把所有的库都变成了静态链接(想要混着来也可以 还要加一些配置)


8.2 符号版本

用到再看吧

8.3 共享库系统路径

还是那三个三个路径
/lib、/usr/lib、/usr/local/lib

8.4 共享库查找过程

  • /etc/ld.so.conf
  • ldconfig命令
    • 会更新共享库的SO-NAME
    • 会生成一个/etc/ld.so.cache的SO-NAME缓存

环境变量 LD_LIBRARY_PATH

  • 临时改变某个应用程序的链接搜索路径 且不影响其他程序
  • 相当于gcc的-L参数
  • 不应该滥用,更不应该export,很容易影响到别的进程
  • 两种修改方式
    在这里插入图片描述
  • 这里注意,提到了共享库的搜索顺序。【设计原则就是由局部变量到全局变量】

更好的summary:ldconfig , ldd 与 LD_LIBRARY_PATH

  • 动态库的搜索路径搜索的先后顺序是
  1. 编译目标代码时指定的动态库搜索路径; //LDIRNAME
  2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径

只需在在该文件中追加一行库所在的完整路径如"/root/test/conf/lib"即可,然后ldconfig是修改生效。(实际上是根据缓存文件/etc/ld.so.cache来确定路径)

  1. 默认的动态库搜索路径/lib;(64位机器为/lib64)
  2. 默认的动态库搜索路径/usr/lib。(64位机器为/usr/lib64)
Linux 运行的时候,是如何管理共享库(*.so)的?

在 Linux 下面,共享库的寻找和加载是由 /lib/ld.so 实现的。 ld.so 在标准路经(/lib, /usr/lib) 中寻找应用程序用到的共享库。 但是,如果需要用到的共享库在非标准路经,ld.so 怎么找到它呢?

  • 目前,Linux 通用的做法是将非标准路经加入 /etc/ld.so.conf,然后运行 ldconfig 生成 /etc/ld.so.cache。 ld.so 加载共享库的时候,会从 ld.so.cache 查找。
  • 传统上,Linux 的先辈 Unix 还有一个环境变量:LD_LIBRARY_PATH 来处理非标准路经的共享库。ld.so 加载共享库的时候,也会查找这个变量所设置的路经。
  • LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib export LD_LIBRARY_PATH 但是,有不少声音主张要避免使用 LD_LIBRARY_PATH 变量,尤其是作为全局变量

ldd的作用

ld dependency

环境变量 LD_PRELOAD

环境变量 LD_DEBUG

  • 用于调试链接过程非常有用,可以用来查看程序搜索库的路径
  • LD_DEBUG=files / all / help / versions / reloc等等等等
  • 使用example:
# 比如说你想要看某次gcc过程中找库的目录
$ LD_DEBUG = libs gcc test.cc -o test
# 然后就会输出相应的过程和结果
 
# 还可以指定输出文件
$ LD_DEBUG=help,output=rtld-debug.txt prog
	# 另一种方式就是指定LD_DEBUG_OUTPUT变量 (两种方式共存的时候,LD_DEBUG_OUTPUT优先级更高)


  • gcc命令其实是多个命令的合集 里面includes ld命令,我们可以使用-Wl,-rpath,值(或者-soname,值) 之类的形式,这样gcc命令在被拆解到ld命令那一步的时候就会带上这些参数

summary

  • 安装库的时候尽量不管三七二十一就ldconfig一下,能省去不少麻烦。

    注意,这里说的安装,如果你不是安装,ldconfig的意义就不大了,那主要还是得靠指定路径的方式

  • task : 试试创建一个.so文件 然后创建相应的软链接,然后使用-rpath之类的进行链接然后运行看看
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值