【问题标题】:Linking fails with gcc 4.8.2 / ld 2.24, succeeds with gcc 4.4.7 / ld 2.20gcc 4.8.2 / ld 2.24 链接失败,gcc 4.4.7 / ld 2.20 链接成功
【发布时间】:2014-12-03 18:08:47
【问题描述】:

在我正在使用的基于 CentOS 6.4 的 chroot 中,使用 ld 2.20 与 ncurses 链接成功,但与 ld 2.24 链接失败。我不直接调用链接器,gcc 正在处理它——gcc 4.4.7 正在使用 ld 2.20,而 gcc 4.8.2 正在使用 ld 2.24。

这是一个在我的特定环境中无法与 gcc 4.8.2 / ld 2.24 链接的最小示例。

#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    WINDOW* window = NULL;

    if (!(window = initscr())) {
        printf("Error initializing ncurses.");
        exit(1);
    }

    halfdelay(50);
    getch();
    endwin();
}

成功(ld 2.20):

$ gcc main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded" attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libncurses.so succeeded $

失败(ld 2.24):

$ /opt/gcc/4.8.2/bin/gcc48 main.c -lncurses -Wl,--verbose | grep "ncurses.*succeeded" attempt to open /usr/lib/../lib64/libncurses.so succeeded /opt/binutils/2.24/bin/ld24: /tmp/ccCxUFxl.o: undefined reference to symbol 'halfdelay' /lib64/libtinfo.so.5: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status $

请注意,这两个命令似乎都链接到同一个 libncurses.so。

对于它的价值,在基于 CentOS 5.4 的不同 chroot 中,有不同的 libncurses 版本,它与 ld 2.24 链接良好,但不幸的是,在该 chroot 中构建不是一种选择。 nm 实用程序显示这里的(静态)libncurses.a 确实具有所需的符号(nm 没有列出 libncurses.so 的符号——所以我只是假设它们是相似的)。

然而,在 CentOS 6.4 chroot 中,nm 显示我收到“未定义引用”消息的所有 ncurses 符号确实未定义或不存在于 Centos 6.4 chroot 的 libncurses.a 中,这令人困惑,因为与 gcc 4.4.7 链接有效。有点不对劲。

另外,我尝试使用 gcc 4.4.7 生成一个对象,然后与 gcc 4.8.2 链接,但这没有帮助。

我很困惑为什么一个编译器/链接器会成功而另一个会失败。这是 ABI 问题吗?有谁知道这里发生了什么?我可以将任何标志传递给 gcc 以使新的链接器工作吗?

【问题讨论】:

  • @FaroukJouti,那是错误的,所以没有理由尝试!库位于需要它们的文件之后。
  • 我尝试了与您尝试的完全相同的方法,并且在 gcc 4.8.2 中对我来说效果很好

标签: c linux gcc linker ld


【解决方案1】:

您的 libncurses 库本身链接到 libtinfo,这会导致您的旧工具链也在 libtinfo 中查找符号。

但较新的工具链通常使用--as-needed--no-copy-dt-needed-entries 运行链接器,后者可能会导致您看到的差异。

基本上,您还需要链接到 libtinfo,这是 halfdelay 函数所在的位置。

gcc main.c -lncurses -ltinfo

【讨论】:

  • 让我重申一下我的理解。如果仅将 --as-needed 标志传递给链接器,并且我的示例程序使用来自 libtinfo 的符号,而不是来自 libncurses,则 -lncurses 将与隐式 -ltinfo 一起被删除,因为不需要来自 libncurses 的符号.这将为 libtinfo 中的所需符号提供未定义的引用。但是,我的程序使用了 libtinfo 和 libncurses 中的符号,所以 --as-needed 并没有伤害到我。但是 --no-copy-dt-needed-entries 阻止了 -lncurses 引入 -ltinfo,并且由于我使用了 libtinfo 中的符号,所以我得到了未定义的引用。
  • 据推测,Farouk 能够链接的原因要么是因为他的工具链没有将这些标志传递给链接器,要么是因为他的 libncurses 版本包含所有必需的符号。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2014-11-26
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多