分类

减小 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 信息
  • 清理包依赖列表中存有的多个不同版本的同名包

参考