Cargoでblakeのバージョン競合が起きた時の解決方法

Solanaプログラム開発でCargoがblakeクレートのバージョン競合を起こした場合、まずCargo.lockを更新し、依存関係を明示的に指定して解決するのが最短だ。競合の相手を特定できれば、数分で解消できる。

なぜCargoでblakeのバージョン競合が起きるのか

なぜCargoでblakeのバージョン競合が起きるのか

blakeとは、ブロックチェーンでよく使われるハッシュ関数の実装をまとめたRustクレート群だ。SolanaのSDKやAnchorフレームワークは、トランザクションの署名検証やデータの整合性確認にblake系クレートを内部で利用している。

競合が起きる典型的な原因は、プロジェクト内の複数のクレートが、互換性のない異なるバージョンのblakeを要求することだ。たとえば、あるクレートがblake3 1.0を要求し、別のクレートがblake3 1.5を要求した場合、Cargoは両方を同時に解決できずエラーを返す。

これはCargoのバグではなく、依存解決の仕組みとして正しい動作だ。Semantic Versioning(セマンティックバージョニング)のルール上、メジャーバージョンが異なるクレートは互換性がないとみなされる。要は、プロジェクト内で「同じ名前のクレートの複数バージョンを同時に使いたい」という矛盾した要求が生まれているということだ。

競合している相手を特定する手順

競合している相手を特定する手順

まず、どのクレートがどのバージョンのblakeを要求しているのかを正確に把握する。闇雲に依存関係を書き換えても、別の競合を引き起こすだけだ。

最初に実行すべきは、依存関係ツリーの表示だ。ターミナルで以下を実行する。

cargo tree -i blake3

このコマンドは、blake3に依存しているすべてのクレートと、その要求バージョンを逆引きで表示してくれる。blake2bで競合しているなら cargo tree -i blake2b_simd のように、実際に競合しているクレート名に置き換えること。

出力を見れば、競合の相手がSolana SDKなのか、Anchorなのか、あるいは別のライブラリなのかが判明する。競合相手が特定できたら、解決策を選べる状態になる。

Cargo.lockを更新して解決する手順

Cargo.lockを更新して解決する手順

最も簡単で効果的なのは、ロックファイルの再生成だ。Cargo.lockが古いバージョンのblakeを固定しているケースでは、更新するだけで解決することが多い。

次のコマンドを順番に実行する。

  1. cargo update -p blake3 でblake3単体を更新する
  2. それでも解決しない場合は cargo update で全依存関係を更新する
  3. 最後に cargo build でビルドが通るか確認する

競合の内容によっては、blake3を最新版に更新するだけでは解決しない。相手のクレートが古いバージョンを要求し続けるためだ。その場合は次に進む。

Cargo.tomlで依存関係を明示的に固定する

Cargo.tomlで依存関係を明示的に固定する

ロックファイルの更新で解決しない場合、Cargo.tomlにblakeのバージョンを明示的に指定する。これにより、Cargoがどのバージョンで解決すべきかの判断材料が増える。

競合の相手が「blake3 1.0系を要求するクレート」と「blake3 1.5系を要求する別のクレート」だと仮定する。この場合、自分のCargo.tomlに以下のように記述して、両方が受け入れられるバージョン帯を指示する。

[dependencies]
blake3 = "1.5"

バージョン指定は "1.5" のようにメジャーとマイナーまで書くのが安全だ。単に "1" と書くと、Cargoが利用可能な最新の1系を選ぶ。執筆時点ではblake3 1系が広く使われているが、最新の安定版はcrates.ioで確認してほしい。

blake2系で競合している場合は、blake2b_simdやblake2のクレート名で同様に指定する。Solana SDKはblake3への依存が中心なので、まずblake3を疑うのが現実的だ。

それでも解決しない時の対処法

それでも解決しない時の対処法

ここまでの手順で解決しない場合、原因は依存関係の深い位置にある。競合相手のクレート自体が古いblakeを要求し続けており、自分のCargo.tomlからは制御できない状態だ。

この場合、競合相手のクレートをアップデートすることで解決する。Anchorを使っているならAnchorのバージョンを最新にする。Solana SDKならsolana-programのバージョンを上げる。どちらもCargo.tomlの該当行を書き換えて cargo update を実行すればよい。

どうしても解消できない場合は、GitHubの該当リポジトリのissueを確認する。blake系のバージョン競合は一過性の問題であることが多く、既知のissueとして解決策が載っているケースがある。

再発を防ぐための依存関係管理

再発を防ぐための依存関係管理

一度解決しても、依存関係の更新を繰り返すうちに再発する可能性はある。再発を防ぐには、Cargo.lockをリポジトリにコミットしておくのが基本だ。

Solanaプログラムのようなバイナリプロジェクトでは、Cargo.lockのコミットが推奨される。ロックファイルを共有することで、開発者全員が同じバージョンの依存関係を使い、環境による差異を防げる。

加えて、依存関係を更新する際は cargo update を一括で実行せず、関連するクレートを個別に更新する習慣をつける。更新後にビルドが通るかを確認すれば、競合が起きた原因を特定しやすくなる。

よくある質問

Cargo.lockを削除して再生成してもよいのか

最終手段としては有効だが、最初に試すべきではない。Cargo.lockを削除すると全依存関係が最新版に更新され、別の競合を引き起こす可能性がある。まず cargo update -p で対象を絞って更新するのが安全だ。

blake2とblake3は互換性があるのか

ない。blake2とblake3は別のアルゴリズムで、クレートも別物だ。どちらを使うかは依存元のクレートが決めるため、勝手に置き換えると署名検証やハッシュ値が一致しなくなる。競合しているクレート名を正確に特定してから対処する必要がある。

Anchorを使っている場合に特に注意することはあるか

Anchorはバージョンによって依存するblake3のバージョンが異なる。Anchorをアップデートする際は、リリースノートで依存関係の変更を確認してから行うと、競合の発生を未然に防げる。また、AnchorとSolana SDKの両方を同時に最新にすると、互換性の問題が起きにくい。

エラーメッセージに「failed to select a version for the requirement」と出る

このエラーは、Cargoが依存関係を解決できなかったことを示す。blake以外のクレートでも同じエラーが出る。解決の手順は共通で、cargo tree -i クレート名 で競合相手を特定し、バージョンを明示指定するのが基本だ。

この記事のポイント

  • blakeの競合は複数クレートが異なるバージョンを要求するのが原因
  • まず cargo tree -i blake3 で競合相手を特定する
  • cargo update -p blake3 で対象を絞って更新する
  • 解決しない場合はCargo.tomlでblake3のバージョンを明示指定する
  • Cargo.lockはコミットして再発を防ぐ
共有:

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)