我将首先回答您问题的第二部分,即为什么重命名 libre2.so.0 没有达到您的预期。
当您运行可执行文件时,传递给链接器的文件名是无关紧要的(除非您无法提供-soname
构建库时 - 请参阅下面的第二次编辑)。依赖关系取自所谓的“soname”。如果您运行readelf
在你的库上命令你可以确定它的soname,例如。
readelf -d libre2.so.0 | grep SONAME
即使您重命名该文件也没关系。上述命令的结果仍然会给你相同的soname,因此程序仍然无法找到“libre2.so.0”。
至于你问题的原始部分,这完全取决于图书馆是否有RPATH
or RUNPATH
内置于它们和/或您的内容LD_LIBRARY_PATH
环境变量是。这些是运行时链接器 (ld.so) 将用来查找共享库的内容。尝试
man ld.so
了解更多信息。
由于您自己构建了这些库,因此您会知道它们是否使用了-rpath
or -runpath
最后链接阶段的选项。或者,使用readelf
再次例如。
readelf -d libre2.so.0 | grep RPATH
readelf -d libre2.so.0 | grep RUNPATH
我怀疑上面两个命令不会返回任何内容。
我的猜测是你的当前目录在LD_LIBRARY_PATH
这将允许运行时链接器找到 lib/libjson_linux-gcc-4.4.6_libmt.so 但找不到 libre2.so.0。我注意到您回复了我对您的问题的评论,表示您的LD_LIBRARY_PATH
是空的。这很奇怪。
也许您以某种方式在 libjson 的 soname 上添加了前缀“lib/”?即做了readelf
SONAME 返回命令
lib/libjson_linux-gcc-4.4.6_libmt.so
而不仅仅是
libjson_linux-gcc-4.4.6_libmt.so
另外,通过运行检查程序在 soname 方面需要什么
readelf -d my_progam | grep NEEDED
也许“lib/”前缀在那里是因为你将它传递给 gcc 的方式。如果是这样,那么如果您使用 @enobayram 给出的 gcc 命令,那么它将平衡竞争环境,即它也将无法找到 libjson。
首先要确定的不是为什么not找到 libre2.so.0 但它是如何实现的is设法找到 libjson。如果您尝试从不同的目录运行可执行文件,它仍然有效还是现在对于 libjson 也失败了?或者,如果您将 libre2.so.0 复制到可执行文件旁边,这会改变什么吗?
Edit
A 在 Fedora 论坛上发帖建议 Fedora 版本的 ld.so 将当前目录作为内置搜索路径。虽然我无法验证这一点,但它可以解释为什么你要选择任何库,因为你的案例中不存在 ld.so 使用的所有其他东西。
Edit 2
从我系统上的 ld 手册页
-soname=名称
创建ELF共享对象时,设置内部DT_SONAME字段
到指定的名称。当可执行文件与共享文件链接时
具有 DT_SONAME 字段的对象,然后当可执行文件运行时
动态链接器将尝试加载指定的共享对象
DT_SONAME 字段而不是使用给定的文件名
链接器。
版权所有 (c) 1991、1992、1993、1994、1995、1996、1997、1998、1999、
2000、2001、2002、2003、2004、2005、2006、2007、2008、2009 免费
软件基金会公司
授予复制、分发和/或修改本文档的许可
根据 GNU 自由文档许可证 1.3 版的条款或
自由软件基金会发布的任何更高版本;没有
不变部分,没有封面文本,也没有封底
文本。许可证副本包含在标题为“GNU
免费文档许可证”。
所以,你评论中的理论是正确的。如果不-soname
在构建库时显式指定,则共享对象中不存在 SONAME,并且可执行文件中的 NEEDED 字段仅具有提供给链接器的文件名,在您的情况下,该文件名包含前导“lib/”。