Cargoとは何か
RustにはCargoという強力なツールが標準で付属しています。Cargoは一言で言うとビルドツール兼パッケージマネージャーです。
他の言語でいえば、PHPのComposerやNode.jsのnpmに相当します。Cargoを使うことで以下のことができます。
- プロジェクトの作成・ビルド・実行
- 外部ライブラリ(クレート)の依存関係管理
- テストやドキュメントの生成
- crates.ioへのパッケージ公開
Rustをインストールするとrustup経由でCargoも自動的にインストールされるため、別途セットアップは不要です。
プロジェクトの作成と基本構造
新しいプロジェクトを作成するにはcargo newコマンドを使います。
# バイナリ(実行可能ファイル)プロジェクトを作成
cargo new hello_cargo
# ライブラリプロジェクトを作成
cargo new my_lib --lib
cargo new hello_cargoを実行すると、以下のようなディレクトリ構造が生成されます。
hello_cargo/
├── Cargo.toml
└── src/
└── main.rs
Cargo.tomlはプロジェクトの設定ファイルです。中身を見てみましょう。
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
[dependencies]
[package]:プロジェクト名・バージョン・使用するRustのエディションを定義します[dependencies]:外部クレートの依存関係をここに追記していきます
基本的なコマンド
ビルドと実行
# デバッグビルド(開発中に使う)
cargo build
# ビルドして即実行
cargo run
# リリースビルド(最適化あり・本番向け)
cargo build --release
cargo runはビルドと実行を一度に行ってくれるため、開発中は主にこちらを使います。リリースビルドは最適化が入るためコンパイルは遅くなりますが、実行速度が格段に上がります。
チェックとテスト
# コンパイルエラーがないか確認(バイナリを生成しないため高速)
cargo check
# テストを実行
cargo test
cargo checkはバイナリを生成せずにコードの検証だけを行うため、cargo buildよりも高速です。コードを書いている最中のエラー確認に重宝します。
依存関係の管理
外部クレートを追加するにはCargo.tomlの[dependencies]セクションに追記します。例として、シリアライズ・デシリアライズでよく使われるserdeを追加してみましょう。
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
追記後にcargo buildを実行すると、自動的にcrates.ioからダウンロードされます。
cargo build
# Downloading crates ...
# Compiling serde v1.0.x
# Compiling serde_json v1.0.x
# Compiling hello_cargo v0.1.0
cargo addコマンドを使うとコマンドラインから直接追加することも可能です。
cargo add serde --features derive
cargo add serde_json
Cargo.lockの役割
依存関係を解決した際にCargo.lockファイルが生成されます。このファイルには実際に使用したクレートの正確なバージョンが記録されます。
- バイナリプロジェクト:
Cargo.lockをGitにコミットする(再現性のある環境を保つため) - ライブラリプロジェクト:
Cargo.lockはGitignoreに追加するのが一般的
ワークスペースで複数クレートを管理する
大きなプロジェクトでは複数のクレートに分割することがあります。Cargoのワークスペース機能を使うと、これらをまとめて管理できます。
ルートのCargo.tomlに以下のように記述します。
[workspace]
members = [
"api_server",
"shared_lib",
"cli_tool",
]
ディレクトリ構成は以下のようになります。
my_workspace/
├── Cargo.toml # ワークスペース設定
├── Cargo.lock # 共有されるロックファイル
├── api_server/
│ ├── Cargo.toml
│ └── src/main.rs
├── shared_lib/
│ ├── Cargo.toml
│ └── src/lib.rs
└── cli_tool/
├── Cargo.toml
└── src/main.rs
ワークスペース内のクレートはCargo.lockを共有するため、依存関係の整合性が保たれます。また、ルートディレクトリでcargo buildを実行すると全クレートをまとめてビルドできます。
よく使うその他のコマンド
# コードのフォーマット(rustfmt)
cargo fmt
# 静的解析(Clippy)
cargo clippy
# ドキュメントを生成してブラウザで開く
cargo doc --open
# 使用していない依存関係を確認(cargo-udepsが必要)
cargo udeps
cargo clippyはRust公式の静的解析ツールで、バグの可能性があるコードや非慣用的な書き方を指摘してくれます。積極的に活用しましょう。
まとめ
Cargoは単なるビルドツールにとどまらず、Rustのエコシステム全体を支える中心的な存在です。本記事で紹介したコマンドをまとめます。
| コマンド | 内容 |
|---|---|
cargo new | 新しいプロジェクトを作成 |
cargo build | プロジェクトをビルド |
cargo run | ビルドして実行 |
cargo check | コードを高速検証 |
cargo test | テストを実行 |
cargo add | 依存クレートを追加 |
cargo fmt | コードをフォーマット |
cargo clippy | 静的解析を実行 |
cargo doc | ドキュメントを生成 |
まずはcargo newでプロジェクトを作り、cargo runでコードを動かすところから始めてみてください。Cargoの便利さを実感できるはずです。