Linker-plugin-LTO
Linker-plugin-LTO
-C linker-plugin-lto 标签允许将 LTO (译者注:Linking Technology and Order)优化推迟到实际链接步骤中,如果要链接的所有目标文件(object files) 都是基于 LLVM 工具链优化的,则此标签又允许跨编程语言边界执行过程间优化,本文示例主要展示如何将 Rust 代码与使用 Clang 编译的 C/C++ 代码链接在一起。
用法
链接基于LTO的插件有两种主要的情况:
- 编译 Rust
staticlib用于 C ABI 的依赖项。 - 在
rustc调用链接器的地方编译 Rust 二进制文件。
在这两种情况下,Rust代码需要用 -C linker-plugin-lto 编译,并且 c/c++ 代码使用 -flto 或 -flto=thin 以便将目标文件生成 LLVM 位码。
Rust staticlib 作为 C/C++ 程序中的依赖项
在这种情况下,Rust 编译器只需要确保 staticlib 中的目标文件格式正确即可。
要想进行链接,必须使用带有 LLVM 插件的链接器 (例如 LLD)。
直接使用 rustc :
# 编译 Rust staticlib
rustc --crate-type=staticlib -Clinker-plugin-lto -Copt-level=2 ./lib.rs
# 用 `-flto=thin` 编译 C代码
clang -c -O2 -flto=thin -o main.o ./main.c
# 链接起来,得先确保我们使用的是合适的链接器。
clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
使用 cargo:
# 编译 Rust staticlib
RUSTFLAGS="-Clinker-plugin-lto" cargo build --release
# 用 `-flto=thin` 编译 C代码
clang -c -O2 -flto=thin -o main.o ./main.c
# 链接起来,得先确保我们使用的是合适的链接器。
clang -flto=thin -fuse-ld=lld -L . -l"name-of-your-rust-lib" -o main -O2 ./cmain.o
C/C++ 代码作为 Rust 中的依赖项
在这种情况下,将由 rustc 调用链接器。我们再次必须确保使用合适的链接器。
直接使用 rustc :
# 用 `-flto=thin` 编译 C代码
clang ./clib.c -flto=thin -c -o ./clib.o -O2
# 从 C代码中创建静态库
ar crus ./libxyz.a ./clib.o
# 使用其他参数一起调用 `rustc`
rustc -Clinker-plugin-lto -L. -Copt-level=2 -Clinker=clang -Clink-arg=-fuse-ld=lld ./main.rs
直接使用 cargo:
# 用 `-flto` 编译 C代码
clang ./clib.c -flto=thin -c -o ./clib.o -O2
# 从 C代码中创建静态库
ar crus ./libxyz.a ./clib.o
# 通过 RUSTFLAGS 设置链接参数
RUSTFLAGS="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" cargo build --release
明确指定 rustc 要使用的链接器插件
如果想要使用 LLD 以外的链接器,需要明确指定使用的 LLVM 链接器插件。否则链接器无法读取目标文件。插件的路径通过作为 -Clinker-plugin-lto 选项的参数传递:
rustc -Clinker-plugin-lto="/path/to/LLVMgold.so" -L. -Copt-level=2 ./main.rs
工具链的兼容性
为了使这种 LTO 生效,LLVM 链接器插件必须能够处理由 rustc 和 clang 产生的 LLVM 位码。
通过使用基于相同版本的 LLVM 的 rustc 和 clang 实现可获得最佳结果。可以使用 rustc -vV 来查看给定 rustc 版本所使用的 LLVM。注意因为Rust有时会使用 LLVM 的不稳定版本,所以此处所给出的版本号只是一个近似值,但是这种近似通常是可靠的。
下表展示了已知工具链的良好组合。
| Rust 版本 | Clang 版本 |
|---|---|
| Rust 1.34 | Clang 8 |
| Rust 1.35 | Clang 8 |
| Rust 1.36 | Clang 8 |
| Rust 1.37 | Clang 8 |
| Rust 1.38 | Clang 9 |
| Rust 1.39 | Clang 9 |
| Rust 1.40 | Clang 9 |
| Rust 1.41 | Clang 9 |
| Rust 1.42 | Clang 9 |
| Rust 1.43 | Clang 9 |
| Rust 1.44 | Clang 9 |
| Rust 1.45 | Clang 10 |
| Rust 1.46 | Clang 10 |
注意,此处的兼容性策略将来可能会更改。
-C linker-plugin-lto 标签允许延迟LTO优化到实际的链接步骤
文档原文: What is rustc? - The rustc book
GitHub:rust/src/doc/rustc at master · rust-lang/rust
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
rustc 手册
关于 LearnKu