编译后的Rust可执行文件是否将从依赖项中排除未使用的代码?

时间:2018-08-28 11:45:43

标签: rust dependencies rust-cargo

如果我使用带有某些板条箱依赖项的Cargo构建Rust应用程序,这些依赖项中我的应用程序未使用的任何代码会从最终可执行文件中删除吗?

2 个答案:

答案 0 :(得分:9)

看起来像。我并排制作了一个测试库和垃圾箱:

// 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

我相信(但我不确定)是链接器删除了无效代码,因此它可能仍然已被编译,然后在链接期间被删除。

答案 1 :(得分:5)

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

这实际上是LLVM的工作,它将至少跟踪每个未使用的功能。 任何未使用的代码(例如未在整个应用程序中使用的功能的代码路径)可能需要激活LTO(链接时间优化),才能将板条箱变成一个编译单元,并为LLVM提供了一个战斗机会。 / p>