コンテンツにスキップ

Rustのエラー E0463: can't find crate(クレートが見つからない)

E0463 は、コンパイラがクレート(ライブラリ)を丸ごと探しに行ったのに、見つからずに手ぶらで帰ってきた、という意味のエラーです。たいていは、Cargo.toml に書かれていないクレートを extern crate の行で使おうとしています。ときには、見つからないクレートが std そのものということもあります。これは別の種類のマシン向けにビルドしようとして、そのターゲットをまだインストールしていないときに起こります。どちらもすぐに直せますし、リンカーのしくみを理解していなくても大丈夫です。このシリーズのほかのエラーは、Rustのコンパイルエラー解説を見てください。

error[E0463]: can't find crate for `rand`
--> src/main.rs:1:1
|
1 | extern crate rand;
| ^^^^^^^^^^^^^^^^^^ can't find crate

「can’t find crate for rand」は「rand のクレートが見つからない」という意味です。

このエラーが出るのは、cargo new で作ったばかりで [dependencies] に何も書いていないプロジェクトの、次のプログラムです。

extern crate rand;
fn main() {
let roll = rand::random_range(1..=6);
println!("You rolled {roll}");
}

よく見るもう1つの形には、行番号がまったくありません。std を求めているのはあなたのコードのどこか1行ではなく、どのプログラムも std を必要とするからです。

error[E0463]: can't find crate for `std`
|
= note: the `aarch64-unknown-linux-gnu` target may not be installed
= help: consider downloading the target with `rustup target add aarch64-unknown-linux-gnu`

note は「aarch64-unknown-linux-gnu ターゲットがインストールされていないかもしれない」、help は「rustup target add でターゲットをダウンロードしてはどうか」という意味です。これは、自分のマシン用のターゲットしか入っていない状態で cargo build --target aarch64-unknown-linux-gnu(Raspberry Pi のような64ビット ARM の Linux 向け)を実行すると出ます。どの直し方が必要かは、クレートの名前と note: で決まります。

表示される内容 よくある原因 直し方
extern crate の行で can't find crate for `rand` そのクレートが Cargo.toml にない 直し方1
同じエラーが、#[macro_use] のある古いコードで出る 2018 エディションより前に書かれたコード 直し方2
can't find crate for `std` と target may not be installed rustup がまだダウンロードしていないターゲット向けのビルド 直し方3
E0463 の近くに crate name using dashes are not valid コードの中のクレート名に - がある 直し方4

extern crate rand; は、コンパイラに「rand という名前のコンパイル済みライブラリを、このプログラムにリンクして」と伝える行です。コンパイラは何もダウンロードしませんし、インターネットを探しに行くこともありません。見るのは Cargo が渡してくれたライブラリだけで、Cargo が渡すのは Cargo.toml に書かれたクレートだけです。そこに rand がなければ、リストにも rand のライブラリはないので、E0463 になります。

std の場合も、1段下で同じことが起きています。標準ライブラリもコンパイル済みのライブラリで、rustup はターゲットごとに1つずつインストールします。ふだんのツールチェーンには、自分のコンピュータ用のものしか入っていません。ARM 向けのビルドを頼むと、コンパイラは ARM 用の std を探しますが、それが入っていないのです。

「戸棚の小麦粉を使う」と書かれたレシピのようなものです。だれも小麦粉を買っていなければ、レシピがどんなによくても料理は始められません。

Rust には、Python の pip install やシステム全体の node_modules のような、みんなで共有する「インストール済みライブラリのフォルダ」がありません。プロジェクトごとに、使うものをバージョンつきで Cargo.toml に正確に書き、Cargo がそのプロジェクトのためにクレートをビルドします。だから、同じプロジェクトが自分のノートパソコンでも、同僚のマシンでも、CI でも同じようにビルドされます。書かれていないクレートは、あなたのコードからは存在しないのと同じです。

extern crate は、ほとんど Rust 2015 の名残です。2018 エディションからは、Cargo.toml にあるクレートはすべて自動で使えるようになったので、今のコードでは use rand::random_range; と書くだけです。それでも古いチュートリアルや Stack Overflow の回答では今も extern crate を見かけますし、E0463 のほとんどはそこから来ています。今のコードで依存が足りないと、use の行なら E0432、コード中のパスなら E0433 が代わりに出ます。原因は同じで、エラーコードが違うだけです。

依存クレートのしくみはCargoとクレートを、ツールチェーンとターゲットについてはRustのツールを見てください。

直し方1:cargo add でクレートを追加する

Section titled “直し方1:cargo add でクレートを追加する”

足りないクレートが rand、regex、serde_json のような crates.io のクレートなら、これを選びましょう。いちばんよくあるケースです。Cargo.toml があるフォルダで、次のコマンドを実行します。

Terminal window
cargo add rand

Cargo が最新のバージョンを書き足してくれます。

[dependencies]
rand = "0.10.3"

これだけで E0463 は直ります。ついでに extern crate rand; の行も消しておきましょう。2018 以降のエディションでは必要ありません(Cargo.toml の edition = を確認してください)。次のプログラムは、出た目の代わりにチェックの結果を表示するので、いつも同じ結果になります。

fn main() {
let roll = rand::random_range(1..=6);
println!("出た目は1から6のどれか: {}", (1..=6).contains(&roll));
}

実行結果:

出た目は1から6のどれか: true
▶ 実際に試してみよう

古いコードは、バージョンが変わって名前の変わった関数を呼んでいることもあります。cargo add で E0463 は直ったのに、thread_rng のようなもので E0425 や E0432 が出るときは、使っているバージョンのクレートのドキュメントを確認しましょう。詳しくはcargo add で依存クレートを追加するを見てください。

直し方2:古い extern crate の行を use に置き換える

Section titled “直し方2:古い extern crate の行を use に置き換える”

2018 年より前のコードをコピーしてきたときは、これを選びます。そういうコードは、よくこんなブロックで始まっていて、どの行も E0463 になりえます。

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize)]
struct Order {
item: String,
qty: u32,
}
error[E0463]: can't find crate for `serde_derive`
--> src/main.rs:2:1
|
2 | extern crate serde_derive;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
error[E0463]: can't find crate for `serde_json`
--> src/main.rs:3:1
|
3 | extern crate serde_json;
| ^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

serde_derive と serde_json のどちらのクレートも見つからない、と言われています。ここで serde_derive を別のクレートとして追加してはいけません。今は、serde の derive フィーチャーをオンにすると、derive マクロも一緒に付いてきます。

Terminal window
cargo add serde --features derive
cargo add serde_json

そのあと extern crate のブロックを消して、使うものをふつうの use の行でインポートします。#[macro_use] もいりません。

use serde::Serialize;
#[derive(Serialize)]
struct Order {
item: String,
qty: u32,
}
fn main() {
let order = Order { item: String::from("apple"), qty: 3 };
println!("{}", serde_json::to_string(&order).unwrap());
}

実行結果:

{"item":"apple","qty":3}
▶ 実際に試してみよう

extern crate の行に書かれたクレートを、コードの中で実際には使っていないなら、その行を消すだけで済みます。今どきの設定の全体は、serdeでJSONを扱うのレッスンで紹介しています。

直し方3:rustup target add でターゲットをインストールする

Section titled “直し方3:rustup target add でターゲットをインストールする”

エラーが std(または core)についてのもので、note: に「ターゲットがインストールされていないかもしれない」と書かれているときは、これを選びます。ターゲット名は help: の行からコピーしましょう。

Terminal window
rustup target add aarch64-unknown-linux-gnu
rustup target list --installed # 今入っているターゲットを確認する

そのあと、同じ --target を付けてもう一度ビルドします。ターゲットとは、コンパイルした結果を動かすマシンの種類のことで、aarch64-unknown-linux-gnu や wasm32-unknown-unknown のような「トリプル」で書きます。rustup がそのターゲット用のビルド済み std をダウンロードするので、E0463 は消えます。

注意が2つあります。1つ目に、多くのターゲットでは、これが最後の手順ではありません。ほかの OS 向けに完全なプログラムをビルドするには、たいていその環境用のリンカーも必要で、それが足りないと別のエラーになります。2つ目に、プロジェクトに rust-toolchain.toml があるなら、コマンドはプロジェクトのフォルダの中で実行しましょう。そうすれば、そのプロジェクトが実際に使うツールチェーンにターゲットが追加されます。詳しくはコンポーネントとターゲットと、よく使うターゲットの例としてWebAssemblyのレッスンを見てください。

直し方4:コードではダッシュをアンダースコアで書く

Section titled “直し方4:コードではダッシュをアンダースコアで書く”

serde-json や tracing-subscriber のように、クレート名にダッシュが入っているときは、これを選びます。Cargo.toml やコマンドラインでは、ダッシュのままで大丈夫です。でも Rust のコードの中では - はマイナス記号なので、名前はいつも _ で書きます。ダッシュを使った古いコードでは、こうなります。

error: crate name using dashes are not valid in `extern crate` statements
--> src/main.rs:1:14
|
1 | extern crate serde-json;
| ^^^^^^^^^^ dash-separated idents are not valid
|
help: if the original crate name uses dashes you need to use underscores in the code
|
1 - extern crate serde-json;
1 + extern crate serde_json;
|
error[E0463]: can't find crate for `serde_json`

1つ目のエラーは「extern crate の文では、ダッシュを含むクレート名は使えない」、help は「元のクレート名にダッシュがあるなら、コードではアンダースコアを使う必要がある」という意味です。rustc はすでに名前を serde_json と読みかえているので、その下の E0463 が出るのは、クレートが Cargo.toml にもないときだけです。use の行でダッシュを使うと、expected one of `::`, `;`, or `as`, found `-` (::、;、as のどれかが来るはずなのに - があった)という別のメッセージになります。直し方はどこでも同じです。必要なら cargo add でクレートを追加し、コードでは _ で書きます。

use serde_json::json;
fn main() {
let order = json!({ "item": "apple", "qty": 3 });
println!("{order}");
}

実行結果:

{"item":"apple","qty":3}
▶ 実際に試してみよう

自分のパッケージにも同じルールが当てはまります。shop-app という名前のプロジェクトは、その main.rs やテストからは shop_app としてインポートします。

rustc main.rs を直接実行したとき。 rustc だけでは Cargo.toml を読まないので、cargo add rand をしたあとでも、extern crate rand; の行に対して rustc --edition 2021 src/main.rs は can't find crate for `rand` と言います(use rand::... の行なら E0432)。直し方:cargo run か cargo build でビルドします。これらは依存クレートをコンパイラに渡してくれます。

[dev-dependencies] に書いたクレート。 dev-dependencies(cargo add --dev で追加したもの)は、テスト、example、ベンチマークのためだけに存在します。ふつうのコードから使うと、extern crate なら E0463、パスなら E0433 になります。直し方:cargo remove --dev serde_json を実行してから cargo add serde_json を実行し、[dependencies] に移します。

OS のない組み込みボード。 thumbv7em-none-eabihf のようなターゲットでは、インストールするだけでは足りません。そもそも std がないからです。note もそう言う内容に変わります。

error[E0463]: can't find crate for `std`
|
= note: the `thumbv7em-none-eabihf` target may not support the standard library
= note: `std` is required by `shop` because it does not declare `#![no_std]`

「このターゲットは標準ライブラリに対応していないかもしれない」「shop は #![no_std] を宣言していないので std が必要」という意味です。直し方:プログラムを #![no_std] で書きます。これは println! が使えず、パニックハンドラーも自分で用意するということです。The Embedded Rust Book(英語)で手順を追って学べます。

  • E0432:unresolved import(インポートを解決できない)。クレートが Cargo.toml にないとき、use の行で出るエラーです。
  • E0433:failed to resolve(解決に失敗した)。クレートがないとき、rand::rng() のようなパスで出るエラーです。
  • E0603:クレートは見つかったけれど、使いたいアイテムが非公開になっている。
  • crate name using dashes are not valid:このエラーにはコードがありません。- の代わりに _ を書きます(直し方4)。
  • コンパイルエラーの一覧:エラー解説ページの全リストです。

理解度チェック

1. 古いコードが extern crate regex; で始まっていて、E0463 が出ます。2021 エディションのプロジェクトでいちばんよい直し方はどれですか?

2. cargo build --target wasm32-unknown-unknown で、std のクレートが見つからず、ターゲットがインストールされていないかもしれないと言われました。何を実行しますか?

3. Cargo.toml に tracing-subscriber = "0.3" と書かれています。Rust のコードではクレート名をどう書きますか?

スコア: 0 / 3