rustc-basics について
rustc と Cargo を扱うエージェント向けの Rust コンパイラ支援スキルです。ビルド設定やフラグ、コンパイラ出力の確認、単相化、バイナリサイズ、一般的なエラーの調査を解説します。
主な機能
- 01Cargo ビルドプロファイルの設定
- 02RUSTFLAGS によるコンパイラオプションの指定
- 03MIR とアセンブリの確認
- 04単相化の影響の把握
- 05バイナリサイズの削減
- 06一般的なコンパイルエラーの調査
活用シーン
- 01リリースビルドの速度やサイズの調整
- 02関数が生成するアセンブリの確認
- 03コンパイル低速化やバイナリ肥大化の調査
- 04Rust コンパイルエラーの診断
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill rustc-basicsインストール後、Claude Code で/rustc-basicsを入力して読み込まれたか確認します。
同梱ファイルreferences/rustflags-profiles.md
詳細
rustc の基本
目的
RUSTFLAGS、Cargo プロファイルの設定、ビルドモード、MIR とアセンブリの確認、単相化、および一般的なコンパイルエラーパターンを通じて、Rust コンパイラーの呼び出し方法をエージェントに案内します。
トリガー
- 「Rust で最高のパフォーマンスを得るために、リリースビルドを設定するにはどうすればよいですか?」
- 「Rust の関数のアセンブリ出力を見るにはどうすればよいですか?」
- 「単相化とは何ですか? また、なぜコンパイルが遅くなるのですか?」
- 「Rust で LTO を有効にするにはどうすればよいですか?」
- 「Rust のバイナリが大きすぎます。小さくするにはどうすればよいですか?」
- 「Rust の MIR 出力を読むにはどうすればよいですか?」
ワークフロー
1. ビルドモードを選択する
# Debug (default) — fast compile, no optimization, debug info
cargo build
# Release — optimized, no debug info by default
cargo build --release
# Check only (fastest, no codegen)
cargo check
# Build for specific target
cargo build --release --target aarch64-unknown-linux-gnu
2. Cargo.toml のプロファイル設定
[profile.release]
opt-level = 3 # 0-3, "s" (size), "z" (aggressive size)
debug = false # true = full, 1 = line tables only, 0 = none
lto = "thin" # false | "thin" | true (fat LTO)
codegen-units = 1 # 1 = max optimization, higher = faster compile
panic = "abort" # "unwind" (default) | "abort" (smaller binary)
strip = "symbols" # "none" | "debuginfo" | "symbols"
overflow-checks = false # default true in debug, false in release
[profile.release-with-debug]
inherits = "release"
debug = true # release build with debug symbols
strip = "none"
[profile.dev]
opt-level = 1 # Speed up debug builds slightly
| 設定 | 影響 |
|---|---|
lto = true (fat) | 最適化が最も優れますが、リンクが最も遅くなります |
lto = "thin" | 良好な最適化と並列リンクが得られます |
codegen-units = 1 | インライン化が最も優れますが、コンパイルが遅くなります |
panic = "abort" | アンワインドテーブルを削除し、バイナリを小さくします |
opt-level = "z" | サイズを積極的に削減します |
3. RUSTFLAGS
# Set for a single build
RUSTFLAGS="-C target-cpu=native" cargo build --release
# Enable all target CPU features
RUSTFLAGS="-C target-cpu=native -C target-feature=+avx2,+bmi2" cargo build --release
# Control codegen at invocation level
RUSTFLAGS="-C opt-level=3 -C codegen-units=1 -C lto=on" cargo build --release
.cargo/config.toml で永続化します:
[build]
rustflags = ["-C", "target-cpu=native"]
[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "target-cpu=native", "-C", "link-arg=-fuse-ld=lld"]
4. アセンブリ出力を確認する
# Using cargo-show-asm (recommended)
cargo install cargo-show-asm
cargo asm --release 'myapp::module::function_name'
# Using rustc directly
rustc --emit=asm -C opt-level=3 -C target-cpu=native src/lib.rs
cat lib.s
# View MIR (mid-level IR, before codegen)
rustc --emit=mir -C opt-level=3 src/lib.rs
cat lib.mir
# View LLVM IR
rustc --emit=llvm-ir -C opt-level=3 src/lib.rs
cat lib.ll
# Use Compiler Explorer (Godbolt) patterns locally
RUSTFLAGS="--emit=asm" cargo build --release
find target/ -name "*.s"
5. 単相化を理解する
Rust のジェネリクスは単相化されます。つまり、具体的な型のインスタンス化ごとに個別のコードが生成されます。これにより、次の問題が発生します。
- バイナリサイズの肥大化
- コンパイル時間の増加
- i-cache 圧迫の可能性
# Measure monomorphization bloat
cargo install cargo-llvm-lines
cargo llvm-lines --release | head -30
# Shows: lines of LLVM IR per function (monomorphized copies visible)
緩和策:
// 1. Type erasure with dyn Trait (trades monomorphization for dispatch)
fn process(iter: &mut dyn Iterator<Item = i32>) { ... }
// 2. Non-generic inner function pattern
fn my_generic<T: AsRef<str>>(s: T) {
fn inner(s: &str) { /* actual work */ }
inner(s.as_ref()) // monomorphization only in thin wrapper
}
6. バイナリサイズの削減
[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
panic = "abort"
strip = "symbols"
# Check binary size breakdown
cargo install cargo-bloat
cargo bloat --release --crates # per-crate size
cargo bloat --release -n 20 # top 20 largest functions
# Compress executable (at cost of startup time)
upx --best --lzma target/release/myapp
7. よくあるエラーの切り分け
| エラー | 原因 | 修正方法 |
|---|---|---|
cannot find function in this scope | use の不足、またはモジュールパスの誤り | use crate::module::fn_name を追加します |
the trait X is not implemented for Y | impl の不足、またはジェネリック境界の誤り | トレイトを実装するか、境界を調整します |
lifetime may not live long enough | 借用チェッカーのライフタイムに関する問題 | ライフタイム注釈を明示的に追加します |
cannot borrow as mutable because also borrowed as immutable | エイリアシング違反 | 借用が重複しないように再構成します |
use of moved value | クロージャーまたは関数に move した後の値を使用しています | .clone() を使うか、代わりに借用します |
mismatched types: expected &str found String | String と &str の混同 | .as_str() または &my_string を使います |
8. 便利な rustc フラグ
# Show all enabled features at a given opt level
rustc -C opt-level=3 --print cfg
# List available targets
rustc --print target-list
# Show target-specific features
rustc --print target-features --target x86_64-unknown-linux-gnu
# Explain an error code
rustc --explain E0382
RUSTFLAGS のリファレンスと Cargo プロファイルのパターンについては、references/rustflags-profiles.md を参照してください。
関連スキル
- ワークスペース管理と Cargo ツールについては、
skills/rust/cargo-workflowsを使用します - GDB/LLDB を使った Rust バイナリのデバッグについては、
skills/rust/rust-debuggingを使用します - プロファイリングとフレームグラフについては、
skills/rust/rust-profilingを使用します - メモリ安全性の検証については、
skills/rust/rust-sanitizers-miriを使用します
コメント
Markdown 対応