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

The*_*Saw 4 c++ linker llvm

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

llvm-config-3.2 --ldflags --libs
Run Code Online (Sandbox Code Playgroud)

这会产生以下命令。

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)
Run Code Online (Sandbox Code Playgroud)

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

undefined reference to ffi_type_float
Run Code Online (Sandbox Code Playgroud)

所以,我在最后添加了-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
Run Code Online (Sandbox Code Playgroud)

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

Pra*_*ian 5

一个或多个库出现在命令行上,-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
Run Code Online (Sandbox Code Playgroud)