Cargoは、複数のバイナリやライブラリを含む大規模なプロジェクトを構築するためにワークスペース機能を提供しています。これはMavenに似た概念ですが、より柔軟性に欠ける面もあります。
ワークスペースの基本構造
ワークスペースは主に以下の要素で構成されます:
- ルートとなる
Cargo.tomlファイル - 各メンバークレートのディレクトリ構成
ルート設定ファイルの記述
最新のワークスペース仕様については、公式ドキュメントを参照してください:Workspaces - The Cargo Book
重要なポイント:
- メンバー間で共通の
Cargo.lockを共有する - ビルド成果物を同じ出力ディレクトリに集約する
[workspace.package]によりメタデータを統一管理可能patch,replace,profile.*はルートでのみ定義可
仮想ワークスペース
ルート Cargo.toml に [package] セクションが存在しない場合、それは「仮想ワークスペース」となります。この形式ではすべてのメンバーがサブディレクトリとして配置され、Mavenスタイルのプロジェクト構成に近くなります。
メンバークレートの設定
各メンバークレートは個別の Cargo.toml を持ちますが、以下のようなワークスペースとの連携設定が必要です:
xxx.workspace = trueによるプロパティ共有[dependencies]内での依存関係のワークスペース共有
実装例
ここでは3つのクレートからなるワークスペースを作成します:
- wsmain (バイナリ)
- student (ライブラリ)
- teacher (ライブラリ)
ディレクトリ構成
wsexample/
├── Cargo.toml
├── student/
│ ├── Cargo.toml
│ └── src/lib.rs
├── teacher/
│ ├── Cargo.toml
│ └── src/lib.rs
└── wsmain/
├── Cargo.toml
└── src/main.rs
ルート設定 (./Cargo.toml)
[workspace]
members = ["student", "teacher", "wsmain"]
resolver = "2"
[workspace.package]
version = "0.1.0"
edition = "2021"
[workspace.dependencies]
rand = "0.9.0-beta.1"
バイナリクレート設定 (./wsmain/Cargo.toml)
[package]
name = "wsmain"
version.workspace = true
edition.workspace = true
[dependencies]
student = { path = "../student" }
teacher = { path = "../teacher" }
ライブラリクレート設定 (./student/Cargo.toml)
[package]
name = "student"
version.workspace = true
edition.workspace = true
[dependencies]
rand.workspace = true
アプリケーションコード
./wsmain/src/main.rs
use teacher::*;
use student::*;
fn main() {
let stu = StudentInfo {
name: String::from("田中"),
age: 20,
gender: String::from("女性"),
id: String::from("S12345")
};
display_student(&stu);
stu.study();
stu.rest();
let prof = TeacherInfo {
name: String::from("佐藤"),
age: 35,
gender: String::from("男性"),
role: String::from("主任"),
};
prof.instruct_student(&stu);
display_teacher(&prof);
}
実行方法
仮想ワークスペースでは以下のように実行可能です:
cargo run
# または明示的に指定
cargo run -p wsmain
補助ツール
手動でのワークスペース管理に代わる手段として、cargo-workspaces が利用できます。
インストールと基本コマンド
cargo install cargo-workspaces
使用可能なサブコマンド:
create: 新規ワークスペース作成list: メンバー一覧表示changed: 変更があったメンバーのみ表示exec: 各メンバーに対して任意のコマンド実行publish: 公開処理rename: 名前変更
利用シーン
- 多数の関連クレートを持つmonorepo管理
- 関連ライブラリ群の一括公開
- CI/CDパイプラインとの統合
- 依存関係の最適化とクリーンアップ