Errore Rust E0463: can't find crate (crate non trovato)
E0463 significa che il compilatore è andato a cercare un intero crate (una libreria) ed è tornato a mani vuote. Di solito il tuo codice ha una riga extern crate per un crate che non è in Cargo.toml. A volte il crate mancante è std stesso, e succede quando compili per un altro tipo di macchina senza aver ancora installato quel target. Entrambi i casi si risolvono in fretta, e non serve capire i linker per farlo. Questa pagina fa parte della guida agli errori del compilatore.
Il messaggio di errore
Sezione intitolata “Il messaggio di errore”error[E0463]: can't find crate for `rand` --> src/main.rs:1:1 |1 | extern crate rand; | ^^^^^^^^^^^^^^^^^^ can't find crateIl compilatore dice: «non trovo il crate rand». Questo è il programma che lo produce, in un progetto appena creato con cargo new e senza niente sotto [dependencies]:
extern crate rand;
fn main() { let roll = rand::random_range(1..=6); println!("You rolled {roll}");}La seconda forma comune non ha nessun numero di riga, perché nessuna riga del tuo codice chiede std. Ogni programma ne ha bisogno:
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`La ottieni da cargo build --target aarch64-unknown-linux-gnu (Linux su ARM a 64 bit, come un Raspberry Pi) quando è installato solo il target della tua macchina. La nota dice che il target potrebbe non essere installato, e l’help suggerisce di scaricarlo. La soluzione che ti serve dipende dal nome del crate e dalla note::
| Cosa vedi | Cosa è andato storto di solito | Soluzione |
|---|---|---|
can't find crate for `rand` su una riga extern crate |
il crate non è in Cargo.toml |
Soluzione 1 |
la stessa cosa, in codice vecchio con #[macro_use] |
codice scritto prima dell’edizione 2018 | Soluzione 2 |
can't find crate for `std` + target may not be installed |
compili per un target che rustup non ha scaricato | Soluzione 3 |
crate name using dashes are not valid accanto a E0463 |
un - nel nome del crate dentro il codice |
Soluzione 4 |
Cosa significa
Sezione intitolata “Cosa significa”extern crate rand; dice al compilatore «collega a questo programma la libreria compilata che si chiama rand». Il compilatore non scarica niente e non cerca su internet. Guarda solo le librerie che gli passa Cargo, e Cargo gli passa solo i crate elencati in Cargo.toml. Se lì non c’è rand, nella lista non c’è nessuna libreria rand: ecco E0463.
Il caso di std è la stessa idea, un livello più in basso. Anche la libreria standard è una libreria compilata, e rustup ne installa una copia per ogni target. La tua toolchain normale ha solo la copia per il tuo computer. Chiedi una build per ARM e il compilatore cerca una copia ARM di std che non c’è.
È come una ricetta che dice «usa la farina della dispensa». Se nessuno ha comprato la farina, il cuoco non può cominciare, per quanto buona sia la ricetta.
Perché Rust si comporta così
Sezione intitolata “Perché Rust si comporta così”Rust non ha una cartella globale e condivisa di librerie installate, come il pip install di Python o un node_modules di sistema. Ogni progetto dice esattamente cosa usa in Cargo.toml, con le versioni, e Cargo compila quei crate per quel progetto. Per questo lo stesso progetto si compila allo stesso modo sul tuo portatile, sul computer di un collega e nella CI. Un crate che non è scritto lì, per il tuo codice semplicemente non esiste.
extern crate è per lo più un residuo di Rust 2015. Dall’edizione 2018, ogni crate in Cargo.toml è disponibile in automatico, quindi il codice moderno scrive semplicemente use rand::random_range;. Trovi ancora extern crate nei vecchi tutorial e nelle risposte di Stack Overflow, ed è da lì che arriva la maggior parte degli E0463. Oggi, senza la dipendenza, una riga use dà E0432 e un percorso nel codice dà E0433. Stessa causa, codice diverso.
Vedi Cargo e crate per come funzionano le dipendenze, e Strumenti Rust per toolchain e target.
Come risolverlo
Sezione intitolata “Come risolverlo”Soluzione 1: Aggiungi il crate con cargo add
Sezione intitolata “Soluzione 1: Aggiungi il crate con cargo add”Scegli questa quando il crate mancante viene da crates.io, come rand, regex o serde_json. È il caso più comune. Esegui questo comando nella cartella che contiene Cargo.toml:
cargo add randCargo aggiunge per te la versione più recente:
[dependencies]rand = "0.10.3"Basta questo per risolvere E0463. Già che ci sei, cancella la riga extern crate rand;: dall’edizione 2018 in poi non serve (controlla edition = in Cargo.toml). Questa versione stampa un controllo invece del numero uscito, così l’output è sempre lo stesso:
fn main() { let roll = rand::random_range(1..=6); println!("Il lancio è tra 1 e 6: {}", (1..=6).contains(&roll));}Output:
Il lancio è tra 1 e 6: trueIl codice vecchio potrebbe anche chiamare funzioni cambiate tra una versione e l’altra. Se cargo add risolve E0463 ma poi ottieni E0425 o E0432 per qualcosa come thread_rng, controlla la documentazione del crate per la versione che hai. Vedi Cargo e crate, dove si parla di cargo add.
Soluzione 2: Sostituisci le vecchie righe extern crate con use
Sezione intitolata “Soluzione 2: Sostituisci le vecchie righe extern crate con use”Scegli questa quando hai copiato codice di prima del 2018. Spesso comincia con un blocco come questo, e ogni riga può dare 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 crateNon aggiungere serde_derive come crate separato. Oggi le macro derive arrivano con serde quando attivi la sua feature derive:
cargo add serde --features derivecargo add serde_jsonPoi cancella il blocco extern crate e importa ciò che usi con una normale riga use. Non serve nemmeno #[macro_use]:
use serde::Serialize;
#[derive(Serialize)]struct Order { item: String, qty: u32,}
fn main() { let order = Order { item: String::from("mela"), qty: 3 }; println!("{}", serde_json::to_string(&order).unwrap());}Output:
{"item":"mela","qty":3}Se una riga extern crate nomina un crate che il tuo codice in realtà non usa, cancella semplicemente la riga. La lezione JSON con serde mostra la configurazione moderna completa.
Soluzione 3: Installa il target con rustup target add
Sezione intitolata “Soluzione 3: Installa il target con rustup target add”Scegli questa quando l’errore riguarda std (o core) e la note: dice che il target potrebbe non essere installato. Copia il nome del target dalla riga help::
rustup target add aarch64-unknown-linux-gnurustup target list --installed # controlla cosa hai adessoPoi compila di nuovo con lo stesso --target. Un target è il tipo di macchina per cui compili, scritto come una «tripla» (triple) come aarch64-unknown-linux-gnu o wasm32-unknown-unknown. rustup scarica la std già compilata per quel target, e l’E0463 sparisce.
Due note. Primo: per molti target non è l’ultimo passo, perché compilare un programma completo per un altro sistema operativo di solito richiede anche un linker per quella piattaforma, e quello è un errore diverso. Secondo: se il progetto ha un rust-toolchain.toml, esegui il comando dentro la cartella del progetto, così rustup aggiunge il target alla toolchain che quel progetto usa davvero. Vedi Componenti e target e la lezione WebAssembly, per un target che probabilmente userai.
Soluzione 4: Nel codice, scrivi i trattini come trattini bassi
Sezione intitolata “Soluzione 4: Nel codice, scrivi i trattini come trattini bassi”Scegli questa quando il nome del crate ha un trattino, come serde-json o tracing-subscriber. In Cargo.toml e sulla riga di comando il trattino va bene. Nel codice Rust, un - è il segno meno, quindi il nome si scrive sempre con _. Il codice vecchio con un trattino dà questo:
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`rustc legge già il nome come serde_json, quindi l’E0463 sotto compare solo se il crate manca anche da Cargo.toml. In una riga use, un trattino dà un messaggio diverso, expected one of `::`, `;`, or `as`, found `-` . La soluzione è la stessa ovunque: fai cargo add del crate se serve, e scrivi _ nel codice:
use serde_json::json;
fn main() { let order = json!({ "item": "mela", "qty": 3 }); println!("{order}");}Output:
{"item":"mela","qty":3}La stessa regola vale per il tuo pacchetto: un progetto chiamato shop-app si importa come shop_app dal suo main.rs e dai suoi test.
Dove lo incontri di solito
Sezione intitolata “Dove lo incontri di solito”Eseguire direttamente rustc main.rs. rustc da solo non legge Cargo.toml, quindi anche dopo cargo add rand, rustc --edition 2021 src/main.rs dice ancora can't find crate for `rand` per una riga extern crate rand; (ed E0432 per una riga use rand::...). Soluzione: compila con cargo run o cargo build, che passano le tue dipendenze al compilatore.
Un crate elencato sotto [dev-dependencies]. Le dev-dependencies (aggiunte con cargo add --dev) esistono solo per test, esempi e benchmark. Usarne una dal codice normale dà E0463 con extern crate, o E0433 con un percorso. Soluzione: spostala in [dependencies] con cargo remove --dev serde_json e poi cargo add serde_json.
Schede embedded senza sistema operativo. Per un target come thumbv7em-none-eabihf, installarlo non basta, perché non ha proprio la std. La nota cambia e lo dice:
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]`Qui rustc dice che il target potrebbe non supportare la libreria standard, e che shop ne ha bisogno perché non dichiara #![no_std]. Soluzione: scrivi il programma come #![no_std], il che significa anche niente println! e un gestore di panic tutto tuo. L’Embedded Rust Book (in inglese) ti accompagna passo per passo.
Errori correlati
Sezione intitolata “Errori correlati”- E0432:
unresolved import, quello che dà una rigausequando il crate manca daCargo.toml. - E0433:
failed to resolve, quello che dà un percorso comerand::rng()quando il crate manca. - E0603: il crate è stato trovato, ma l’elemento che vuoi è privato.
crate name using dashes are not valid: questo non ha un codice di errore; scrivi_invece di-(Soluzione 4).- Tutti gli errori del compilatore: l’elenco completo delle pagine sugli errori.
Verifica veloce
Sezione intitolata “Verifica veloce”Verifica veloce
1. Del codice vecchio comincia con extern crate regex; e ottieni E0463. Qual è la soluzione migliore in un progetto con l'edizione 2021?
2. cargo build --target wasm32-unknown-unknown dice che non trova il crate std e che il target potrebbe non essere installato. Cosa esegui?
3. Il tuo Cargo.toml ha tracing-subscriber = "0.3". Come scrivi il nome del crate nel codice Rust?
Punteggio: 0 / 3
Per approfondire
Sezione intitolata “Per approfondire”- E0463 — Rust error codes index (in inglese): la spiegazione ufficiale del caso del crate mancante.
- Increasing Functionality with a Crate — The Rust Book (in inglese): aggiungere la tua prima dipendenza a
Cargo.toml, passo per passo. - Specifying Dependencies — The Cargo Book (in inglese): versioni, feature, e la differenza tra
[dependencies]e[dev-dependencies]. - Path and module changes in Rust 2018 — Edition Guide (in inglese): perché
extern cratenon serve più. - Cross-compilation — The rustup book (in inglese): installare target con
rustup target add.