LoginSignup
35
29

More than 5 years have passed since last update.

Rustのバイナリサイズを削減する

Posted at

前提条件

  • rustcバージョン rustc 1.19.0-nightly (e2eaef849 2017-06-11)
  • MacOSX 10.11.6
  • ターゲットプロジェクト mozilla/sccache#c92e0d6

試したコマンドとその結果

デバッグビルド

$ cargo build
26884180

リリースビルド

$ cargo build --release
6217224
4502360 (strip)

以降特に記載ない限りはリリースビルド前提で、2つの数値の上の数字はコマンド実行後のサイズ、下の数値はstripコマンド実施済みのサイズです。

リンク時シンボルテーブルを含めない

$ cargo rustc --release -- -C link-args=-Wl,-x
5713768
4502360 (strip)

リンク時デバッグ情報を含めない

$ cargo rustc --release -- -C link-args=-Wl,-S
5206568
4502360 (strip)

stripすると-C link-argsを付けても付けなくても同じ。

コンパイラサイズ最適化オプション -Os

$ cargo rustc --release -- -C opt-level=s
5774864
3928720 (strip)

コンパイラサイズ最適化オプション -Oz (-Osよりアグレッシブ)

$ cargo rustc --release -- -C opt-level=z
5845516
3794644 (strip)

LTO(Link Time Optimization)

$ cargo rustc --release -- -C lto
5782092
4372820 (strip)

私自身、LTOによる最適化をあまり理解できていない。
リンク時にコンパイル単位を越えた最適化ができるとのことだが、動作を変える可能性があり注意が必要。

コンパイラサイズ最適化オプション-OsとLTO

$ cargo rustc --release -- -C opt-level=s -C lto
5078180
3542092 (strip)

コンパイラサイズ最適化オプション-OzとLTO

$ cargo rustc --release -- -C opt-level=z -C lto
5134516
3391444 (strip)

panic戦略をpanic=abortにする (プロセスabortさせる)

$ cargo rustc --release -- -C panic=abort
5916312
4243312 (strip)

プロセスがOSレベルでAbortシグナル飛ばして死ぬ。あまり実用的ではないかもしれない。

もろもろ合わせ技

$ cargo rustc --release -- -C opt-level=z -C lto -C link-args=-Wl,-x,-S
3399300
3391444 (strip)

stripすると、-C link-argsをつけてもつけなくても同じ。

ダイナミックリンク

$ cargo rustc --release -- -C prefer-dynamic -C link-args=-Wl,-rpath,$RUST_RPATH
5512288
4119560 (strip)

RUST_RPATH$HOME/.rustup/toolchains/nightly-x86_64-apple-darwin/libを指定する

otoolで共有ライブラリを確認

$ otool -L target/release/sccache
target/release/sccache:
    @rpath/libstd-438eba4cd7d88a45.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 57337.60.3)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1259.11.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
    /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)

ダイナミックリンク+もろもろ指定

$ cargo rustc --release -- -C opt-level=z -C prefer-dynamic -C link-args=-Wl,-x,-S,-rpath,$RUST_RPATH
3549448
3411744 (strip)

libstd以外もリンクするようになるともっとサイズ削減の効果がでるかもしれない。

まとめ

cargo rustc --release -- -C opt-level=z -C lto -C link-args=-Wl,-x,-Sが一番サイズ削減できました。
upxを使うとさらに削減できると思います。

$ upx target/release/sccache
1229464 (strip+upx)

今回のケースでは5.9Mから1.2Mと約1/5程になりました。

おわりに

Linuxでも測定しようかと思っていましたが、力尽きました。

参考

35
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
29