我有一个名为“alpha”的二进制可执行文件,需要一个链接库(libz.so.1.2.7),该库位于/home/username/myproduct/lib/libz.so.1.2.7
在通过执行以下命令生成二进制可执行文件之前,我将其导出到终端实例。
export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH
现在,当我生成另一个需要相同库但版本不同的应用程序“bravo”时,即(libz.so.1.2.8),它在 中可用
/lib/x86_64-linux-gnu/libz.so.1.2.8
,系统会抛出以下错误。
version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)
如果我取消设置LD_LIBRARY_PATH
,“bravo”就会正常启动。我知道上述行为是因为在查找链接库时LD_LIBRARY_PATH
优先于定义的目录路径,因此发生了上述错误。/etc/ld.so.conf
我只是好奇为什么UNIX / LINUX的开发人员没有设计操作系统来根据层次结构搜索其他目录中的链接库,如果库的第一个实例是不同版本的。
简单地说,UNIX/LINUX 系统遍历一组目录,直到找到所需的库。但为什么它不做同样的事情,直到找到预期的版本,而不是接受库的第一个实例,无论其版本如何?
答案1
但为什么它不做同样的事情,直到找到预期的版本,而不是接受库的第一个实例,无论其版本如何?
据它所知,确实如此。zlib.so.1.2.7
两者zlib.so.1.2.8
都有一个 soname zlib.so.1
,所以你的alpha
和bravo
二进制文件说他们需要zlib.so.1
。动态加载器加载它找到的第一个匹配的库;它不知道1.2.8版本提供了bravo
需要的额外符号。 (这就是为什么发行版煞费苦心地指定额外的依赖信息,例如zlib1g (>= 1.2.8)
for bravo
。)
您可能认为这应该很容易修复,但事实并非如此,尤其是因为二进制文件和库将它们所需的符号与它们所需的库分开列出,因此加载程序无法检查给定库是否提供了所需的所有符号。都需要从中得到。符号可以通过多种方式提供,并且在符号和提供它们的库之间引入链接可能会破坏现有的二进制文件。符号插入也增加了乐趣,使事情变得复杂(并使安全敏感的开发人员抓狂)。
一些库提供版本信息,最终存储在 中.gnu.version_r
,并带有指向提供库的链接,这在这里会有所帮助,但libz
不是其中之一。
(考虑到 sonames,我希望你的alpha
二进制文件能够与 . 一起正常工作zlib.so.1.2.8
。)