---
title: ワークスペースとプロジェクト管理
url: https://doc.liz6.com/ja/rust/09-cargo-and-build/03-workspace-and-project-management
locale: ja
area: rust
tags:
- rust
- cargo-and-build
date: 2026-06-30
modified: 2026-07-16
description: プロジェクトに複数の相互依存するクレート（コアライブラリ＋APIサーバー＋CLIなど）が含まれている場合、ワークスペースはそれらに同じ Cargo.lock と target ディレクトリを共有させます。これにより、コンパイルキャッシュの再利用や依存バージョンの統一が可能になります。patch を使用すると、開発中に特定の依存のソースコードを一時的に置き換えることができ、build.rs はコンパイル前にコード生成を実行します。
---

# ワークスペースとプロジェクト管理

> プロジェクトに複数の相互依存するクレート（コアライブラリ＋APIサーバー＋CLIなど）が含まれている場合、ワークスペースはそれらに同じ Cargo.lock と target ディレクトリを共有させます。これにより、コンパイルキャッシュの再利用や依存バージョンの統一が可能になります。patch を使用すると、開発中に特定の依存のソースコードを一時的に置き換えることができ、build.rs はコンパイル前にコード生成を実行します。

## ワークスペース: 1つのリポジトリで複数のクレート

プロジェクトに複数の相互依存するクレート（コアライブラリ＋APIサーバー＋CLIなど）が含まれている場合、1つのワークスペースに配置することには以下の3つの利点があります。

```toml
[workspace]
members = ["crates/core", "crates/api", "crates/cli"]
resolver = "2"
```

1. **ビルド成果物の共有**: すべてのメンバーが `target/` ディレクトリを共有するため、依存関係は1回だけコンパイルされ、ディスク容量とコンパイル時間が大幅に削減されます。
2. **バージョンの一貫性**: `Cargo.lock` はワークスペースレベルで共有されるため、すべてのメンバーが同じバージョンの依存関係を確認できます。
3. **内部からの相互参照**: `api` は `path = "../../crates/core"` を使用して `core` を直接参照できます（crates.io への公開は不要です）。

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

1.64以降では、ルート `Cargo.toml` でバージョンを宣言し、メンバーがキーで参照できるようになりました。

```toml
[workspace.dependencies]
serde = "1"
tokio = { version = "1", features = ["full"] }

# 各メンバー: [dependencies] → serde = { workspace = true }
```

これにより、複数のクレートを含むプロジェクトにおける「依存バージョンが各所に散在しており、アップグレード時に特定の箇所を見逃してしまう」という古典的な問題を解決します。バージョンを1箇所変更するだけで、すべてのメンバーが更新されます。

## [patch]: 依存の一時的な置き換え

アップストリームのクレートにバグがあり、アップストリームが修正するまでフォーク版を使用したい場合：

```toml
[patch.crates-io]
serde = { git = "https://github.com/myfork/serde", branch = "fix" }
```

注意：`[patch]` 内のバージョンはワークスペース全体で互換性がある必要があります。メンバーの1つが `serde 1.0` を、もう1つが `serde 1.3` を依存している場合、フォークは両方のAPIを満たす必要があります。そのため、フォークでは内部ロジックのみを変更し、公開APIを変更しないことが推奨されます。

## build.rs の高度な活用

```rust
// build.rs — メインコードのコンパイル前に実行される
fn main() {
    // 再実行条件: これらの条件が変化した時のみ再実行
    println!("cargo:rerun-if-changed=src/c/wrapper.h");
    println!("cargo:rerun-if-env-changed=MY_LIB_PATH");

    // システムライブラリのリンク
    println!("cargo:rustc-link-search=native={}", my_lib_dir);
    println!("cargo:rustc-link-lib=static=my_lib");

    // メインコードに cfg を渡す — #[cfg(has_avx2)] を有効にする
    println!("cargo:rustc-cfg=has_avx2");
}
```

build.rs は主に、C/C++ の依存関係のコンパイル（`cc` クレート経由）、システムライブラリの存在確認、コード生成（protobuf, OpenAPI）、feature フラグの設定に使用されます。

## 参考

- **Cargo Book**: ワークスペース、ビルドスクリプト
- **cc crate**: docs.rs/cc

*Keywords: ワークスペース, メンバー, patch, build.rs, 共有依存関係, マルチクレート, Cargo.lock*
