【问题标题】:Differences in linking behavior between Ubuntu and CentOSUbuntu 和 CentOS 之间链接行为的差异
【发布时间】:2019-07-22 07:23:14
【问题描述】:

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

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

在 Ubuntu 上,B 对 A 的依赖是使用它的 rpath 解决的,而在 CentOS 上,链接器警告 A 找不到,我应该在编译可执行文件。

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

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,这似乎可行。当然我不知道它们将被部署到哪里的绝对路径,所以这并不能解决这个问题,但它表明 CentOS 7(或其加载器)不支持 $ORIGIN

【问题讨论】:

  • 如果在最后一个命令中添加-la 会发生什么?或者只是testdir/liba.so
  • 它会工作,如果我设置LD_LIBRARY_PATH。如果在 CentOS(或其他基于 RedHat 的发行版)上可以使用 rpath 提示依赖项的运行时位置,那么我强烈希望这样做,因为这意味着库的用户不需要列出所有依赖项已作为库的一部分列出。
  • 您也可以在最后一个链接中使用 -rpath 和 ORIGIN。
  • 您使用的是哪个版本的 CentOS 和 Ubuntu?
  • @florian: 会不会是this bug?这被标记为已在 bunutils 2.28 中修复,我认为这是在您系统上的版本之间。

标签: c ubuntu linker centos


【解决方案1】:

我认为这里的问题可能是this bug,针对 binutils 2.26 进行了报告,但可能也存在于早期版本中。问题是链接器ld,不像动态加载器ld.so,没有解释rpath中的特殊替换字符串$ORIGIN,所以只能使用绝对路径。

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

【讨论】:

    猜你喜欢
    • 2021-06-09
    • 1970-01-01
    • 2012-12-07
    • 2014-07-25
    • 2020-03-14
    • 2011-11-04
    • 2017-10-09
    • 2011-01-04
    • 1970-01-01
    相关资源
    最近更新 更多