はじめに
Rustのビルドシステムでは、Rustの世界ではスタティックリンク、OSの標準ライブラリとはダイナミックリンクが基本になっている。これは、Rustの標準ライブラリぐらいはダイナミックリンクにして、バイナリをスリム化するための備忘録である。
環境
- macOS Sierra 10.12.6 (16G2011)
- rustc 1.36.0-nightly (e305df184 2019-04-24)
- Apple LLVM version 9.0.0 (clang-900.0.39.2)
ダイナミックリンクを指定する方法
rustc のコード生成時のオプションとして -C prefer-dynamic を指定すればよい。cargo を使う場合、rustc のフラグを指定する方法には以下の3つがあるようだが、それぞれ、ちょっとしたデメリットがある。
-
cargo rustcのコマンドラインで指定-
cargo buildではないサブコマンドを使わないといけない - いちいち指定するのが面倒
- これでビルドしても、
cargo runすると、通常のcargo buildが走ってしまう
-
-
.cargo/configのrustflagsに記述- ビルドするターゲットごとに指定することはできなさそう
- "Cargo.toml" と同様の TOML フォーマットで記述すればよいのだが、
"をエスケープすることができないので、指定にちょっとコツがいる
- 環境変数
RUSTFLAGSで指定- いちいち指定するのが面倒(だが、これが一番お手軽な気がする)
ちなみに、ダイナミックリンクされているライブラリが何かを知るためには、otool -L バイナリファイル名 とすればよい。
例 1. cargo rustc のコマンドラインで指定
# ビルド
$ cargo rustc -- -C prefer-dynamic
# 起動(Rust標準ライブラリのパスを環境変数で設定)
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge
# もしくは
$ DYLD_LIBRARY_PATH=~/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib ./target/debug/hogehoge
# 起動(rustup経由)
$ rustup run stable ./target/debug/hogehoge
# もしくは
$ rustup run nightly ./target/debug/hogehoge
例 2. .cargo/config の rustflags に記述
# config 設定
$ mkdir .cargo
$ cat <<EOF >.cargo/config
[build]
rustflags = ["-C", "prefer-dynamic"]
EOF
# ビルド
$ cargo build
# 起動
$ cargo run
例 3. 環境変数 RUSTFLAGS で指定
# 環境変数の設定
$ export RUSTFLAGS="-C prefer-dynamic"
# ビルド
$ cargo build
# 起動
$ cargo run
結果
結果は以下の通り(Swift については、2019/8/14 追記)。
| unstripped | stripped | |
|---|---|---|
| Rust (-C opt-level=3) | 276,272 bytes | 178,856 bytes |
| Rust (-C opt-level=3 -C prefer-dynamic) | 9,048 bytes | 8,656 bytes |
| C (-Oz) | 8,432 bytes | 8,440 bytes |
| Swift (-Osize) | 8,960 bytes | 8,824 bytes |
比較のためのプログラムは以下の通り。
hello/src/main.rs
fn main() {
println!("Hello, world!");
}
hello/c/hello.c
# include <stdio.h>
int main() {
printf("Hello, world!\n");
}
hello/swift/hello.swift
print("Hello, world!")
なかなかいい線いっているという感じか。次はスタティックリンクに挑戦。
参考
様々な最適化フラグの比較については、下記が参考になる。