RustのCargo.tomlの書き方と設定項目まとめ!プロジェクト管理とビルド設定を初心者向けに完全解説
生徒
「RustでプロジェクトをCargoで作ったんですが、Cargo.tomlというファイルが自動生成されました。これって何のファイルですか?」
先生
「Cargo.tomlは、Rustプロジェクトの設定ファイルです。プロジェクト名やバージョン、依存ライブラリなどを管理する、いわばプロジェクトの設計図のようなものですね。」
生徒
「TOMLって拡張子ですが、これはどういう形式なんですか?」
先生
「TOMLはTom's Obvious, Minimal Languageの略で、人間が読み書きしやすい設定ファイル形式です。JSONやYAMLと似ていますが、よりシンプルで理解しやすいのが特徴です。では、Cargo.tomlの書き方と設定項目を見ていきましょう!」
1. Cargo.tomlの基本構造とは
Rustのプロジェクト管理ツールであるCargoは、プロジェクトのルートディレクトリに配置されるCargo.tomlファイルを使って、プロジェクトのメタデータや依存関係、ビルド設定などを管理します。このファイルはTOML形式で記述され、セクションごとに異なる設定を記述できる構造になっています。
Cargoで新しいプロジェクトを作成すると、自動的に最小限のCargo.tomlが生成されますが、プロジェクトの成長に伴って様々な設定を追加していくことになります。ビルドオプション、依存ライブラリ、プロファイル設定など、Cargo.tomlで管理できる項目は非常に多岐にわたります。
2. packageセクション:プロジェクトの基本情報
[package]セクションには、プロジェクトの基本的なメタデータを記述します。プロジェクト名、バージョン、作成者、エディション、ライセンスなど、プロジェクトを識別するための重要な情報がここに含まれます。
特にeditionフィールドは重要で、使用するRustのエディション(2015、2018、2021など)を指定します。エディションによって利用できる機能や構文が異なるため、プロジェクトの要件に応じて適切なエディションを選択する必要があります。
[package]
name = "my_rust_project"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <you@example.com>"]
license = "MIT"
description = "Rustプロジェクトのサンプル説明文"
repository = "https://github.com/username/my_rust_project"
keywords = ["rust", "cargo", "example"]
categories = ["development-tools"]
| フィールド名 | 説明 | 必須 |
|---|---|---|
name |
プロジェクトの名前(パッケージ名) | ○ |
version |
プロジェクトのバージョン番号 | ○ |
edition |
使用するRustエディション | ○ |
authors |
作成者の情報 | |
license |
ライセンス種別 |
3. dependenciesセクション:外部ライブラリの管理
[dependencies]セクションは、プロジェクトが依存する外部クレート(ライブラリ)を指定する場所です。Rustのエコシステムでは、crates.ioという公式パッケージレジストリから膨大な数のライブラリを利用できます。
依存関係の指定方法はいくつかあり、バージョン番号を直接指定する方法、GitリポジトリのURLを指定する方法、ローカルパスを指定する方法などがあります。バージョン指定では、セマンティックバージョニングに基づいた柔軟な指定が可能です。
[dependencies]
serde = "1.0"
tokio = { version = "1.35", features = ["full"] }
regex = "1.10"
chrono = "0.4.31"
[dev-dependencies]
mockall = "0.12"
criterion = "0.5"
上記の例では、serdeは単純なバージョン指定、tokioは特定の機能を有効化したバージョン指定を行っています。また、[dev-dependencies]セクションには、テストやベンチマーク時にのみ使用する依存関係を記述します。これにより、本番ビルドには不要なライブラリを分離できます。
"1.0"と書くと、実際には"^1.0"と解釈され、1.0以上2.0未満の互換性のあるバージョンが使用されます。
4. profileセクション:ビルドプロファイルの設定
[profile]セクションでは、異なるビルドプロファイルごとに最適化レベルやデバッグ情報の有無などを設定できます。主なプロファイルには、開発用のdev、リリース用のrelease、テスト用のtest、ベンチマーク用のbenchがあります。
最適化レベルは0から3まであり、数字が大きいほど最適化が強力になります。開発時は高速なコンパイルを優先し、リリース時は実行速度を優先するという使い分けが一般的です。デバッグシンボルの有無も制御でき、バイナリサイズと開発効率のバランスを取ることができます。
[profile.dev]
opt-level = 0
debug = true
split-debuginfo = "unpacked"
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
strip = true
panic = "abort"
リリースビルドでは、LTO(リンク時最適化)を有効にすることで、さらなるパフォーマンス向上が期待できます。ただし、コンパイル時間は長くなるため、開発中は無効にしておくのが一般的です。stripオプションを有効にすると、デバッグシンボルが削除され、バイナリサイズが小さくなります。
5. featuresセクション:機能フラグの定義
[features]セクションでは、条件付きコンパイルのための機能フラグを定義できます。これにより、同じコードベースから異なる機能セットを持つバイナリをビルドすることが可能になります。例えば、デバッグ用の機能、実験的な機能、プラットフォーム固有の機能などを切り替えることができます。
機能フラグは依存関係と組み合わせることもでき、特定の機能が有効な場合にのみ特定のライブラリを含めるという柔軟な設定が可能です。これにより、ビルドサイズを最適化したり、不要な依存関係を排除したりできます。
[features]
default = ["json"]
json = ["serde_json"]
xml = ["quick-xml"]
full = ["json", "xml", "networking"]
networking = ["reqwest"]
[dependencies]
serde_json = { version = "1.0", optional = true }
quick-xml = { version = "0.31", optional = true }
reqwest = { version = "0.11", optional = true }
この例では、defaultフィーチャーでJSON機能を標準で有効にし、XMLやネットワーク機能はオプションとしています。ユーザーはcargo build --features "full"のようにコマンドラインから機能を指定できます。
6. workspaceセクション:マルチパッケージプロジェクト
大規模なプロジェクトでは、複数の関連するパッケージを一つのリポジトリで管理したい場合があります。[workspace]セクションを使用することで、複数のCargoパッケージを一つのワークスペースとして統合管理できます。
ワークスペースを使用すると、共通の依存関係を共有し、一度のコマンドで全てのパッケージをビルドできるようになります。また、ワークスペース全体で依存関係のバージョンを統一することで、互換性の問題を回避しやすくなります。
ワークスペースのルートCargo.toml例:
[workspace]
members = [
"frontend",
"backend",
"shared"
]
resolver = "2"
各メンバーパッケージは独自のCargo.tomlを持ち、個別にビルドや公開が可能です。ワークスペースのルートディレクトリでcargo buildを実行すると、全てのメンバーパッケージが一括でビルドされます。
7. targetセクション:ビルドターゲットの設定
[[bin]]、[[lib]]、[[example]]などのセクションでは、ビルドターゲットを明示的に指定できます。通常、Cargoはsrc/main.rsをバイナリとして、src/lib.rsをライブラリとして自動認識しますが、カスタムパスや追加のターゲットを定義する場合にこれらのセクションを使用します。
複数のバイナリを持つプロジェクトや、サンプルコード、ベンチマークを含むプロジェクトでは、これらのセクションで各ターゲットを明確に定義することで、ビルドプロセスを細かく制御できます。
[[bin]]
name = "app"
path = "src/main.rs"
[[bin]]
name = "cli-tool"
path = "src/bin/cli.rs"
[lib]
name = "mylib"
path = "src/lib.rs"
crate-type = ["cdylib", "rlib"]
8. build-dependenciesとビルドスクリプト
[build-dependencies]セクションは、ビルドスクリプト(build.rs)内でのみ使用される依存関係を指定します。ビルドスクリプトは、コンパイル前に実行される特別なRustプログラムで、コード生成、ネイティブライブラリのリンク、環境変数の設定などを行えます。
例えば、プロトコルバッファのコード生成、C/C++ライブラリとのバインディング生成、バージョン情報の埋め込みなど、ビルド時に動的な処理が必要な場合にビルドスクリプトを活用します。
ビルドスクリプトの活用例
- プロトコルバッファやgRPCの定義ファイルからRustコードを生成
- FFI(Foreign Function Interface)を使用する際のC/C++ライブラリのコンパイル
- 環境変数やビルド時情報をバイナリに埋め込む
- 条件付きコンパイルのための設定の検出
9. その他の重要な設定項目
Cargo.tomlには他にも多くの設定項目があります。[badges]セクションではREADMEに表示するバッジの設定、[patch]セクションでは依存関係の一時的な置き換え、[replace]セクションでは依存関係の強制的な置き換えが可能です。
rust-versionフィールドでは、プロジェクトが要求する最小のRustバージョンを指定できます。これにより、古いバージョンのRustでビルドを試みた際に、分かりやすいエラーメッセージを表示できます。また、publishフィールドをfalseに設定することで、誤ってcrates.ioに公開するのを防ぐこともできます。
readme- READMEファイルのパスhomepage- プロジェクトのホームページURLdocumentation- ドキュメントのURLexclude- パッケージから除外するファイル
rust-version- 必要な最小Rustバージョンpublish- crates.io公開の可否default-run- デフォルトで実行するバイナリautobins- バイナリの自動検出
10. 実践的なCargo.toml設定例
実際のプロジェクトでは、これまで説明した様々な設定を組み合わせて使用します。ここでは、Webアプリケーションを想定した実践的なCargo.tomlの例を示します。この設定には、非同期ランタイム、Webフレームワーク、データベース接続、シリアライゼーションなど、実用的なライブラリの依存関係が含まれています。
[package]
name = "web_application"
version = "1.0.0"
edition = "2021"
rust-version = "1.75"
authors = ["Developer <dev@example.com>"]
license = "MIT OR Apache-2.0"
description = "実践的なRust Webアプリケーション"
readme = "README.md"
homepage = "https://example.com"
repository = "https://github.com/user/web_application"
keywords = ["web", "api", "server"]
categories = ["web-programming::http-server"]
[dependencies]
tokio = { version = "1.35", features = ["full"] }
axum = "0.7"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sqlx = { version = "0.7", features = ["runtime-tokio", "postgres"] }
tracing = "0.1"
tracing-subscriber = "0.3"
dotenvy = "0.15"
[dev-dependencies]
tokio-test = "0.4"
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
[profile.dev]
opt-level = 0
[features]
default = []
database = ["sqlx"]
metrics = ["prometheus"]
この設定例では、非同期処理のためにtokio、Webフレームワークとしてaxum、データベース接続にsqlxを使用しています。開発環境とリリース環境で異なる最適化レベルを設定し、機能フラグでオプション機能を制御できるようにしています。