Rustlang-Tutorial

So programmieren Sie mit Rust

24.11.2022
Von 
Serdar Yegulalp schreibt für unsere US-Schwesterpublikation Infoworld.
Programmieren mit Rust? Mit diesem Tutorial gelingt Ihnen der Einstieg.
Rusts eigene Toolchain ist ein Grund für die Entwicklungsfortschritte der Programmiersprache. Unser Tutorial vermittelt Ihnen die Grundlagen der Programmierarbeit mit Rust.
Rusts eigene Toolchain ist ein Grund für die Entwicklungsfortschritte der Programmiersprache. Unser Tutorial vermittelt Ihnen die Grundlagen der Programmierarbeit mit Rust.
Foto: Roman Gorielov - shutterstock.com

Im Laufe der letzten Jahre hat sich die Programmiersprache Rust von einer Kuriosität, die den Mozilla-Laboren entsprungen ist, zu einem starken Anwärter unter den Coding-Sprachen entwickelt, wenn es um die nächste Generation nativer Anwendungen und Bare-Metal-Lösungen geht. Diese Fortschritte sind in erster Linie darauf zurückzuführen, dass Rust seine eigene Toolchain und sein eigenes Komponenten-Management-System bereitstellt, inklusiver bestimmter beliebter Funktionen und Eigenheiten.

Dieses Tutorial richtet sich an Entwickler, die gerade in die Programmierung mit Rust einsteigen - oder in Betracht ziehen, bei zukünftigen Projekten mit der Programmiersprache zu arbeiten. Im Folgenden lesen Sie unter anderem,

  • wie Sie eine Arbeitsumgebung in Rust einrichten,

  • was zu beachten ist, wenn Sie eine IDE konfigurieren, und

  • wie Sie sich das hervorragende Anwendungsentwicklungs-Toolset von Rust optimal zunutze machen.

Rust-Releases verstehen

Die Toolchain von Rust besteht in erster Linie aus dem Rust-Compiler - rustc - sowie aus Tools, um eine Rust-Installation zu managen. Da Rust ständig weiterentwickelt wird, ist die Toolchain auf leichte Aktualisierbarkeit konzipiert. Softwareprojekte werden oft über mehrere Kanäle bereitgestellt, um stabile und Beta-Versionen des Codes zu trennen. Rust funktioniert auf die gleiche Weise und bietet drei Kanäle für Toolchain-Updates:

  • Stable: Große Versionen, die etwa alle sechs Wochen erscheinen.

  • Beta: Kandidaten für die nächste Hauptversion, die häufiger erscheinen.

  • Nightly: Der unmittelbare Build, der Zugang zu den neuesten Funktionen bietet - aber keine Stabilitätsgarantie.

Wie auch Entwickler Karol Kuczmarski in einem Blogpost betont, ist es empfehlenswert, den Nightly-Kanal als eine eigene Sprache zu betrachten: Einige Rust-Funktionen sind nur in diesem Channel verfügbar und nur durch spezielle Compiler-Direktiven zu aktivieren. Mit anderen Worten: Sie lassen sich weder im Beta- noch im Stable-Channel kompilieren.

Das ist so gewollt, denn es gibt keine Garantie dafür, dass die Nightly-Features auch anderweitig unterstützt werden. Viele dieser Funktionen werden jedoch irgendwann aus der Nightly- in die Beta- und Stable-Versionen überführt. Nach WebAssembly zu kompilieren, funktioniert zum Beispiel inzwischen in der Stable-Version Rust 1.30. Für Entwickler bedeutet das kurz zusammengefasst:

  • Nutzen Sie Stable für die tatsächliche Produktions-Arbeit.

  • Nutzen Sie Beta, um aktuelle Software mit kommenden Versionen zu testen und um zu überprüfen, ob sich beim Upgrade Fehler und Defekte einschleichen könnten.

  • Nutzen Sie Nightly für Sandbox-Experimente mit den neuesten Funktionen von Rust.

Betriebssystem für Rust wählen

Rust unterstützt die drei großen Plattformen - Windows, Linux und macOS - in allen 32- und 64-Bit-Varianten, für die es jeweils offizielle Binärdateien gibt. Für eine Reihe weiterer Plattformen stehen ebenfalls offizielle Binaries zur Verfügung - dieses sind aber nicht gleichermaßen gut ausgestattet, wenn es um automatisiertes Testing geht. Zu diesen "zweitklassigen" Plattformen gehören etwa ARMv6 und ARMv7 für iOS, Android und Linux, MIPS Linux und MIPS64 Linux, die 32-Bit-Editionen von x86-iOS, -Windows und -Linux sowie WebAssembly. Weitere Plattformen wie Windows XP oder das experimentelle HaikuOS, werden durch inoffizielle Builds unterstützt.

Laut den Rust-Entwicklern war es nicht ihr Ziel, eine Programmiersprache mit möglichst breiter Portabilität zu schaffen. Obwohl Rust zum Beispiel auf vielen ARM-Architekturen verfügbar ist, gibt es keine Garantie, dass sie offiziell auf Low-End-Hardware-Plattformen unterstützt wird. Durch den Support von 32- und 64-Bit-Windows, Linux und macOS dürfte jedoch die überwiegende Mehrheit der gängigen Use Cases abgedeckt sein.

Wenn Sie mit Rust unter Windows entwickeln wollen, sollten Sie Ihre Toolchains im Auge behalten. Im Fall von Windows unterstützt Rust:

  • die native Microsoft Visual C (MSVC) ABI;

  • die Gnu ABI, die vom GCC-Linker verwendet wird;

Da fast alle C/C++-Applikationen, die unter Windows erstellt werden, ohnehin MSVC verwenden, empfiehlt sich diese Option. Wenn Sie jemals GCC benötigen, dann höchstwahrscheinlich für die Interoperabilität mit Bibliotheken von Drittanbietern, die in Windows mit GCC erstellt wurden. Das Toolchain-Management-System von Rust ermöglicht es Ihnen dabei, sowohl die MSVC- als auch die GCC-Toolchain zu installieren und bei Bedarf zu wechseln.

Zu den Kompilierungszielen von Rust gehört WebAssembly - Sie können also in Rust programmieren und das Ergebnis über einen Webbrowser bereitstellen. Weder WebAssembly selbst, noch der Rust-Support sind allerdings vollständig ausgereift - wenn Sie sich die Hände dennoch "schmutzig" machen wollen, empfiehlt sich die Lektüre dieses E-Books, das den Prozess der Kompilierung von WebAssembly nach Rust ausführlich beschrieben wird.

Rust-Setup starten

Rust bietet ein All-In-One-Installationsprogramm und Toolchain-Wartungssystem namens rustup. Nach dem Download steht die aktuellste Version der Rust-Toolchain zur Installation bereit. Zu den wichtigsten Tools, die über rustup gewartet werden, gehören:

  • rustup selbst: Wann immer neue Versionen von rustup oder anderen Tools veröffentlicht werden, aktualisieren Sie diese mit rustup update automatisch.

  • rustc: der Rust-Compiler.

  • Cargo: der Package- und Workspace-Manager von Rust.

Standardmäßig installiert rustup Rust aus dem Stable-Channel. Wenn Sie Beta- oder Nightly-Versionen verwenden möchten, müssen Sie diese Kanäle manuell installieren (zum Beispiel mit rustup install nightly) und Sie als Standardeinstellung in Rust konfigurieren (rustup default nightly). Dabei können Sie auch manuell festlegen, welcher Kanal verwendet werden soll, wenn eine Rust-Applikation kompiliert wird. So müssen Sie nicht jedes Mal, wenn Sie zwischen Projekten wechseln den Standard neu konfigurieren.

Der rustup-Befehl sorgt dafür, dass alle Teile der Toolchain auf die neuesten Versionen aktualisiert werden. Hier wird die Nightly-Toolchain mit den neuesten und potenziell instabilen Sprachkomponenten getrennt von der Stable-Version aktualisiert.
Der rustup-Befehl sorgt dafür, dass alle Teile der Toolchain auf die neuesten Versionen aktualisiert werden. Hier wird die Nightly-Toolchain mit den neuesten und potenziell instabilen Sprachkomponenten getrennt von der Stable-Version aktualisiert.

Sie können rustup auch verwenden, um eigene Toolchains zu installieren und zu pflegen. Diese werden typischerweise von inoffiziellen Rust-Builds von Drittanbietern für nicht unterstützte Plattformen verwendet und benötigen in der Regel ihre eigenen Linker oder andere plattformspezifische Tools.

Eine weitere Grundlage in Rust: Cargo-Files (heruntergeladene Pakete und Konfigurationsinformationen) werden standardmäßig in einem Unterverzeichnis Ihres Benutzerprofils gespeichert. Das ist nicht immer wünschenswert: Manchmal sollen diese Daten auf andere Laufwerke mit mehr Platz oder leichterem Zugang abgelegt werden. Das bewerkstelligen Sie, indem Sie diese nach der Installation händisch verschieben. Dazu gehen Sie wie folgt vor:

  1. Beenden Sie alle Programme, die Cargo nutzen (könnten).

  2. Kopieren Sie das .cargo-Verzeichnis an den gewünschten Ort.

  3. Richten Sie die Umgebungsvariablen CARGO_HOME und RUSTUP_HOME so aus, dass sie auf das neue Verzeichnis verweisen.

  4. Setzen Sie PATH so an, dass er auf das bin-Unterverzeichnis des neuen Ordners verweist.

  5. Stellen Sie mit cargo sicher, dass Cargo ordnungsgemäß läuft.

IDE für Rust konfigurieren

Obwohl Rust eine relativ junge Programmiersprache ist, wird sie bereits von vielen gängigen IDEs unterstützt. Der Developer Manuel Hoffman hat mit "Are we (I)DE yet?" ein Projekt ins Leben gerufen, das Sie dabei unterstützt, den IDE-Support-Überblick zu behalten.

Ein ausdrückliches Ziel des Rust-Entwicklerteams ist es, die Programmiersprache mit Hilfe des Rust Language Server (RLS) möglichst gut für die Zusammenarbeit mit integrierten Entwicklungen zu gestalten. Der RLS liefert dazu Live-Feedback über den betreffenden Code - allerdings nicht von einem Parser eines Drittanbieters, sondern über den Rust-eigenen Compiler.

Das Language-Server-Projekt von Rust liefert Live-Feedback vom Compiler für den Code, mit dem Sie arbeiten, an eine IDE. Visual Studio Code (hier im Bild) bringt umfassenden Support für den Rust Language Server mit.
Das Language-Server-Projekt von Rust liefert Live-Feedback vom Compiler für den Code, mit dem Sie arbeiten, an eine IDE. Visual Studio Code (hier im Bild) bringt umfassenden Support für den Rust Language Server mit.

Folgende IDEs bringen Support für Rust mit:

Rust-Projekt erstellen

Rust-Projekte sollten eine einheitliche Verzeichnisstruktur aufweisen, in der Code- und Projekt-Metadaten auf bestimmte Art und Weise gespeichert werden: Der Code wird in einem src-Unterverzeichnis gespeichert, Details über das Projekt werden in zwei Dateien im Stammverzeichnis des Projekts gespeichert - Cargo.toml (die grundlegenden Informationen des Projekts) und Cargo.lock (eine automatisch generierte Liste der Abhängigkeiten). Sie können diese Verzeichnisstruktur und die Metadaten von Hand erstellen - es ist jedoch einfacher, die Rust-eigenen Tools dafür zu verwenden.

Das Cargo-Tool von Rust verwaltet sowohl Rust-Projekte als auch -Bibliotheken oder die "Crates", die sie verwenden. Mit dem Befehl cargo new my_project erstellen Sie ein neues Rust-Projekt mit dem Namen my_project in einem eigenen Verzeichnis (C#-Entwickler, die mit .Net Core arbeiten, denken an den Befehl dotnet new.) Das neue Projekt erscheint in einem Unterverzeichnis mit diesem Namen, zusammen mit einem grundlegenden Projektmanifest - der Datei Cargo.toml - und einem Stub für den Quellcode des Projekts in einem src-Unterverzeichnis.

Wenn Sie ein neues Projekt erstellen, wird im src-Verzeichnis des Projekts automatisch eine Datei main.rs erstellt. Diese Datei enthält eine einfache "Hello World"-Anwendung, die es Ihnen ermöglicht, Ihre Rust-Toolchain sofort zu testen, indem Sie sie kompilieren und ausführen. Hier Quellcode für die eben beschriebene Applikation:

fn main() {

println!("Hello World!");

}

Um die Anwendung zu kompilieren und auszuführen, nutzen Sie den Befehl cargo_run im Stammverzeichnis des Projekts. Beachten Sie, dass Cargo Projekte standardmäßig im Debug-Modus erstellt. Um im Release-Modus zu starten, verwenden Sie cargo run --release. Die Binärdateien werden im Unterverzeichnis target/debug oder target/release des Projekts erstellt, je nachdem, welches Kompilierungsprofil Sie verwenden.

Wenn ein Rust-Projekt kompiliert wird, werden auch alle Abhängigkeiten automatisch ermittelt und kompiliert. Detailliertes, zeilenweises Feedback erscheint für alles, was eine Warnung oder einen ausgewachsenen Fehler auslöst.
Wenn ein Rust-Projekt kompiliert wird, werden auch alle Abhängigkeiten automatisch ermittelt und kompiliert. Detailliertes, zeilenweises Feedback erscheint für alles, was eine Warnung oder einen ausgewachsenen Fehler auslöst.

Das Online-Handbuch "Rust By Example" hält interactive Code-Beispiele bereit, die direkt im Browser bearbeitet und ausgeführt werden können. Hier wird fast jedes bedeutsame Rust-Konzept abgedeckt.

Mit Rust Crates arbeiten

Package Management ist ein essenzieller Bestandteil jeder modernen Entwicklungsumgebung. Dafür bietet Rust "Crates" - Drittanbieterbibliotheken, die für die Distribution mit den Rust Tools verpackt werden. Crates stehen in der offiziellen Rust Package Registry zur Verfügung. Falls Ihr Projekt von einem bestimmten Crate abhängig ist, müssen das angeben, indem Sie die Cargo.toml-Datei entsprechend editieren. Das geschieht in der Regel manuell mit einem Texteditor. Wenn das Projekt das nächste Mal neu erstellt wird, holt sich Rust automatisch alle benötigten Abhängigkeiten. Die beiden Tools cargo-edit und cargo-edit-locally können Abhängigkeiten von der Kommandozeile aus aktualisieren - es handelt sich aber um inoffizielle Drittanbieterprojekte (cargo-edit-locally wurde seit 2017 nicht mehr aktualisiert).

Wenn Sie ein Rust-Projekt erstellen, das von externen Crates abhängt, sucht Cargo standardmäßig nach diesen Crates auf Crates.io - Sie müssen sie nicht manuell beschaffen. Sie können auch URLs nutzen, um auf Crates in Ihrem Projekt zu verweisen, für den Fall, dass diese beispielsweise aus einem privaten Repository stammt.

Einige Crates können zudem ausschließlich im Nightly-Channel von Rust installiert und erstellt werden, weil sie experimentelle Funktionen verwenden, die in anderen Channels nicht verfügbar sind. Wenn Sie versuchen, im Release-Channel einen solchen Crate zu installieren, werden Sie keine Warnung erhalten - bis die Kompilierung selbst fehlschlägt. Die Crate-Dokumentation gibt normalerweise Auskunft darüber, ob es den Nightly-Channel benötigt oder nicht - lesen Sie also nach, bevor Sie es einbinden, geschweige denn kompilieren.

Crates können auch Binärdateien enthalten. Einige sind Kommandozeilen-Tools, die in der Rust-Entwicklung verwendet werden, andere Allzweck-Tools (wie ripgrep). Um eines dieser Crates zu installieren, nutzen Sie cargo install <crate name>. Das ist nicht der einzige Weg, eine mit Rust erstellte Binärdatei zu verteilen, aber ein bequemer Weg für Rust-Entwickler, diese mit Rust-Tools zu erhalten.

Rust-Projekte cross-kompilieren

Weil Rust mehrere Toolchains unterstützt, können Sie Rust-Anwendungen für ein anderes Betriebssystem und eine andere Umgebung kompilieren als die, auf der Sie kompilieren. Eine solche Cross-Kompilierung erfordert auf der Plattform, auf der Sie arbeiten, eine Toolchain die mit der Zielplattform übereinstimmt.

Das erfordert in einigen Fällen - wie bei der Cross-Kompilierung von Linux auf Windows oder umgekehrt - nicht mehr als den GCC-Linker. In anderen Fällen gestalten sich die Dinge komplexer. Für die Cross-Kompilierung nach macOS benötigen Sie zum Beispiel die Xcode-IDE-Bibliotheken, -cctools (Apples Äquivalent zu binutils) und das macOS-SDK.

Diese Hürden lassen sich teilweise mit Tools von Drittanbietern nehmen:

  • Cross läuft direkt auf einem 64-Bit-x86-Linux-Host und ermöglicht eine "Zero Setup" Cross-Kompilierung zu einer Vielzahl von Zielumgebungen, einschließlich 64-Bit-Windows und MIPS.

  • Das Travis CI- und AppVeyor-Template Trust kann automatisch Binärversionen eines Rust-Projekts veröffentlichen. Trust kann für Linux, Windows und macOS bauen. Dabei sind nicht nur die Travis-CI- und AppVeyor-Services obligatorisch, sondern auch, dass Ihr Projekt auf GitHub gehostet wird.

  • Das Crossbuild-Projekt stellt ein Multi-Architektur-Docker-Image zur Verfügung, das für die Cross-Build-Erstellung zwischen allen drei großen Plattformen verwendet werden kann.

Mit Ausnahme von Cross wurden diese Tools schon über einen längeren Zeitraum nicht mehr aktualisiert (Stand: November 2022).

Mit anderen Rust-Projekten arbeiten

Ein Drittanbieter-Projekt auszuprobieren und lokal daran zu arbeiten, ist eine gute Möglichkeit, sich mit Rust vertraut zu machen. Der einfachste Weg, das zu tun: Erstellen Sie einen Git-Klon des Repositorys eines Rust-Projekts. Solange das Repository eine Cargo.toml-Datei in seinem Stammverzeichnis hat, wird es von Cargo erkannt.

Was Cargo (noch) nicht kann: Einen lokalen Klon eines Crates erstellen. Das ist aber mit Git möglich (das jeder, der ernsthaft mit Rust arbeiten will, ohnehin installiert haben sollte). Sie können diese Funktionalität über die (Drittanbieter-)Cargo-Subcommandos cargo-clone und cargo-clone-crate direkt hinzufügen.

Projekte zum Herumexperimentieren und Lernen finden Sie zum Beispiel im "Awesome Rust"-GitHub-Repository. Hier finden Sie auch das Servo-Webbrowser-Engine-Projekt, eine der ersten Rust-Applikationen in der echten Welt, wenn alles nach Plan läuft. Interessant ist auch das mdBook-Projekt.

Viele andere Projekte sind für sich genommen nützlich, nicht nur um Rust kennenzulernen oder weil sie Teil eines größeren Projekts sind. Dazu gehören:

  • Trust-DNS (ein DNS-Server und -Client),

  • Alacritty (ein GPU-gestützter Terminalemulator) und

  • die dezentrale Datenplattform MaidSafe.

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld. (fm)