从LLVM位代码生成Rust可执行文件

11

我如何生成由Rust编写且已编译为LLVM-IR位代码的应用程序的可执行文件?

如果我尝试使用rustc编译 .bc 文件,它会告诉我 流不包含有效的UTF-8 ,我似乎找不到rustc中是否有特定的选项可以解决这个问题。

基本上,我想实现以下操作: program.rs -> program.bc -> program。 其中 program 是最终的可执行文件。我应该采取哪些步骤来实现这一点?


1
rustc 是 Rust 编译器,它不会编译其他输入格式。如果您有位码,为什么不使用 LLVM 的 llc 或等效工具呢? - Shepmaster
这是我的初步猜测,但我对llc不太熟悉,只找到了这个:-filetype - 选择文件类型(并非所有类型都适用于所有目标): =asm - 发出一个汇编('.s')文件 =obj - 发出本机对象('.o')文件 =null - 发出空的内容,用于性能测试。 然而,它们都不是我在找的。 - Leonardo Marques
2个回答

7

从这个源代码开始:

fn main() {
    println!("Hello, world!");
}

您可以创建LLVM中间表示(IR)或位码(BC):
# IR in hello.ll
rustc hello.rs --emit=llvm-ir
# BC in hello.bc
rustc hello.rs --emit=llvm-bc

这些文件可以被LLVM进一步处理,产生汇编代码或目标文件:

# Assembly in hello.s
llc hello.bc
# Object in hello.o
llc hello.bc --filetype=obj

接下来,您需要将文件链接以生成可执行文件。这需要链接到Rust标准库。路径取决于平台和版本:

cc -L/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ -lstd-f4a73f2c70e583e1 -o hello2 hello.o

您可以运行这个程序:

DYLD_LIBRARY_PATH=/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ ./hello2

这个答案提供了macOS特定的解决方案,但是一般概念可以扩展到Linux和Windows。在Linux上,实现会略有不同,在Windows上可能会大大不同。值得注意的是,我使用了DYLD_LIBRARY_PATH,因为我动态链接到了Rust标准库,而这个库不在我的常规库搜索路径中。
请注意,LLVM IR和BC文件没有最强的前向/后向兼容性保证。这意味着您需要使用与您正在使用的rustc版本兼容的llc版本。对于这个答案,我使用了由我的本地Rust开发构建生成的llc
% rustc --version --verbose
rustc 1.53.0 (53cb7b09b 2021-06-17)
binary: rustc
commit-hash: 53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b
commit-date: 2021-06-17
host: x86_64-apple-darwin
release: 1.53.0
LLVM version: 12.0.1

% llc --version
LLVM (http://llvm.org/):
  LLVM version 12.0.1-rust-dev
  Optimized build.
  Default target: x86_64-apple-darwin20.5.0
  Host CPU: skylake

还可以参考:


1
@LeonardoMarques 当我将目标文件与标准库链接时,它使用了动态链接。由于Rust标准库不在我的默认库搜索路径中,因此我必须在程序执行时告诉动态链接器在哪里找到它。你可以构建一个静态二进制文件(对我来说在OS X上有点棘手,所以我跳过了),或者如果标准库在搜索路径中,运行时链接器就会知道在哪里找到它。 - Shepmaster
-lstd-2f39a9bd 不应该有 .dylib 扩展名吗?为什么构建静态二进制文件很棘手? - Leonardo Marques
1
@LeonardoMarques 这就是 -l 标志的工作原理。它会在前面加上 lib 并添加 .dylib(或 .so,或适用于该平台的任何内容)。 - Shepmaster
1
@LeonardoMarques "苹果不支持在Mac OS X上静态链接二进制文件"。另请参阅创建静态Mac OS X C构建。Stack Overflow有很多这些细节。 :-) - Shepmaster
谢谢!我看到了这篇有用的帖子:https://dev59.com/5nDYa4cB1Zd3GeqPB5Ip - rambi
显示剩余4条评论

5

LLVM文档非常晦涩,所以并不明显,但是 clang 可以编译LLVM IR文件(“.ll”)和bitcode文件(“.bc”),并链接您的系统库。

在具有Rust 1.9的Linux上:

clang -dynamic-linker /usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d16b8f0e.so  hello.ll -o hello

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接