共享库版本
- 1、兼容性,为了使共享库能够有更好的二进制兼容性,最好做到不要使用c++做接口,如果一定要使用需注意(1)不在接口类中使用虚函数;(2)不改变类中任何成员变量的位置和类型
- 2、共享库版本命名
libname.so.x.y.z
x主版本号,x不同共享库不兼容
y次版本号,表示增量升级,添加新接口
z发布版本号,修改错误和性能方面的问题
- 3、SO-NAME,表示一个库的接口,体现一个程序依赖的共享库所需要的最少信息
libname.so.x
linux中通常是以so-name作为链接,指向一个实际的最新的动态库,每次按照新共享库后需执行ldconfig将软链接指向最新的共享库
libname.so.x->libname.so.x.y.z
由于历史原因c语言库和动态链接器的so-name如下
ld-linux.so->ld-2.6.1.so
libc.so.6->libc-2.6.1.so
符号版本
之所以提出符号版本的概念是因为次版本交会问题,使用SO-NAME在程序运行时只判断了主版本,但是主版本号相同的共享库也存在的一定的接口数量的差别,这将导致依赖于SO-NAME并不能保证程序可以正常执行(这个也就是次版本交会问题)。
符号版本的基本思路是让共享库的每一个导入导出符号都有一个相关联的版本号,做法上类似名称修饰的方式。
共享库的系统路径
目前大多数linux系统都支持一个叫做FHS(file hierarchy standard)的标准,规定系统中系统文件应该如何放置,各个目录的结构、组织和作用
FHS中规定了三个共享库的放置目录
- 1、/lib存放系统最关键和基础的共享库,主要是/bin、/sbin和系统启动需要使用到的共享库
- 2、/usr/lib主要存放非系统运行时所需要的关键性共享库,包括一些开发库等
- 3、/usr/local/lib主要存放第三方应用程序的库
共享库的查找过程
动态链接模块所依赖的模块路径保存在.dynamic由DT_NEED类型项表示,通常存放的共享库的相对路径,链接在链接时就需要查找到共享库的实际位置,查找顺序如下
- 0、LD_LIBRARY_PATH变量所指示的路径下查找,这个变量可以临时修改某个程序的共享库查找路径,指定了该变量链接器在查找共享库时会优先查找该变量所指示的路径
- 1、查找/etc/ld.so.cache,由ldconfig创建更新
- 2、查找/lib和/usr/lib目录
与链接相关的环境变量
- 1、LD_LIBRARY_PATH
这个变量可以临时修改某个程序的共享库查找路径,指定了该变量链接器在查找共享库时会优先查找该变量所指示的路径 - 2、LD_PRLOAD
这个变量可以在程序装载其他共享库时,指定预先装载一些共享库,优先于LD_LIBRARY_PATH,且无论程序是否依赖该共享库,均会被加载。(由于该机制的存在,同时还有加载时的全局符号介入机制,导致可以利用该变量对标准库或者其他库中的符号进行替换) - 3、LD_DEBUG
这个变量可以打开动态链接的调试功能,查看到链接的过程中的各种详细信息,如共享库的加载、符号的解析、路径查找等过程
共享库的创建安装
1、创建
gcc -shared -fPIC -Wl,-soname,my_soname -o libname source_file
-shared 表示生成共享库
-fPIC表示使用地址无关代码技术
-Wl表示把后面的参数传递给链接器,例如-soname表示指定共享库的SO-NAME
2、安装
复制到/lib或者/usr/lib或者/usr/local/lib目录下,然后运行ldconfig
3、共享库脚本
前面提到共享库通常是elf的dso文件,但共享库也可以是一个符合一定格式的脚本,通过这种脚本可以把结构现有的共享库通过一定的方式组合起来,从用户的角度就是一个新的共享库,格式如下
GROUP( /lib/libc.so.6 /lib/libm.so.2)
end~
网友评论