首页 > 解决方案 > Ubuntu 和 CentOS 之间链接行为的差异

问题描述

我正在构建两个共享库,一个库 (B) 依赖于另一个 (A) 并且都使用rpathof构建$ORIGIN/.,然后将可执行文件链接到库 B。因此依赖关系如下:

可执行 C -> 库 B -> 库 A

在 Ubuntu 上,B 对 A 的依赖是使用它的 解决的rpath,而在 CentOS 上,链接器警告说找不到 A,我应该在编译可执行文件期间使用“尝试使用-rpath或”。-rpath-link

这是重现该问题的最小示例:

mkdir testdir
echo 'void a() {}' > testdir/a.c
echo 'int a(); void b() { a(); }' > testdir/b.c
echo 'int b(); int main() { b(); }' > testdir/c.c
gcc testdir/a.c -shared -o testdir/liba.so -Wl,-rpath,'$ORIGIN/.' -fPIC
gcc testdir/b.c -Ltestdir -la -shared -o testdir/libb.so -Wl,-rpath,'$ORIGIN/.' -fPIC
gcc testdir/c.c -Ltestdir -lb -o testdir/a.out

导致此问题的 Ubuntu 和 CentOS 上的链接行为有什么区别?有没有办法可以“解决”这个问题,这样 A 就可以得到解决,而不必依赖诸如LD_LIBRARY_PATH?


更新:如果我使用库目录的绝对路径而不是$ORIGIN,这似乎可行。当然我不知道它们将被部署到哪里的绝对路径,所以这并不能解决这个问题,但它表明$ORIGINCentOS 7(或其加载程序)不支持。

标签: cubuntulinkercentos

解决方案


我认为这里的问题可能是这个错误,针对 binutils 2.26 报告,但可能也存在于早期版本中。问题是链接器ld与动态加载器不同ld.so,它没有解释$ORIGINrpath 中的特殊替换字符串,因此只能使用绝对路径。

该错误在 binutils 2.28 中被标记为已修复,但 Centos 7 具有 binutils 2.27。另一方面,Ubuntu 18.4 使用 binutils 2.30。


推荐阅读