linux 链接器/加载器搜索顺序
这个问题与编译和动态链接期间查找库的方式有关。
考虑这个小项目:
- 项目
- liba
- a.hpp
- a.cpp
- libb
- b.hpp
- b.cpp
- main.cpp
- liba
a.hpp:
int AAA();
a.cpp:
#include <b.hpp>
int AAA()
{
return BBB();
}
b.hpp:
int BBB();
b.cpp:
int BBB()
{
return 3;
}
main.cpp:
#include "liba/a.hpp"
#include "libb/b.hpp"
int main()
{
AAA();
BBB();
}
libb 编译为:
cd libb; g++ -shared -o libb.so b.cpp
liba 编译为:
cd liba; g++ -I../libb/ -L../libb/ -lb -shared -o liba.so -Wl,-rpath /full/path/to/project/libb/ a.cpp
和 main 编译为:
g++ -Lliba -la -Wl,-rpath /full/path/to/project/liba/main.cpp
编译完成,没有报错,但是执行a.out时,找不到libb.so。
ldd 输出:
ldd ./a.out
linux-gate.so.1 => (0xffffe000)
liba.so => /full/path/to/project/liba/liba.so (0xb780a000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb76ba000)
libm.so.6 => /lib/libm.so.6 (0xb7692000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7672000)
libc.so.6 => /lib/libc.so.6 (0xb750f000)
libb.so => not found
libb.so => /full/path/to/project/libb/libb.so (0xb750c000)
/lib/ld-linux.so.2 (0xb780e000)
请注意,libb.so 出现两次。有一次,动态链接器无法找到该库,有一次又找到了。我假设,在第二种情况下,它使用 liba.so 中嵌入的 rpath。
当然,有多种方法可以解决该问题(例如LD_LIBRARY_PATH,在编译main.cpp时嵌入正确的rpath...),但我更感兴趣的是为什么main.cpp的编译有效,而动态链接却不起作用't。
到目前为止,我假设使用相同的过程来搜索所需的库。我是否遗漏了什么,或者有什么我不知道的隐藏魔法? :)
(在带有 gcc 4.3.4 的 SLED11 盒子上测试。)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
没有隐藏的魔法,但你基本上已经向编译器承诺你将在运行时告诉加载器在哪里可以找到函数,但你没有。从 AAA 调用的 BBB 知道如何到达那里,但从 main 调用的 BBB 不知道。
There's no hidden magic but you've basically promised the compiler that you're going to tell the loader, at run-time, where to find the functions but you haven't. The BBB called from AAA knows how to get there but the BBB called from main does not.