让软件支持多个Linux发行版,动态库不兼容?3种解法!( 二 )

我们看到这里的libstc++动态库版本号是6.0.30 。但千万不要误以为这是Linux采用的C++标准库的代码版本号 。动态库版本号 6.0.30 表示该动态库的版本信息 。版本号通常由三个部分组成,分别表示主版本号、次版本号和补丁版本号 。
动态库的版本号通常用于标识软件或库的不同版本,以便用户和系统能够识别和管理不同版本的软件或库 。在使用动态库时,程序会根据需要去加载相应版本的动态库 。
动态库的版本号的确定,通常是由库的开发者或维护者根据库的更新和发布情况分配的 。因此,即使库的代码进行了重大更新,版本号也可能只进行了微小的变化 。所以库的版本号并不一定与库的代码版本直接相关;即使同一个vim软件,在不同的Linux发行版有不同的打包维护人,虽然都从软件官方获得同一源码版本号的vim的代码,但不同Linux发行版的软件打包维护人根据自己发行版的情况决定编译后打包的库文件的版本 。
当然,也有些软件采用两个版本号相等的方式发布软件版本和代码,比如Ubuntu的维护者将OpenGL项目的动态库版本与代码版本保持一致,动态库版本后面以-数字表示该版本代码的第几次正式打包,这个数字每次正式打包前都要+1,如图中的2.2.0-4为Ubuntu 22.04系统的libglew2.2软件包的2.2.0版本的第4次打包入库 。

让软件支持多个Linux发行版,动态库不兼容?3种解法!

文章插图
虽然这个版本经历了4次打包发布,但libglew-2.2.0的4次生成的软件包,在安装后,路径中的动态库的文件名仍保持.so.2.2.0结尾 。
让软件支持多个Linux发行版,动态库不兼容?3种解法!

文章插图
这是因为4次打包期间,库代码接口没变,自然不应该修改X.Y.Z中的任何一个数字 。以免破坏 /usr/lib/x86_64-linux-gnu/libGLEW.so -> libGLEW.so.2.2.0 这种libGLEW.so软链接对实际动态库文件libGLEW.so.2.2.0的链接效果:
让软件支持多个Linux发行版,动态库不兼容?3种解法!

文章插图
开发者可以从哪里查询,动态库文件的版本号与代码版本号的对应关系?如果开发依赖了 OpenGL(v1,v2,v3都有,libGLEW、libGLut、libGL、libegl-mesa0等名称繁多) 这种带有较多版本历史包袱的开发库 , 有时必须确定系统已安装的OpenGL库的版本号跟开发要求的库的代码版本号的是否匹配,才能确保代码调用的函数跟实际运行环境的库的版本能兼容 。
那么如何查询呢?这个问题没有为唯一答案,软件的发布方式和维护形式太多了 。但那些主流的Linux发行版的软件源安装的软件包往往采用了近似的策略,方便了用户查询帮助信息 。如果你的Linux是Ubuntu、centos,那么安装后可以直接从命令中获得大部分信息,包括动态库版本说明:
(1) Ubuntu使用命令$ apt show libglew2.2 查询软件帮助信息
让软件支持多个Linux发行版,动态库不兼容?3种解法!

文章插图
(2) Centos 使用命令$ yum info glew-devel 查询软件帮助信息
[root@device78969 ~]# yum info glew-develLoaded plugins: fastestmirror, ovlLoading mirror speeds from cached hostfile * base: mirrors.ustc.edu.cn * extras: mirrors.aliyun.com * updates: mirrors.163.comAvAIlable PackagesName: glew-develArch: i686Version: 1.10.0Release: 5.el7Size: 172 kRepo: base/7/x86_64Summary: Development files for glewURL: http://glew.sourceforge.NETLicense: BSD and MITDescription : Development files for glewName: glew-develArch: x86_64Version: 1.10.0Release: 5.el7Size: 172 kRepo: base/7/x86_64Summary: Development files for glewURL: http://glew.sourceforge.netLicense: BSD and MITDescription : Development files for glew最后,分享3个思路,解决运行时动态库不兼容问题这是很多开发者发布软件包时最头痛的 , 系统自带的动态库版本,与软件运行所要求的动态库不兼容,直接影响了软件在Linux当前系统的正常功能 。
让软件支持多个Linux发行版,动态库不兼容?3种解法!

文章插图
评论区有网友指出,动态库最大的弊端是跨Linux发行版部署的时候 , 常因为依赖的动态库版本在不同Linux上实际安装的是不同版本,两个版本的动态库未保持向低版本兼容 , 导致主程序找不到合适的依赖库版本而无法运行 。
下面介绍针对这个问题的3种解法(实际本质上是2种:被动、主动)
思路1:由shell脚本帮助载入合适的动态库:通过局部环境变量设置 LD_LIBRARY_PATH 和 PRE_LOAD,让软件优先使用受支持版本的动态库 。
LD_PRELOAD 环境变量用于指定在加载动态链接库时优先加载的库文件 。通过设置 LD_PRELOAD 环境变量,你可以在程序加载动态链接库之前加载你自己的库文件,从而实现对程序行为的修改或调试 。


推荐阅读