Linux:为啥加载器会找到我的共享库?

Posted

技术标签:

【中文标题】Linux:为啥加载器会找到我的共享库?【英文标题】:Linux: Why loader finds my shared library?Linux:为什么加载器会找到我的共享库? 【发布时间】:2015-12-18 10:11:11 【问题描述】:

我已经用 CMake 编译了一个共享库作为子项目,然后主应用程序链接到该库。库和应用程序位于我的主目录下的同一输出目录中。

因为我使用的是 Linux,所以我现在不明白为什么加载程序会看到我的库。

当我使用 ldd 检查库时,一切正常。但是,我的印象是我必须设置 LD_LIBRARY_PATH 以便我的应用程序可以从同一目录加载共享库。但我还没有设置它,它仍然有效。为什么?

【问题讨论】:

可能 CMake 设置了 makefile 来为链接器添加一个选项来告诉它共享库在哪里。搜索ld 选项--rpath 是.so 使用-L-l 链接的吗?另一种方法是使用 .so 的完整路径和名称直接链接。如果 CMAKE 使用其完整路径和名称链接 .so,则在加载时没有搜索。它只是使用相同的完整路径和名称。 @JSF 不,它似乎使用 -Wl,-rpath。 【参考方案1】:

也许您的构建过程正在您的可执行文件中设置RPATH 以在同一目录中查找库。要对此进行测试,请尝试将可执行文件移动到其他目录,然后查看是否可以运行它(或 ldd 它)。

您还可以通过以下任一方式检查可执行文件中的RPATH

readelf -d the-exe | grep RPATH
objdump -x the-exe | grep RPATH

有关更多信息,请参阅此处:https://unix.stackexchange.com/questions/22926/where-do-executables-look-for-shared-objects-at-runtime

【讨论】:

或运行readelf -d ./thebinary |grep RPATH。 automake/autoconf 通常会自动嵌入 RPATH,因此您可以轻松地从项目文件夹中运行已编译的应用程序,并重新链接它以在 make install 期间排除 RPATH(如果 DESTDIR 位于不需要 RPATH 的常见位置)我怀疑 CMake 有类似的自动智能。 @nos:谢谢,我添加了您的readelf 想法以及objdump 替代方案。

以上是关于Linux:为啥加载器会找到我的共享库?的主要内容,如果未能解决你的问题,请参考以下文章

linux管理共享库

C++在Linux平台运行时加载共享库并提取类实现

Linux 共享库被加载两次

Linux,共享库使用主程序中的函数而不是其他共享库

如何将共享库链接到Linux中的其他共享库?

Linux之静态库共享库