【问题标题】:Generating Rust executable from LLVM bitcode从 LLVM 位码生成 Rust 可执行文件
【发布时间】:2016-05-24 14:16:33
【问题描述】:

如何生成用 Rust 编写并编译成 LLVM-IR 位码的应用程序的可执行文件?

如果我尝试使用 rustc 编译 .bc 文件,它会告诉我 stream did not contain valid UTF-8,我似乎无法确定 rustc 中是否有特定的选项。

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

【问题讨论】:

  • rustc 是 Rust 编译器,它不编译其他输入格式。如果您有位码,为什么不使用 LLVM 的 llc 或等效的?
  • 这是我最初的猜测,但我对 llc 不是很熟悉,只发现了这个:-filetype - 选择文件类型(并非所有目标都支持所有类型):=asm - 发出一个程序集 ('.s') 文件 =obj - 发出本机对象 ('.o') 文件 =null - 不发出任何内容,用于性能测试。它们都不是我想要的。

标签: rust llvm-ir bitcode


【解决方案1】:

从这个源代码开始:

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

您可以创建 LLVM 中间表示 (IR) 或 bitcode (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

另见:

【讨论】:

  • DYLD_LIBRARY_PATH=/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ 是什么?
  • @LeonardoMarques 当我将目标文件与标准库链接时,它使用了动态链接。由于 Rust 标准库不在我的默认库搜索路径中,我必须在程序执行时通知动态链接器在哪里可以找到它。您可以构建一个静态二进制文件(在 OS X 上这对我来说有点棘手,所以我跳过了它)或者如果标准库在搜索路径中,运行时链接器会知道在哪里找到它。
  • 不是 -lstd-2f39a9bd 应该具有 .dylib 扩展名吗?为什么构建静态二进制文件很棘手?
  • @LeonardoMarques 这就是-l 标志的工作方式。它在lib 前面加上.dylib(或.so,或任何适合该平台的内容)。
  • @LeonardoMarques "Apple does not support statically linked binaries on Mac OS X"。另见Creating static Mac OS X C build。 Stack Overflow 充实了很多这些细节。 :-)
【解决方案2】:

这并不明显,因为 LLVM 文档非常晦涩,但 clang 将编译 LLVM IR 文件(“.ll”)和位码文件(“.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

【讨论】:

    猜你喜欢
    • 2017-07-26
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 2013-01-05
    相关资源
    最近更新 更多