4

我正在尝试编译一个示例 LLVM 程序。链接器步骤使用此命令。

llvm-config-3.2 --ldflags --libs

这将导致以下命令。

g++  -o bin/Debug/test-llvm obj/Debug/main.o   -L/usr/lib/llvm-3.2/lib  -lpthread -lffi -ldl -lm  (a boat load of LLVM libraries here)

但是,它无法链接。我收到这样的错误。

undefined reference to ffi_type_float

所以,我添加-lffi-ldl最后。

g++  -o bin/Debug/test-llvm obj/Debug/main.o   -L/usr/lib/llvm-3.2/lib  -lpthread -lffi -ldl -lm  (a boat load of LLVM libraries here) -lffi -ldl

所以,是的,他们在命令中出现了两次......但它是这样工作的。为什么?前面的论点中清楚地引用了它们。

4

3 回答 3

4

出现在命令行上的一个或多个库之后-lffi-ldl引用其中一个库中定义的符号。但是链接器已经完成扫描libffi并且libdl不会重新扫描它们以查找这些符号。这种循环依赖可以通过强制链接器通过在列表末尾重新列出它们的名称来再次扫描这些库来解决。

一个更具可扩展性的解决方案是使用--start-group archives --end-group选项列出要链接到的库。从手册页引用:

-( archives -)
--start-group archives --end-group 档案应该是档案文件的列表。它们可以是显式文件名,也可以是 -l 选项。

重复搜索指定的档案,直到没有创建新的未定义引用。通常,存档仅按照命令行中指定的顺序搜索一次。如果需要该存档中的符号来解析稍后出现在命令行上的存档中的对象所引用的未定义符号,则链接器将无法解析该引用。通过对档案进行分组,它们都被反复搜索,直到解决所有可能的参考。

使用此选项会带来很大的性能成本。最好仅在两个或多个档案之间存在不可避免的循环引用时才使用它。

所以你的命令行看起来像这样:

g++ -o bin/Debug/test-llvm obj/Debug/main.o -L/usr/lib/llvm-3.2/lib --start-group -lpthread -lffi -ldl -lm ... --end-group
于 2013-06-14T03:51:32.113 回答
2

啊,我找到了解决方案。交换标志实际上并没有改变顺序。我不得不把它分成两个单独的电话。

llvm-config-3.2 --libs
llvm-config-3.2 --ldflags

是的,这在另一个问题中在技术上得到了回答:为什么链接库的顺序有时会导致 GCC 中的错误?

我仍然认为这个问题是相关的,因为按照医生告诉我的去做会让我陷入危险之中。:(

于 2013-06-14T04:00:53.160 回答
1

为什么我必须链接这些库两次

因为命令行上存档库的顺序很重要,而您的顺序是错误的。

于 2013-06-14T03:52:06.797 回答