🦉
Cargo のワークスペースの構造がやっと理解できた
はじめに
これは本家のドキュメントで躓いた理解力の乏しい人向けの記事です。
本家では add で adder と add-one を作る例になっていたため私はまず名前で混乱しました。その上、常識的に考えて add が人に説明するときのワークスペース名なわけがないだろうと勝手な先入観を持ってしまいました。そこでドキュメントには書いてないけどあらかじめワークスペースとなるその親ディレクトリを cargo new
で用意しとかないといけないのかな? と、ディレクトリ構造を深くしてしまったり、add 自体を cargo new
で作ったりと無駄な試行錯誤を重ねてしまいました。
わかったことを一言で言えば、
- 共通の何もない親に子のディレクトリ名を列挙した Cargo.toml を置く
たったそれだけのことでした。
なんなら本家のドキュメントその一行でよかったぐらいです。
確認用スクリプト
少し長いかもしれないけどこの内容と実行結果を見るだけで確実に理解できるでしょう。
#!/bin/sh
rm -fr /tmp/my_workspace1
mkdir -p /tmp/my_workspace1
cd /tmp/my_workspace1
cargo new --bin my_project1
cargo new --bin my_project2
(cd my_project1 && cargo build)
(cd my_project2 && cargo build)
exa -T -F -I "deps|incremental|debug|*.d|*.TAG"
(cd my_project1 && cargo clean)
(cd my_project2 && cargo clean)
cat <<'EOF' > Cargo.toml
[workspace]
members = [
"my_project1",
"my_project2",
]
EOF
cargo build
exa -T -F -I "deps|incremental|debug|*.d|*.TAG"
実行結果
./
├── my_project1/
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── src/
│ │ └── main.rs
│ └── target/
└── my_project2/
├── Cargo.lock
├── Cargo.toml
├── src/
│ └── main.rs
└── target/
./
├── Cargo.lock
├── Cargo.toml
├── my_project1/
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
├── my_project2/
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
└── target/
一つ目は単に my_project1 と my_project2 が別々にあるだけです。二つ目は親に Cargo.toml と target ディレクトリがあるのがわかります。
まとめ・わかったこと
- cargo のサブコマンドとして workspace があるわけではない
- ググると
cargo workspace
という表記があったりするがなんも関係ない
- ググると
- 共通のワークスペースディレクトリ(親)を
cargo new
で作るべからず - 親は空でよい
-
cargo new
で作った子のディレクトリがあるだけという意味
-
- 子のディレクトリ名を列挙した Cargo.toml を新規で親に置く
- 親の Cargo.toml は子を作ったあとで置く
- 先に作ってしまうと
cargo new --bin my_project1
をするとき、親の Cargo.toml を読み込んで、あとから作成する予定の my_project2 がないと騷ぎ立てて面倒なことになる
- 親で
cargo build
すると子がビルドされる - ビルド結果は親の target/ に生成される
- いろいろ集約されることで依存関係がいい感じになったりビルド時間が短縮できる
- 親から
cargo test
すると子のテストを順に実行してくれる - とはいえ親から
cargo run
としても子を順番に実行したりはしない- 何を実行したらいいのかわからないと言われる
- 親から
cargo run -p my_project1
とすると実行するものを指定できる- my_project1 のなかで
cargo run
するのと同じなので別に親から実行しなくてもよい
- my_project1 のなかで
参照
Discussion