はじめに
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!")
なかなかいい線いっているという感じか。次はスタティックリンクに挑戦。
参考
様々な最適化フラグの比較については、下記が参考になる。