为什么Rust可执行文件如此巨大?

刚刚find了Rust并阅读了文档的前两章,我发现他们定义语言的方法和方式特别有趣。 所以我决定让我的手指湿润,并开始与你好世界…

我在Windows 7 x64上这样做,顺便说一句。

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

发货cargo build ,看targets\debug的结果targets\debug我发现得到的.exe是3MB。 经过一些search(货物命令行标志的文档很难find…)我发现--release选项并创build了发布版本。 令我吃惊的是,.exe的大小只有很小的一点点变小了:2.99MB而不是3MB。

所以,承认我是Rust和它的生态系统的新手,我的期望是系统编程语言会产生一些紧凑的东西。

任何人都可以详细说明鲁斯特正在编译的内容,怎么可能从3class计划中产生如此巨大的图像呢? 它是编译到虚拟机? 有没有一个脱衣舞的命令我错过了(debugging发布版本内的信息?)? 还有什么可能让人明白是怎么回事?

Rust使用静态链接来编译它的程序,这意味着即使是最简单的Hello world!也需要所有的库Hello world! 程序将被编译到您的可执行文件中。 这还包括Rust运行时。

要强制Rustdynamic链接程序,请使用命令行参数-C prefer-dynamic ; 这将导致更小的文件大小, 也需要在运行时为您的程序提供Rust库(包括其运行时)。 这基本上意味着如果计算机没有它们,则需要提供它们,占用比原始静态链接程序占用的更多空间。

为了便于携带,我build议你如果要将程序分发给其他人,就要以你一直在做的方式静态链接Rust库和运行库。

我没有任何Windows系统可以尝试,但是在Linux上,一个静态编译的Rust hello world实际上比等效的C小。如果你看到一个巨大的尺寸差异,这可能是因为你连接了Rust可执行文件静态的和C的dynamic。

通过dynamic链接,您还需要考虑所有dynamic库的大小,而不仅仅是可执行文件。

所以,如果你想比较苹果和苹果,你需要确保两者都是dynamic的,或者都是静态的。 不同的编译器将有不同的默认值,所以你不能只依靠编译器的默认值来产生相同的结果。

如果你有兴趣,这里是我的结果:

 -rw-r  -  r-- 1 aij aij 63 Apr 5 14:26 printf.c
 -rwxr-xr-x 1 aij aij 6696 Apr 5 14:27 printf.dyn
 -rwxr-xr-x 1 aij aij 829344 Apr 5 14:27 printf.static
 -rw-r-r-- 1 aij aij 59 Apr 5 14:26 puts.c
 -rwxr-xr-x 1 aij aij 6696 Apr 5 14:27 puts.dyn
 -rwxr-xr-x 1 aij aij 829344 Apr 5 14:27 puts.static
 -rwxr-xr-x 1 aij aij 8712 Apr 5 14:28 rust.dyn
 -rw-r  -  r-- 1 aij aij 46 4月5日14:09 rust.rs
 -rwxr-xr-x 1 aij aij 661496 Apr 5 14:28 rust.static

这些编译与海湾合作委员会(Debian的4.9.2-10)4.9.2和rustc 1.0.0-晚上(d17d6e7f1 2015-04-02)(build于2015-04-03),默认选项和静态的海湾合作委员会和-C prefer-dynamic rustc -C prefer-dynamic

我有两个版本的C Hello World,因为我认为使用puts()可能会链接到更less的编译单元。

如果你想尝试在Windows上重现它,这里是我使用的来源:

printf.c:

 #include <stdio.h> int main() { printf("Hello, world!\n"); } 

puts.c:

 #include <stdio.h> int main() { puts("Hello, world!"); } 

rust.rs

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

另外请记住,不同数量的debugging信息或不同的优化级别也会有所不同。 但我期望如果你看到了巨大的差异,这是由于静态与dynamic链接。

使用Cargo进行编译时,可以使用dynamic链接:

 cargo rustc --release -- -C prefer-dynamic 

这将显着减小二进制文件的大小,因为它现在是dynamic链接的。

至less在Linux上,您也可以使用strip命令去除符号的二进制数:

 strip target/release/<binary> 

这大约会减less大部分二进制文件的大小。