共享库的组织
共享库的兼容
由于共享库的优点,许多程序都采用了共享库作为通用的库,而减少了静态库的使用。系统中,就会存在许多的共享库, 各个版本不一。在编译的时候,会在可执行文件的.dynamic段中写入程序依赖的动态库的SO_NAME。SO_NAME是一个类似libname.so.3的字符串,表示依赖名称为name的动态库, 动态库的版本为3.x.x。对于linux,动态库有其命名的规则,为libname.so.3.1.2。版本号的定义遵循semver格式。在linux中,还会存在一个libname.so.3的软链接,指向name对应的主版本为3的最新的版本文件,这样就解决了版本的兼容问题。
gcc -o main -lname // -lname 表示需要链接libname.so.a.b.c, 具体的版本由编译环境决定
但是这个方案无法解决依赖的次版本比实际运行次版本高的问题。次版本号只保证向后兼容, 不保证向前兼容, 可能出现某些接口找不到的问题,需要注意。
共享库的查找路径
程序依赖的共享库会被保存到.dynamic段中, 然后加载的时候由动态链接器进行加载,如果保存的是绝对路径,直接按路径加载;如果是相对路径或者纯文件名,则按/lib, /usr/lib, 和/etc/ld.so.conf配置的路径查找。还有基于ldconfig的缓存优先查找。
还可以基于环境变量LD_LIBRARY_PATH设置优先查找路径
LD_LIBRARY_PATH=/home/lib /bin/ld ./exec_file
查看共享库的查找过程可以设置环境变量 LD_DEBUG, 然后执行程序 会有具体的信息输出。
LD_DEBUG=files ./exec_file
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei
github博客: fishmwei.github.io/