Zum Inhalt springen

Rust-Fehler E0463: can't find crate (Crate nicht gefunden)

E0463 bedeutet: Der Compiler hat nach einem ganzen Crate (einer Bibliothek) gesucht und ist mit leeren Händen zurückgekommen. Meistens enthält dein Code eine extern crate-Zeile für ein Crate, das nicht in Cargo.toml steht. Manchmal ist das fehlende Crate sogar std selbst. Das passiert, wenn du für eine andere Art von Rechner baust und das passende Target noch nicht installiert hast. Für beide Fälle gibt es schnelle Lösungen, und du musst dafür nichts über Linker wissen. Diese Seite gehört zur Reihe Rust-Compilerfehler einfach erklärt.

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“ heißt „Crate rand nicht gefunden“.

Dieses Programm erzeugt den Fehler, in einem frischen cargo new-Projekt, bei dem unter [dependencies] nichts steht:

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

Die zweite häufige Form hat gar keine Zeilennummer, weil keine Zeile deines Codes nach std fragt. Jedes Programm braucht es einfach:

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`

Die note sagt: Das Target aarch64-unknown-linux-gnu ist vielleicht nicht installiert. Das help schlägt vor, es mit rustup target add herunterzuladen. Du bekommst diese Meldung bei cargo build --target aarch64-unknown-linux-gnu (64-Bit-ARM-Linux, zum Beispiel ein Raspberry Pi), wenn nur das Target für deinen eigenen Rechner installiert ist. Welche Lösung du brauchst, hängt vom Namen des Crates und von der note: ab:

Was du siehst Was meistens schiefgelaufen ist Lösung
can't find crate for `rand` bei einer extern crate-Zeile das Crate steht nicht in Cargo.toml Lösung 1
dasselbe, in altem Code mit #[macro_use] Code von vor der Edition 2018 Lösung 2
can't find crate for `std` + target may not be installed Build für ein Target, das rustup noch nicht heruntergeladen hat Lösung 3
crate name using dashes are not valid neben E0463 ein - im Crate-Namen in deinem Code Lösung 4

extern crate rand; sagt dem Compiler: „Binde die kompilierte Bibliothek namens rand in dieses Programm ein.“ Der Compiler lädt dabei nichts herunter und durchsucht nicht das Internet. Er schaut nur in die Bibliotheken, die Cargo ihm gibt. Und Cargo gibt ihm nur die Crates, die in Cargo.toml stehen. Steht dort kein rand, gibt es auch keine rand-Bibliothek auf der Liste, also E0463.

Der Fall mit std ist dieselbe Idee eine Ebene tiefer. Auch die Standardbibliothek ist eine kompilierte Bibliothek, und rustup installiert davon eine Kopie pro Target. Deine normale Toolchain hat nur die Kopie für deinen eigenen Rechner. Verlangst du einen ARM-Build, sucht der Compiler nach einer ARM-Kopie von std, die es nicht gibt.

Das ist wie ein Rezept, in dem steht: „Nimm das Mehl aus dem Schrank.“ Hat niemand Mehl gekauft, kann der Koch nicht anfangen – egal wie gut das Rezept ist.

Rust hat keinen globalen, gemeinsamen Ordner mit installierten Bibliotheken, wie bei Pythons pip install oder einem systemweiten node_modules. Jedes Projekt schreibt in Cargo.toml genau auf, was es benutzt, mit Versionen. Cargo baut diese Crates dann für genau dieses Projekt. Deshalb baut dasselbe Projekt auf deinem Laptop, auf dem Rechner einer Kollegin und in der CI auf dieselbe Weise. Ein Crate, das nicht aufgeschrieben ist, gibt es für deinen Code einfach nicht.

extern crate ist größtenteils ein Überbleibsel aus Rust 2015. Seit der Edition 2018 ist jedes Crate aus Cargo.toml automatisch verfügbar. Moderner Code schreibt also einfach use rand::random_range;. Du begegnest extern crate aber noch in alten Tutorials und Antworten auf Stack Overflow, und von dort kommen die meisten E0463. Fehlt die Abhängigkeit, gibt eine use-Zeile heute stattdessen E0432, und ein Pfad in deinem Code gibt E0433. Gleiche Ursache, anderer Code.

Wie Abhängigkeiten funktionieren, erklärt Cargo und Crates. Toolchains und Targets findest du unter Rust-Tools.

Nimm diese Lösung, wenn das fehlende Crate von crates.io kommt, wie rand, regex oder serde_json. Das ist der häufigste Fall. Führe diesen Befehl in dem Ordner aus, in dem Cargo.toml liegt:

Terminal window
cargo add rand

Cargo trägt die neueste Version für dich ein:

[dependencies]
rand = "0.10.3"

Das allein behebt E0463. Wenn du schon dabei bist, lösch die Zeile extern crate rand;. Ab der Edition 2018 brauchst du sie nicht mehr (schau in Cargo.toml nach edition = ). Diese Version gibt statt des Wurfs eine Prüfung aus, damit die Ausgabe immer gleich ist:

fn main() {
let roll = rand::random_range(1..=6);
println!("Wurf liegt zwischen 1 und 6: {}", (1..=6).contains(&roll));
}

Ausgabe:

Wurf liegt zwischen 1 und 6: true
▶ Selbst ausprobieren

Alter Code ruft manchmal auch Funktionen auf, die sich zwischen Versionen geändert haben. Behebt cargo add den Fehler E0463, aber du bekommst danach E0425 oder E0432 für etwas wie thread_rng, dann schau in die Doku des Crates für deine Version. Siehe Eine Abhängigkeit mit cargo add hinzufügen.

Lösung 2: Alte extern crate-Zeilen durch use ersetzen

Abschnitt betitelt „Lösung 2: Alte extern crate-Zeilen durch use ersetzen“

Nimm diese Lösung, wenn du Code von vor 2018 kopiert hast. Er beginnt oft mit so einem Block, und jede Zeile kann E0463 auslösen:

#[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

Füge serde_derive nicht als eigenes Crate hinzu. Heute kommen die Derive-Makros mit serde, wenn du das Feature derive einschaltest:

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

Dann lösch den extern crate-Block und importiere, was du brauchst, mit einer normalen use-Zeile. Auch #[macro_use] brauchst du nicht mehr:

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

Ausgabe:

{"item":"Apfel","qty":3}
▶ Selbst ausprobieren

Nennt eine extern crate-Zeile ein Crate, das dein Code gar nicht benutzt, lösch die Zeile einfach. Die Lektion JSON mit serde zeigt das moderne Setup vollständig.

Lösung 3: Das Target mit rustup target add installieren

Abschnitt betitelt „Lösung 3: Das Target mit rustup target add installieren“

Nimm diese Lösung, wenn es im Fehler um std (oder core) geht und die note: sagt, dass das Target vielleicht nicht installiert ist. Kopiere den Namen des Targets aus der help:-Zeile:

Terminal window
rustup target add aarch64-unknown-linux-gnu
rustup target list --installed # prüfen, was jetzt installiert ist

Bau danach noch einmal mit demselben --target. Ein Target ist die Art von Rechner, für den du kompilierst. Man schreibt es als „Triple“, etwa aarch64-unknown-linux-gnu oder wasm32-unknown-unknown. rustup lädt die fertig gebaute std dafür herunter, und E0463 ist weg.

Zwei Hinweise. Erstens ist das bei vielen Targets nicht der letzte Schritt: Für ein vollständiges Programm für ein anderes Betriebssystem brauchst du meistens auch einen Linker für diese Plattform. Fehlt der, ist das ein anderer Fehler. Zweitens: Hat das Projekt eine rust-toolchain.toml, führe den Befehl im Projektordner aus. Dann fügt rustup das Target genau der Toolchain hinzu, die das Projekt wirklich benutzt. Siehe Komponenten und Targets und die Lektion WebAssembly für ein Target, das du wahrscheinlich benutzen wirst.

Lösung 4: Bindestriche im Code als Unterstriche schreiben

Abschnitt betitelt „Lösung 4: Bindestriche im Code als Unterstriche schreiben“

Nimm diese Lösung, wenn der Name des Crates einen Bindestrich hat, wie serde-json oder tracing-subscriber. In Cargo.toml und auf der Kommandozeile ist der Bindestrich in Ordnung. Im Rust-Code ist ein - aber ein Minuszeichen, deshalb schreibt man den Namen dort immer mit _. Alter Code mit einem Bindestrich ergibt das hier:

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`

Die Meldung sagt: Namen mit Bindestrichen sind in extern crate nicht erlaubt, im Code brauchst du Unterstriche. rustc liest den Namen schon als serde_json. Das E0463 darunter erscheint also nur, wenn das Crate außerdem in Cargo.toml fehlt. In einer use-Zeile gibt ein Bindestrich eine andere Meldung, expected one of `::`, `;`, or `as`, found `-` . Die Lösung ist überall dieselbe: Füge das Crate bei Bedarf mit cargo add hinzu, und schreib im Code _:

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

Ausgabe:

{"item":"Apfel","qty":3}
▶ Selbst ausprobieren

Dieselbe Regel gilt für dein eigenes Paket: Ein Projekt namens shop-app importierst du aus seiner main.rs und seinen Tests als shop_app.

Wenn du rustc main.rs direkt aufrufst. rustc allein liest Cargo.toml nicht. Selbst nach cargo add rand sagt rustc --edition 2021 src/main.rs bei einer Zeile extern crate rand; deshalb immer noch can't find crate for `rand` (und E0432 bei einer Zeile use rand::...). Lösung: Bau mit cargo run oder cargo build. Die beiden geben deine Abhängigkeiten an den Compiler weiter.

Ein Crate unter [dev-dependencies]. Dev-Dependencies (hinzugefügt mit cargo add --dev) gibt es nur für Tests, Beispiele und Benchmarks. Benutzt du eine davon in normalem Code, gibt es E0463 mit extern crate oder E0433 mit einem Pfad. Lösung: Verschieb sie mit cargo remove --dev serde_json und danach cargo add serde_json nach [dependencies].

Embedded-Boards ohne Betriebssystem. Bei einem Target wie thumbv7em-none-eabihf reicht das Installieren nicht, weil es dort überhaupt kein std gibt. Die Notiz sagt das dann auch:

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

Übersetzt: Dieses Target unterstützt die Standardbibliothek vielleicht nicht, und shop braucht std, weil es kein #![no_std] angibt. Lösung: Schreib das Programm als #![no_std]. Das heißt auch: kein println! und ein eigener Panic-Handler. Das Embedded Rust Book (auf Englisch) führt dich durch alles.

  • E0432: unresolved import (Import nicht aufgelöst). Das gibt eine use-Zeile, wenn das Crate in Cargo.toml fehlt.
  • E0433: failed to resolve (Pfad nicht aufgelöst). Das gibt ein Pfad wie rand::rng(), wenn das Crate fehlt.
  • E0603: Das Crate wurde gefunden, aber das Element, das du daraus willst, ist privat.
  • crate name using dashes are not valid: Dieser Fehler hat keinen Code. Schreib _ statt - (Lösung 4).
  • Alle Compilerfehler: die vollständige Liste der Fehlerseiten.

Kurzer Check

1. Alter Code beginnt mit extern crate regex;, und du bekommst E0463. Was ist in einem Projekt mit Edition 2021 die beste Lösung?

2. cargo build --target wasm32-unknown-unknown meldet, dass es das Crate std nicht findet und das Target vielleicht nicht installiert ist. Was führst du aus?

3. In deiner Cargo.toml steht tracing-subscriber = "0.3". Wie schreibst du den Namen des Crates im Rust-Code?

Punkte: 0 / 3