Ошибка 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 так делает
Заголовок раздела «Почему Rust так делает»В 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.
Как исправить
Заголовок раздела «Как исправить»Исправление 1: добавь крейт через cargo add
Заголовок раздела «Исправление 1: добавь крейт через cargo add»Выбирай это, когда не хватает крейта с crates.io, например rand, regex или serde_json. Это самый частый случай. Запусти это в папке, где лежит Cargo.toml:
cargo add randCargo сам добавит самую новую версию:
[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:
cargo add serde --features derivecargo 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::
rustup target add aarch64-unknown-linux-gnurustup 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
Что почитать
Заголовок раздела «Что почитать»- E0463 — список кодов ошибок Rust (на английском): официальное объяснение случая с отсутствующим крейтом.
- Использование крейта для получения дополнительного функционала — книга «Язык программирования Rust» (перевод на русский): как шаг за шагом добавить первую зависимость в
Cargo.toml. - Specifying Dependencies — The Cargo Book (на английском): версии, возможности (features) и разница между
[dependencies]и[dev-dependencies]. - Path and module changes in Rust 2018 — Edition Guide (на английском): почему
extern crateбольше не нужен. - Cross-compilation — The rustup book (на английском): установка целей через
rustup target add.