Rustが楽しくてAWS SAAの資格勉強が全然捗りません。かなしい(自業自得)

前回のブログで軽く触れた、プロジェクトでRustを動かす際に役立つrust-toolchainファイルについて勉強がてら紹介していこうと思います。

Rustのバージョン管理について

プロジェクトのバージョン管理はそれぞれの言語で違います。

(nodeであればnodenv、pythonであればpyenvなど…)

Rustの場合、使用するバージョンをプロジェクトごとに決める際は、rust-toolchain.tomlが役に立ちます。

Overrides - The rustup book

これにより、各プロジェクトごとにRustのバージョンを切り替える必要がなくなります。

使用するためにはrustupのバージョンを1.23.0以上にしてあげる必要があります。

rust-toolchain.tomlの形式は以下のとおりです。

[toolchain]
channel = "nightly-2023-08-03"
components = [ "rustfmt", "rustc-dev" ]
targets = [ "wasm32-unknown-unknown", "thumbv2-none-eabi" ]
profile = "minimal"

バージョンだけ指定するならchannelだけ指定してあげればいいです。

[toolchain]
channel = "nightly-2023-08-03"

これをCargoパッケージ配下に配置することで、バージョンの指定が可能になります。

もしインストールされていないバージョンが指定されていた場合、cargo buildなどを行うと以下のように自動でバージョンのインストールを行ってくれます。

以下はnightly-2023-08-03をインストールしていない状態でchannelにnightly-2023-08-03を指定し、cargo testを実行した際の出力です。

% cargo test 
info: syncing channel updates for 'nightly-2023-08-03-x86_64-unknown-linux-gnu'
info: latest update on 2023-08-03, rust version 1.73.0-nightly (8131b9774 2023-08-02)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
   Compiling helper v0.1.0 (/home/username/Project/study/rust-lib-and-bin-playground/helper)
    Finished test [unoptimized + debuginfo] target(s) in 0.72s
     Running unittests src/lib.rs (target/debug/deps/helper-bf168264d06a5721)

running 2 tests
test test::bench_add_two ... ok
test test::test_add ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests helper

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

きちんとインストールされますね!

Cargoパッケージ内にあるCargoパッケージごとでバージョンを管理する

親となるCargoパッケージのバージョンと、その配下の子に当たるCargoパッケージで違うバージョンを使うこともできます。(そんなことはあんまりしないだろうけど…)

以下のようなディレクトリ構成の場合で、トップディレクトリ配下のrust-toolchainではnightly-2023-08-03を、cargo_child_packageではnightly-2023-08-02を指定します。

.
├── Cargo.lock
├── Cargo.toml
├── cargo_child_package
│   ├── Cargo.toml
│   ├── rust-toolchain.toml
│   └── src
│       └── main.rs
├── rust-toolchain.toml
└── src
    └── main.rs

この場合、それぞれのディレクトリでrustc --versionを実行すると、どちらも異なるバージョンを選択していることが分かります。

# cargo_parent_packageでバージョンを表示
% rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/username/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-2023-08-02-x86_64-unknown-linux-gnu
nightly-2023-08-03-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu

active toolchain
----------------

# nightly-2023-08-03が選択されている
nightly-2023-08-03-x86_64-unknown-linux-gnu (overridden by '/home/username/Project/study/cargo_parent_package/rust-toolchain.toml')
rustc 1.73.0-nightly (8131b9774 2023-08-02)
# cargo_child_packageでバージョン表示
% rustup show   
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/username/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
nightly-2023-08-02-x86_64-unknown-linux-gnu
nightly-2023-08-03-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu

active toolchain
----------------

# nightly-2023-08-02が選択されている
nightly-2023-08-02-x86_64-unknown-linux-gnu (overridden by '/home/username/Project/study/cargo_parent_package/cargo_child_package/rust-toolchain.toml')
rustc 1.73.0-nightly (d12c6e947 2023-08-01)

とはいえ、同じパッケージ内にあるのに別のバージョンを選択するのは統一性がないので、普通はトップディレクトリに一つ置いておくだけで良いと思います。

2023-08-05 追記

このファイル、いちいち作るの面倒だな〜って思ってたんですが、まだ公式にはこのファイルを作成するコマンドはサポートされていないようです。

Command to create rust-toolchain.toml in the current directory · Issue #2868 · rust-lang/rustup · GitHub

残念。。。