-1

在 Linux 上,D 运行时库依赖于_end符号来确定 GC 根范围 ( man 3 end),这实际上与 Boehm GC 所做的非常相似。但是,在 libcurl 中链接时,链接器不再找到该符号:

$ cat test.c
#include <stdio.h>

extern char _end[];
int main() {
    printf("%p\n", &_end);
    return 0;
}

$ gcc test.c # works
$ gcc test.c -lcurl
/usr/bin/ld: /tmp/ccOPtbEv.o: undefined reference to symbol '_end'
/usr/bin/ld: note: '_end' is defined in DSO /usr/lib/libssl.so.1.0.0 so try adding it to the linker command line
/usr/lib/libssl.so.1.0.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status

从 D 论坛上快速搜索,libpq、libdw 和其他几个库似乎触发了同样的问题。知道这里会发生什么吗?test.c甚至不依赖于 libcurl 中的符号。(Arch Linux x86_64、GCC 4.7.2、ld 2.23)

另外,请注意“尝试在 libssl 中链接”不是我正在寻找的答案,我想了解这里发生了什么。我正在尝试在我正在研究的编译器中解决此问题,因此您可以假设基本熟悉链接过程的工作原理。

编辑:我对告诉用户只在 libssl 中链接,...,明确表示不是特别满意的原因是pkg-config --libs curl,curl-config --libs等不包含此信息;因此,要求它会破坏构建系统。如果有人对确定数据(初始化和 BSS)段的边界有更好的想法,我很想知道。

编辑2:使用上面提到的工具链,end(没有下划线)似乎也被定义了,它不会触发问题。不过,仍然对它发生的原因感到困惑。

4

2 回答 2

0

_end 符号由链接器提供。它指向 bss 中的最后一个对象。但是,这只是一个约定,没有标准要求这样做。显然,您的工具链的链接器没有这样做。

于 2014-03-10T16:00:18.483 回答
0

请注意,“尝试在 libssl 中链接”不是我要寻找的答案。

但很可能它实际上您正在寻找的答案。你的命令行全错了。试试这个:

gcc test.c -lcurl

库和源的顺序,命令行上的对象很重要。

于 2012-11-11T06:50:26.207 回答