在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
(没有下划线),并且它不会触发问题。尽管如此,仍然感到困惑的原因。
答案 0 :(得分:0)
请注意»尝试在libssl中链接«不是我要找的答案。
但很可能实际上 是您正在寻找的答案。您的命令行全部错误。试试这个:
gcc test.c -lcurl
库和源的顺序,命令行上的对象很重要。
答案 1 :(得分:0)
_end符号由链接器提供。它指向bss中的最后一个对象。但是,这只是一个惯例,没有标准要求这样。显然,你的工具链的链接器不会这样做。