2

我编写了一个简单的玩具语言编译器前端,它使用llvm-sys(LLVM 的C 库的 Rust 绑定)生成 LLVM IR 。然后我通过创建一个LLVMTargetMachine基于机器的目标三元组然后调用生成一个目标文件LLVMTargetMachineEmitToFile,它成功生成了一个可执行文件。但是,运行可执行文件会生成zsh: exec format error: ./a.out.

我发现我必须ld -lSystem ./a.out在生成可执行文件后运行才能使其工作。我应该如何在代码中自动调用链接器?

目前在 macOS Catalina 上使用 LLVM 9.0。

4

1 回答 1

2

实际上,LLVMTargetMachineEmitToFile会生成一个仍然需要链接的目标文件- 链接到可执行文件或共享库中。

为此,您需要一个链接器,严格来说,它不是 LLVM 的一部分。LLVM 的集成链接器在 LLVM IR 上运行,而不是本地机器代码。

然而,就像有一个与 LLVM 相关的 C 编译器 Clang 一样,也有一个与 LLVM 相关的本地链接器,称为 LLD。AFAIK,它可以用作库,因此您可以为编译器注入集成链接。

值得注意的是,本机编译器遵循“管道”架构,其中编译器本身和链接器(有时也包括汇编器)完全相互分离。在这样的架构中,编译器可执行文件(如clangor g++)实际上是一个驱动程序,它调用其他程序(cc1真正的编译器和ld链接器)来生成最终的二进制文件。

于 2020-05-19T08:10:15.490 回答