在 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
(没有下划线)似乎也被定义了,它不会触发问题。不过,仍然对它发生的原因感到困惑。