起きた問題
Rustで開発していたところ、Cargo.tomlで指定していたバージョンと異なるバージョンで依存先クレートがコンパイルされていた。
例えば
[package]
name = "tmp"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8.0"
と記述していても、実際はrand 0.8.5でコンパイルされている (2024/08/28時点でのrand 0.8最新バージョン)
実際にCargo.lockの記述を見てみると、下記のようになっている。
Cargo.lock
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
versionのフィールドを見てみると、"0.8.0"と指定したはずが、"0.8.5"となっている。
詳細と解決方法
詳細
dependenciesに記述するversionフィールドは特定のバージョンを指定するものではなく、プログラムが正常に動作するためのバージョンの範囲を指定するもの。なので、"0.8.0"と指定していたとしても、実際は"^0.8.0"となっており、0.8.0かそれ以上の互換性のある最新のバージョンを参照する。
解決方法
Cargo.toml
[dependencies]
rand = "0.8.0"
となっているところを、
Cargo.toml
[dependencies]
rand = "=0.8.0"
とすると、正しくバージョン0.8.0を参照するようになる。
実際にCargo.lockでもバージョン0.8.0でコンパイルされたことが示されている。
Cargo.lock
[[package]]
name = "rand"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76330fb486679b4ace3670f117bbc9e16204005c4bde9c4bd372f45bed34f12"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
細かいこと
このバージョン指定はセマンティックバージョニングというマニュアルに沿っていて、実際にCargoで行われるバージョン管理はこのマニュアルに準拠している。
セマンティックバージョニングのドキュメント(日本語)