Cargoでgitレポジトリ内にある一部crateを依存に追加する

はじめに

Cargo で crates.io に登録されていない crate を指定するには、git や path で指定できます。 git のレポジトリに複数の crate が存在する場合には、左辺に依存する crate 名を指定すると、レポジトリ内から該当 crate を依存関係に追加できます。

# atsamd レポジトリ内の wio-terminal crate を依存に追加
wio-terminal = { git = "https://github.com/jessebraham/atsamd.git", branch = "wio-terminal" }

経緯

最近、Wio Terminal x Rust で遊んでいたところ、 Wio Terminal で使用している SoC の HAL crate を開発している atsamd レポジトリに Wio Terminal の BSP を追加するプルリクが出されました。

github.com

fork 先を clone して examples あたりにコードを追加すれば試せるのですが、Cargo.toml で fork 先から追加された wio-terminal crate だけ引っ張ってきてアプリケーション書けないかな、と考えました。

ちなみに、atsamd レポジトリには、各 SoC の PAC (Peripheral Access Crate) や、atsamd-hal crate、各ボードの BSP crate が集められています。

$ tree -L 2
.
├── boards
│   ├── arduino_mkrvidor4000
│   ├── arduino_mkrzero
│   ├── arduino_nano33iot
# ...
│   ├── trellis_m4
│   ├── trinket_m0
│   ├── wio_terminal  # fork 先のこれだけ持ってきたい
│   └── xiao_m0
├── hal
│   ├── Cargo.toml
│   ├── README.md
│   └── src
# ...
├── pac
│   ├── atsamd11c
│   ├── atsamd21e
# ...
│   ├── atsamd51p
│   ├── atsame54p
│   └── README.md
# ...
└── update.sh

Cargo.toml

atsamd レポジトリ内の atsamd51p crate と wio-terminal crate を引っ張ってきたい場合、次のように書くと意図通り動きました。

[dependencies]
atsamd51p = { git = "https://github.com/jessebraham/atsamd.git", branch = "wio-terminal" }
wio-terminal = { git = "https://github.com/jessebraham/atsamd.git", branch = "wio-terminal" }
panic-halt = "0.2"

解説

解説、というか、The Cargo Book を見ると書いてありました。

doc.rust-lang.org

Cargo will fetch the git repository at this location then look for a Cargo.toml for the requested crate anywhere inside the git repository (not necessarily at the root - for example, specifying a member crate name of a workspace and setting git to the repository containing the workspace).

ということで、fetch してきたレポジトリ内から、指定した Cargo.toml を一生懸命探してくれるようです (root ディレクトリに置いてある必要がなく、メンバー crate も指定できる) 。