4 分で読了 #rust #cargo-and-build
このページの目次

Cargo.toml 詳細解説

Cargo.toml は単なる「依存関係の列挙」ではありません。features は条件付きコンパイルとオプション機能を実現し、profile はデバッグ/リリース時の最適化レベルを制御し、build scripts はコンパイル前に任意のコード(バインディングの生成、C ライブラリのコンパイルなど)を実行します。各設定の正しい記述方法は、よくある失敗に対応するものです。

[dependencies]: バージョン指定

[dependencies]
serde = "1"                          # ^1.0.0: >=1.0.0, <2.0.0 (semver 互換)
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"                       # ^1.0.0

[dev-dependencies]
criterion = "0.5"                    # tests/benches のみで使用可能

[build-dependencies]
cc = "1"                             # build.rs のみで使用可能

[target.'cfg(target_os = "linux")'.dependencies]
x11 = "2"                            # Linux のみ

バージョンルール:Cargo は semver(セマンティックバージョニング)を使用します。"1.2.3" = 完全一致、"^1.2.3"(デフォルト)= >=1.2.3 かつ <2.0.0。Cargo.lock は正確なバージョンを固定します——ライブラリ crate では lockfile をコミットすべきではなく、バイナリ crate ではコミットすべきです。

[features]: 条件付きコンパイル

[features]
default = ["std", "tls"]
std = []
tls = ["tokio", "rustls"]            # tokio と rustls を有効化
json = ["serde", "serde_json"]
nightly = []

使用時:cargo build --no-default-features --features "json,nightly"。feature は加算的です——コードを追加することはできますが、削除することはできません。独立した 2 つの feature が互いに競合することはありません。

[profile]: コンパイル最適化

[profile.release]
opt-level = 3                        # 最大最適化 (0-3, s=size, z=size aggressively)
lto = "fat"                          # リンク時最適化 (LTO)
codegen-units = 1                    # 単一のコード生成ユニット → より多くのインライン化、コンパイル速度は低下
panic = "abort"                      # アンワインドしない (バイナリサイズが小さく、組み込みに適す)

[profile.dev]
opt-level = 0                        # 高速コンパイル、最適化なし
debug = true

release 設定のトレードオフ:opt-level=3 + lto=fat + codegen-units=1 = 最小かつ最速のバイナリですが、コンパイル時間が最も長くなります(10〜30 分かかることも)。日常の開発ではデフォルト(opt-level=3, thin lto, codegen-units=16)を使用し、CI では最高設定を使用します。

[workspace.dependencies]: バージョンの共有

# ルートの Cargo.toml:
[workspace.dependencies]
serde = "1"
tokio = "1"

[dependencies]
serde = { workspace = true }         # ワークスペースのバージョンを参照

この機能 (1.64+) は、「複数の crate で依存関係のバージョンが一致しない」という古典的な問題を解決します——serde のアップグレードは 1 か所だけ変更すれば済みます。

build.rs: コンパイル時スクリプト

// build.rs — Cargo がメインコードをコンパイルする**前に**実行:
fn main() {
    println!("cargo:rustc-link-lib=z");      // libz をリンク
    println!("cargo:rerun-if-changed=wrapper.h");  // ヘッダーが変更された場合のみ再実行
    cc::Build::new().file("src/c/wrapper.c").compile("wrapper");
}

build.rs は主に以下に使用されます:C/C++ 依存関係のコンパイル、システムライブラリの検出、コード生成(protobuf、OpenAPI)、環境変数の設定。出力は OUT_DIR 環境変数に含まれます——これは Cargo によって管理されるため、手動でクリーンアップする必要はありません。

参考

  • Cargo Book: doc.rust-lang.org/cargo
  • The Cargo Book: profiles, features, build scripts

Keywords: Cargo.toml, features, dependencies, profile, LTO, build.rs, workspace