Перейти к содержимому

Ошибка Rust E0463: can't find crate (крейт не найден)

E0463 значит, что компилятор пошёл искать целый крейт (библиотеку) и вернулся с пустыми руками. Обычно в твоём коде есть строка extern crate для крейта, которого нет в Cargo.toml. Иногда не хватает самого std — так бывает, когда ты собираешь программу для другого типа машины и ещё не установил эту цель (target). Оба случая исправляются быстро, и разбираться в линковщиках для этого не нужно. Эта страница — часть руководства по ошибкам компилятора.

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

Компилятор пишет: не удаётся найти крейт rand. Вот программа, которая выдаёт эту ошибку в свежем проекте cargo new, где в [dependencies] пусто:

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

У второй частой формы вообще нет номера строки, потому что ни одна строка твоего кода не просит 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`

Здесь не найден std: цель aarch64-unknown-linux-gnu, возможно, не установлена, и rustc советует скачать её через rustup target add. Эту ошибку ты получишь от cargo build --target aarch64-unknown-linux-gnu (64-битный ARM Linux, например Raspberry Pi), если установлена только цель твоего собственного компьютера. Какое исправление нужно, зависит от имени крейта и от note::

Что ты видишь Что обычно пошло не так Исправление
can't find crate for `rand` в строке extern crate крейта нет в Cargo.toml Исправление 1
то же самое в старом коде с #[macro_use] код написан до редакции 2018 Исправление 2
can't find crate for `std` + target may not be installed сборка для цели, которую rustup не скачал Исправление 3
crate name using dashes are not valid рядом с E0463 - в имени крейта в твоём коде Исправление 4

extern crate rand; говорит компилятору: «подключи к этой программе скомпилированную библиотеку rand». Компилятор ничего не скачивает и не ищет в интернете. Он смотрит только на библиотеки, которые ему передаёт Cargo, а Cargo передаёт только крейты из Cargo.toml. Нет там rand — нет и библиотеки rand в списке, отсюда E0463.

Случай с std — та же идея, только уровнем ниже. Стандартная библиотека — тоже скомпилированная библиотека, и rustup устанавливает по одной её копии на каждую цель. В твоём обычном тулчейне есть только копия для твоего компьютера. Попроси сборку для ARM — и компилятор будет искать ARM-копию std, которой нет.

Это как рецепт, где написано «возьми муку из шкафа». Если муку никто не купил, повар не сможет начать, каким бы хорошим ни был рецепт.

В Rust нет общей глобальной папки установленных библиотек, как у pip install в Python или общесистемного node_modules. Каждый проект точно указывает в Cargo.toml, что он использует, с версиями, и Cargo собирает эти крейты для этого проекта. Поэтому один и тот же проект одинаково собирается на твоём ноутбуке, на машине коллеги и в CI. Крейта, который не записан, для твоего кода просто не существует.

extern crate — в основном пережиток Rust 2015. Начиная с редакции 2018 каждый крейт из Cargo.toml доступен автоматически, поэтому современный код просто пишет use rand::random_range;. Но extern crate всё ещё встречается в старых учебниках и ответах на Stack Overflow, и именно оттуда берётся большинство ошибок E0463. Сегодня без зависимости строка use даст E0432, а путь в коде — E0433. Причина та же, код другой.

Как работают зависимости, рассказано в уроке Cargo и крейты, а про тулчейны и цели — в уроке Инструменты Rust.

Выбирай это, когда не хватает крейта с crates.io, например rand, regex или serde_json. Это самый частый случай. Запусти это в папке, где лежит Cargo.toml:

Terminal window
cargo add rand

Cargo сам добавит самую новую версию:

[dependencies]
rand = "0.10.3"

Одного этого достаточно, чтобы исправить E0463. Заодно удали строку extern crate rand;: в редакции 2018 и новее она не нужна (проверь edition = в Cargo.toml). Эта версия печатает проверку вместо самого броска, поэтому вывод всегда одинаковый:

fn main() {
let roll = rand::random_range(1..=6);
println!("Бросок от 1 до 6: {}", (1..=6).contains(&roll));
}

Вывод:

Бросок от 1 до 6: true
▶ Попробуй сам

В старом коде могут вызываться функции, которые изменились между версиями. Если cargo add исправил E0463, но потом ты получаешь E0425 или E0432 для чего-то вроде thread_rng, загляни в документацию крейта для твоей версии. Подробнее в уроке Cargo и крейты.

Исправление 2: замени старые строки extern crate на use

Заголовок раздела «Исправление 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 отдельным крейтом. Сегодня derive-макросы идут вместе с serde, если включить его возможность (feature) 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("яблоко"), qty: 3 };
println!("{}", serde_json::to_string(&order).unwrap());
}

Вывод:

{"item":"яблоко","qty":3}
▶ Попробуй сам

Если строка extern crate называет крейт, которым твой код на самом деле не пользуется, просто удали её. Урок JSON и serde показывает современную настройку целиком.

Исправление 3: установи цель через rustup target add

Заголовок раздела «Исправление 3: установи цель через rustup target add»

Выбирай это, когда ошибка касается std (или core), а note: говорит, что цель, возможно, не установлена. Скопируй имя цели из строки help::

Terminal window
rustup target add aarch64-unknown-linux-gnu
rustup target list --installed # проверь, что теперь установлено

Потом снова собери с тем же --target. Цель — это тип машины, для которой ты компилируешь, записанный «тройкой» (triple) вроде aarch64-unknown-linux-gnu или wasm32-unknown-unknown. rustup скачивает для неё готовый std, и E0463 исчезает.

Два замечания. Во-первых, для многих целей это не последний шаг: для сборки полноценной программы под другую ОС обычно нужен ещё и линковщик для этой платформы, а это уже другая ошибка. Во-вторых, если в проекте есть rust-toolchain.toml, запускай команду внутри папки проекта, чтобы rustup добавил цель в тот тулчейн, которым проект действительно пользуется. Подробнее в уроке Инструменты Rust и в уроке WebAssembly — там цель, которая тебе, скорее всего, пригодится.

Исправление 4: пиши дефисы в коде как подчёркивания

Заголовок раздела «Исправление 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`

Компилятор говорит, что имена крейтов с дефисами в extern crate недопустимы, и советует писать подчёркивания. rustc уже читает имя как serde_json, так что E0463 под этим сообщением появляется, только если крейта ещё и нет в Cargo.toml. В строке use дефис даёт другое сообщение: expected one of `::`, `;`, or `as`, found `-` . Исправление везде одно: сделай cargo add для крейта, если нужно, и пиши _ в коде:

use serde_json::json;
fn main() {
let order = json!({ "item": "яблоко", "qty": 3 });
println!("{order}");
}

Вывод:

{"item":"яблоко","qty":3}
▶ Попробуй сам

То же правило работает и для твоего собственного пакета: проект с именем shop-app импортируется как shop_app из его main.rs и его тестов.

Запуск rustc main.rs напрямую. Сам по себе rustc не читает Cargo.toml, поэтому даже после cargo add rand команда rustc --edition 2021 src/main.rs всё равно говорит can't find crate for `rand` для строки extern crate rand; (и E0432 для строки use rand::...). Исправление: собирай через cargo run или cargo build — они передают компилятору твои зависимости.

Крейт указан в [dev-dependencies]. Dev-зависимости (добавленные через cargo add --dev) существуют только для тестов, примеров и бенчмарков. Если использовать такую из обычного кода, получишь E0463 с extern crate или E0433 с путём. Исправление: перенеси её в [dependencies] командой cargo remove --dev serde_json, а потом cargo add serde_json.

Встраиваемые платы без операционной системы. Для цели вроде thumbv7em-none-eabihf установки недостаточно, потому что std там нет вообще. Примечание меняется и говорит об этом:

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]`

Здесь rustc объясняет, что эта цель может не поддерживать стандартную библиотеку, а std нужен крейту shop, потому что он не объявляет #![no_std]. Исправление: пиши программу как #![no_std] — это значит ещё и никакого println! и свой обработчик паники. Книга Embedded Rust Book (на английском) проведёт тебя через это шаг за шагом.

  • E0432: unresolved import — то, что даёт строка use, когда крейта нет в Cargo.toml.
  • 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