减小 rust 编译出的程序的文件大小
2019-07-22 00:07 rust
随着引入的依赖包越来越多, 编译生成的 rust 程序二进制文件越来越大, 要花更久的 时间把它推送到线上服务器.
通过使用以下手段, 可以显著减小生成的程序文件大小, 同时不破坏其完整性.
debug 模式
debug 模式生成的文件非常大, 里面包含了很全面的调试信息, 也没有经过优化.
使用 cargo build
生成的 debug 模式的文件大小如下:
$ du -h target/debug/server
118M target/debug/server
release 模式
cargo build --release
默认条件下编译生成的 release 模式的文件大小如下:
$ du -h target/release/server
8.6M target/release/server
Cargo.toml
同 c/c++ 编译器一样, rustc 支持链接优化, 通过牺牲编译时间, 可以生成更小的 二进制文件.
开启方式是在 Cargo.toml
中加入:
[profile.release]
lto = true
开启优化后, 编译生成的二进制对象大小是:
$ du -h target/release/server
5.3M target/release/server
strip
strip 命令用于清除二进制文件中的非关键信息.
可以通过 sudo apt install binutils
命令来安装 strip 命令.
$ du -h target/release/server
3.8M target/release/server
server.lto :
section size addr
.interp 28 736
.note.gnu.build-id 36 764
.note.ABI-tag 32 800
.gnu.hash 164 832
.dynsym 3408 1000
.dynstr 2082 4408
.gnu.version 284 6490
.gnu.version_r 304 6776
.rela.dyn 240984 7080
.rela.plt 312 248064
.init 23 249856
.plt 224 249888
.plt.got 96 250112
.text 2472700 250240
.fini 9 2722940
.rodata 705256 2723840
.eh_frame_hdr 25828 3429096
.eh_frame 185368 3454928
.gcc_except_table 71468 3640296
.tdata 754 3719904
.tbss 968 3720672
.init_array 8 3720672
.fini_array 8 3720680
.data.rel.ro 201248 3720688
.dynamic 576 3921936
.got 1448 3922512
.data 344 3923968
.bss 1264 3924352
.comment 50 0
.debug_aranges 1152 0
.debug_pubnames 73880 0
.debug_info 307758 0
.debug_abbrev 6013 0
.debug_line 167687 0
.debug_frame 4704 0
.debug_str 297022 0
.debug_loc 61321 0
.debug_macinfo 2 0
.debug_pubtypes 35615 0
.debug_ranges 184672 0
.debug_macro 10948 0
Total 5066048
$ size -A target/release/server
server :
section size addr
.interp 28 736
.note.gnu.build-id 36 764
.note.ABI-tag 32 800
.gnu.hash 164 832
.dynsym 3408 1000
.dynstr 2082 4408
.gnu.version 284 6490
.gnu.version_r 304 6776
.rela.dyn 240984 7080
.rela.plt 312 248064
.init 23 249856
.plt 224 249888
.plt.got 96 250112
.text 2472700 250240
.fini 9 2722940
.rodata 705256 2723840
.eh_frame_hdr 25828 3429096
.eh_frame 185368 3454928
.gcc_except_table 71468 3640296
.tdata 754 3719904
.tbss 968 3720672
.init_array 8 3720672
.fini_array 8 3720680
.data.rel.ro 201248 3720688
.dynamic 576 3921936
.got 1448 3922512
.data 344 3923968
.bss 1264 3924352
.comment 50 0
Total 3915274
对比可以发现, strip 后的文件中不再包含 debug 段.
upx
最后, 我们还可以使用 upx 这样的压缩工具.
可以通过 sudo apt install upx
命令来安装 upx 包.
$ upx target/release/server
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2018
UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018
File size Ratio Format Name
-------------------- ------ ----------- -----------
3922536 -> 1595496 40.68% linux/amd64 server
看得出, upx 对可执行文件的压缩率还是相当高的, 最终的文件只有 1.6M.
$ du -h target/release/server
1.6M target/release/server
我们再查看一下二进制文件中各个段的大小:
$ size -A server.upx
server.upx :
section size addr
Total 0
其它
别的可以尝试的方式还有:
- 不包含 unwind 信息
- 清理包依赖列表中存有的多个不同版本的同名包
参考
- https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections
- https://upx.github.io
- https://en.wikipedia.org/wiki/Strip_(Unix)