共享库版本
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
- 动态库的搜索路径搜索的先后顺序是
- 编译目标代码时指定的动态库搜索路径; //LDIRNAME
- 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
- 配置文件/etc/ld.so.conf中指定的动态库搜索路径
只需在在该文件中追加一行库所在的完整路径如"/root/test/conf/lib"即可,然后ldconfig是修改生效。(实际上是根据缓存文件/etc/ld.so.cache来确定路径)
- 默认的动态库搜索路径/lib;(64位机器为/lib64)
- 默认的动态库搜索路径/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
- /etc/ld.preload
- 会覆盖后面装载进来的同名函数 – 用于调试很方便
一个简单的使用sample
环境变量 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之类的进行链接然后运行看看