🦀

[Rust] ワークスペースで利用するクレートのバージョンの一元管理方法

2022/12/20に公開

TL;DR;

  • ワークスペース内の複数クレートが利用するクレートのバージョンを一元管理できます。
  • 各パッケージの Cargo.toml には、ワークスペースの Cargo.toml 内の記述を参照するように設定します。
  • この機能は Cargo 1.64 から利用できます。

ユースケース

Cargo にはワークスペースという機能があります。この機能を利用することで、プロジェクトを複数のパッケージに分割して開発できるようになります。
例えば、次のexample プロジェクトには addcli の 2 つのクレートが存在しています。

example
├── add
└── cli

この 2 つのクレートのの依存関係は次のようになっています。

パッケージ 依存するクレート
add anyhow, thiserror
cli anyhow, add

両方のクレートが anyhow に依存しています。次のように、それぞれの Cargo.toml にバージョンを書いても良いのですが、ワークスペースで一斉にクレートのバージョンを更新するといった作業がやりにくくなります。

[dependencies]
anyhow = "1.0.67"
thiserror = "1.0.38"

このような場合、複数クレートから利用されるクレートのバージョンなどが一元管理されていると便利です。

依存関係の継承

バージョンなどを一元管理する際の鍵となるのが「workspace.dependencies テーブル」と「依存関係の継承」です。workspace.dependencies にワークスペース全体が依存するクレートを記述し、ワークスペース内の各クレートがワークスペースの依存関係を継承することで、一元管理を実現します。

workspace.dependencies テーブル

ユースケースで利用した example ワークスペースの Cargo.toml は次のようになっています。

[workspace]
members = [
    "cli",
    "add"
]

ここに workspace.dependencies テーブルを追加することで、ワークススペース全体が依存するクレートを記述できます。今回は anyhow の 1.0.67 を追加します。

[workspace]
members = [
    "cli",
    "add"
]

[workspace.dependencies]
anyhow = "1.0.67"

依存関係の継承

add が依存するクレートは次のように Cargo.toml に記述されています。

[dependencies]
anyhow = "1.0.67"
thiserror = "1.0.38"

これを次のように変更することで、ワークスペースの依存関係を継承できます。

[dependencies]
anyhow = { workspace = true }
thiserror = "1.0.38"

結論

以上のように、workspace.dependencies の記述を継承することで、 ワークスペースの依存関係をクレートが参照できます。つまりワークスペースの Cargo.toml でバージョン番号を一元管理できます。

featuresoptional は各クレートごとに設定できます。

例えば上記の cli クレートでのみ anyhow の backtrace 機能を使いたい場合は、次のように cli クレートの Cargo.toml に記述します。

[dependencies]
anyhow = { workspace = true, features = ["backtrace"] }
add = { path = "../add" }

レファレンス

Discussion