命名规则
linux共享库版本命名
libname.so.x.y.z
前缀lib,中间是库的名字和后缀.so,后面的三个数字组成版本号,“x”表示主版本号,“y”表示此版本号,“z”表示发布版本号,这个三个版本号的具体含义:
- 主版本号:表示库的重大升级,不同版本号的库之间是不兼容的,依赖与旧的版本号的程序要改动相应的部分,并且重新编译。才可以在新版的共享库中运行,或者系统必须保留旧版的共享库,使得那些依赖于旧版共享库的程序能够正常运行
- 次版本号:表示库的增量升级,即增加一些新的接口符号,并保持原有的符号不变,在主版本号相同的情况下,高的此版本号的库向后兼容低的次版本好的库。
- 发布版本号:表示库的一些错误的修正和性能的改进等,并不添加任何新的接口,也不对接口进行更改,相同主,次版本好的共享库,不同发布版本号之间完全兼容。
也有部分不遵守上述规定的共享库,如glibc,它的c语言库的命名就是libc-x.y.z.so,glibc包含许多组件,C语言库只是其中一个,动态链接器也是glibc的一部分 ,它的命名:
ld-x.y.z.so
SO-NAME软连接
Linux 系统中会为每个共享库在它的在目录创建一个用库的SO-NAME命名的并指向它的软链接,SO-NAME就是共享库的文件名去掉次版本号和发布版本号,如下图,建立软连接的目的是当共享库进行升级的时候,如果只是增量升级,即主版本号不变,可以直接将新版的共享库替换掉旧版,并修改so-name的软链接指向新版的共享库,即可实现升级。
链接名
编译使用共享库时,例如GCC 使用 -l 参数链接共享库libxxx.so.2.1.1,只需要-lxxx,xxx 就是共享库的连接名,编译器会根据当前环境,在相关路径查找最新版本的xxx库。不同类型的库可能有相同的链接名,比如c语言运行库Libc.a,libc.so.x.y.z,那么链接器会根据输出文件的情况动态来选择静态还是动态库,比如,ld 使用 -static 参数,就会查找libc.a,而使用 -Bdynamic 就会查找最新版本的libc.so.x.y.z
共享库系统路径
FHS 标准 规定了开源操作系统(包括linux)的文件如何存放,其中共享库的存放位置主要有三个
- /lib
- /usr/lib
- /usr/local/lib
前两个时一些很常用的,系统本身需要的库,第三个一般是非系统所需的第三方共享库
查找规则
动态链接器会按照下列次序一次装载和查找共享库
- 由环境变量LD_PRELOAD 指定的预先装载的共享库,无论程序是否依赖,都会被装载 ,主要用于调试,正常情况应避免使用
- 由环境变量LD_LIBRARY_PATH 指定的路径,主要用于调试以及测试新的共享库,正常情况应避免使用
- 由路径缓存文件/etc/ld.so.cache指定的路径。这个文件用来收集共享库的存放路径,加快共享库的查找过程。
- 默认共享库目录,先/usr/lib/,然后/lib
参考资料:
《程序员的自我修养-链接,装载与库》
,