【问题标题】:Does a compiled Rust executable exclude unused code from dependencies?编译后的 Rust 可执行文件是否会从依赖项中排除未使用的代码?
【发布时间】:2019-02-03 00:57:40
【问题描述】:

如果我使用带有一些 crate 依赖项的 Cargo 构建 Rust 应用程序,我的应用程序未使用的那些依赖项中的任何代码是否会从最终的可执行文件中删除?

【问题讨论】:

  • 我认为是的,但我不确定。
  • 我可能会检查 objdump 或类似的东西,但我想看看是否有明确的答案,或者是否计划在未来发布。 hello-world 类型可执行文件的大小存在相关问题。
  • 肯定有 LTO,否则我不确定。

标签: rust dependencies rust-cargo


【解决方案1】:

看起来像。我并排制作了一个测试库和 bin crate:

// hellobin/src/main.rs

extern crate hellolib;

fn main() {
    hellolib::func1();
}

对于库:

// hellolib/src/main.rs

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

pub fn func2() {
    println!("Hello, other world!");
}

构建我的二进制文件,然后使用 nm 检查符号:

$ nm target/debug/helloworld | grep hello
0000000100001360 t __ZN10helloworld4main17h749f61fb726f0a10E
00000001000014b0 T __ZN8hellolib5func117hec0b5301559d46f6E

只有使用的函数在最终的二进制文件中有符号。

您可以使用cargo rustc -- -C link-dead-code 进行编译,您会看到两个符号都存在,包括未使用的符号:

$ nm target/debug/helloworld | grep hello
0000000100001270 t __ZN10helloworld4main17h3104b73b00fdd798E
00000001000013d0 T __ZN8hellolib5func117hec0b5301559d46f6E
0000000100001420 T __ZN8hellolib5func217hc9d0886874057b84E

我相信(但我不确定)是链接器删除了死代码,所以它可能仍然被编译,然后在链接过程中被删除。

【讨论】:

  • 很好 :) 我会接受这个作为答案,除非有人从 rust docs/project 中找到明确的答案。
【解决方案2】:

TL;DR:是的,所有未使用的功能都将被排除在外。

这实际上是 LLVM 的工作,它至少会跟踪每个未使用的函数。 任何未使用的代码(如未在整个应用程序中采用的函数中的代码路径)可能需要激活 LTO(链接时间优化)才能将您的 crate 变成一个编译单元并给 LLVM 一个战斗机会。

【讨论】:

  • 我编辑了答案以澄清tl;dr yes 尤其是指未使用的功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 2016-02-28
  • 1970-01-01
  • 2014-07-03
相关资源
最近更新 更多