我们在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,这个文件是含有可执行的二进制代码的。
2) 每个动态库都有一个以”lib”为前缀且以”.so.x”为结尾的被称为soname的特定名称,其中x为主版本号,soname命名格式通常为libxxx.so.x。例如,我的linux系统机器上zlib共享库的soname为libz.so.1。这个soname包含了动态库的主版本号,这个soname一般会包含在库代码的头文件中,这个可以使用 readelf -d 读取出来,使用这个动态库的程序的二进制ELF的头文件中包含有这个动态库的soname。程序运行时会按照这个名称去找真正的库文件。
3) 此外,编译链依赖了共享库的应用模块时,链接器只认不带任何版本号的共享库名, 可以将库名称作linker name。
例如,我的linux系统机器上zlib共享库的linkername为libz.so。也即,链接使用了动态库的程序时查找的动态库名称。例如:gcc -o test test.o -lz , 链接时就会找libz.so 。若没有这个文件,链接器就报错。