ここではワークスペースの構築方法を紹介している。

基礎知識

大きなプログラムは小さなパッケージに分割して作るのが推奨される。

ワークスペースはそれらのパッケージを管理するディレクトリである。

ワークスペースの作成

cargo.toml とその設定項目

ワークスペースディレクトリの直下には cargo.toml ファイルを置かなければならない。このファイルでは、ワークスペース全体のための設定、そして後述するルートパッケージがあればその設定、について記載する。

ワークスペース全体のための設定 (抜粋)

workspace.members
配下のクレートの一覧
workspace.dependencies
配下のクレートから共有される依存関係
workspace.resolver
互換性のための項目

ルートパッケージのための設定 (抜粋)

package
通常パッケージのそれと同じ
dependencies
通常パッケージのそれと同じ

補足: リゾルババージョン

workspace.resolver にはリゾルババージョンを指定する。これは package.edition の指定がある場合は自動で導出されるが、そうでない場合は明示的な指定が推奨されている。

ルートパッケージがある場合

ワークスペースの主役になるパッケージがある場合、それをルートパッケージにすると良い。例えば、アプリの主要な実行ファイルを生成するパッケージや、ライブラリ群のコアになる必須ライブラリを生成するパッケージは、ルートパッケージとして適切だろう。

ディレクトリ構成

ルートパッケージのアイテム、他パッケージのディレクトリ、これらが並んで配置される。

以下では、srctests はルートパッケージ用で、sub は同名のパッケージ用である。

my_app/
├─ cargo.toml
├─ src/...
├─ tests/...
└─ sub/...

cargo.toml ファイル

ワークスペース用の項目の他、ルートパッケージ用の項目を指定する。

以下では、ルートパッケージと sub を配下のパッケージとして指定している。

my_app/cargo.toml

[package]
name = "my_app"
edition = "2021"
version = "0.1.0"

[dependencies]
sub = { path = "sub" }
log = { workspace = true } 
rand = "0.8"

[workspace]
members = ["sub"]

[workspace.dependencies]
log = "0.4"

ルートパッケージがない場合

適切なルートパッケージがない場合について。

ディレクトリ構成

各パッケージのためのディレクトリはどれも並んで配置される。

以下では、appsub はそれぞれ同名のパッケージ用である。

my_app/
├─ cargo.toml
├─ app/...
└─ sub/...

cargo.toml ファイル

ワークスペースのための項目のみを指定する。

以下では、appsub を配下のパッケージとして指定している。

my_app/cargo.toml

[workspace]
members = ["app", "sub"]
resolver = "2"

[workspace.dependencies]
log = "0.4"

配下のクレートの作成

バイナリクレートの場合

まずは、ルートディレクトリにてコマンド cargo new をバイナリモードで実行する。

例えば、前述の例で導入したパッケージ app を作成する場合、以下のようにする。


> cargo new app --bin

続いて、生成されたディレクトリ内のファイルを雛形にコードを作成する。

例えば、以下ではワークスペース側から依存関係を流用したコードになっている。

my_app/app/cargo.toml

[package]
name = "app"
edition = "2021"
version = "0.1.0"

[dependencies]
sub = { path = "../sub" }
log = { workspace = true } 
rand = "0.8"
my_app/app/main.rs

use sub::*;

fn main() {

	/* Do etc... */

	println!("{}", hello());
}

ライブラリクレートの場合

まずは、ルートディレクトリにてコマンド cargo new をライブラリモードで実行する。

例えば、前述の例で導入したパッケージ sub を作成する場合、以下のようにする。


> cargo new sub --lib

続いて、生成されたディレクトリ内のファイルを雛形にコードを作成する。

例えば、以下ではワークスペース側から依存関係を流用したコードになっている。

my_app/sub/cargo.toml

[package]
name = "sub"
edition = "2021"
version = "0.1.0"

[dependencies]
log = { workspace = true } 
rand = "0.8"
my_app/sub/lib.rs

pub fn hello() -> String {

	/* Do etc... */

	"hello".to_string()
}