Linux动态链接库.so文件的命名

我们在linux下开发项目,有时会对外提供动态库,像***.so.1.0.0这样子的文件,另外提供相应的头文件。用户拿到动态库和头文件说明,就可以使用动态库里的function。

那随之而来的一个问题是,动态库的升级问题,我们的动态库更改了一个bug,升级了一个版本,那使用我们动态库的应用程序需要重新编译吗?运行时会产生异常吗?linux下是怎么规范这些内容的呐?

大家一定听说过windows下的dll hell。

Linux中的.so文件 是动态链接的产物
共享库理解为提供各种功能函数的集合,对外提供标准的接口
Linux中命名系统中共享库的规则

主版本号:不同的版本号之间不兼容
次版本号:增量升级 向后兼容
发行版本号:对应次版本的错误修正和性能提升,不影响兼容性

下面说说linux下动态库的命名规范。

为方便管理依赖关系,创建或部署共享库时,必须遵循统一约定的规则才行,其中包括动态库的命名规则及其部署方式。

共享库命名约定

  1. 每个动态库有一个包含了真正的库代码的文件名,通常被称为库的 realname ,命名格式通常为

libxxx.so.x.y.z,其中so后缀中的x为主版本号,y为副版本号,z为发行版本号。例如,我的linux系统机器上zlib共享库的realname为 libz.so.1.2.8,这个文件是含有可执行的二进制代码的。

  1. 每个动态库都有一个以"lib"为前缀且以".so.x"为结尾的被称为 soname

的特定名称,其中x为主版本号,soname命名格式通常为libxxx.so.x。例如,我的linux系统机器上zlib共享库的soname为libz.so.1。这个soname包含了动态库的主版本号,这个doname一般会包含在库代码的头文件中,这个可以使用 readelf -d 读取出来,使用这个动态库的程序的二进制ELF的头文件中包含有这个动态库的soname。程序运行时会按照这个名称去找真正的库文件。

ldd

  ldd不是一个可执行程序,而只是一个shell脚本 ldd能够显示可执行模块的dependency(所属)(所属),其原理是通过设置一系列的环境变量,如下:LD_TRACE_LOADED_OBJECTS、LD_WARN、LD_BIND_NOW、LD_LIBRARY_VERSION、LD_VERBOSE等。当LD_TRACE_LOADED_OBJECTS环境变量不为空时,任何可执行程序在运行时,它都会只显示模块的dependency(所属),而程序并不真正执行。要不你可以在shell终端测试一下,如下: export LD_TRACE_LOADED_OBJECTS=1 再执行任何的程序,如ls等,看看程序的运行结果。

  ldd显示可执行模块的dependency(所属)的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现的。我们知道,ld-linux.so模块会先于executable模块程序工作,并获得控制权,因此当上述的那些环境变量被设置时,ld-linux.so选择了显示可执行模块的dependency(所属)。 实际上可以直接执行ld-linux.so模块,如:/lib/ld-linux.so.2 --list program(这相当于ldd program)

原文地址:https://www.cnblogs.com/chendeqiang/p/15172099.html