Wie erstelle ich mehrere Binärdateien mit Cargo, ohne die Leistung zu verlieren?
\n\nHaben Sie jemals die Situation erlebt, in der Ihr Rust-Projekt so stark wächst, dass eine einzige Binärdatei nicht mehr ausreicht? Vielleicht schreiben Sie ein CLI-Tool, das separate ausführbare Dateien für verschiedene Aufgaben haben soll: eine für die Datenanalyse, eine andere für die Berichterstellung, eine dritte für die Interaktion mit einer API. Oder Sie entwickeln eine Serveranwendung, bei der Sie Überwachung, Anfrageverarbeitung und Hintergrundaufgaben trennen müssen.
\n\nDie Frage "How can I build multiple binaries with Cargo?" ist eine der beliebtesten auf Stack Overflow unter Rust-Entwicklern. Und das nicht ohne Grund. Wenn ein Projekt über das einfache "Hello, World!" hinausgeht, wird die Fähigkeit, den Build mehrerer Binärdateien geschickt zu organisieren, zu einer entscheidenden Fähigkeit. Aber wie macht man das, ohne Leistungseinbußen? Wie vermeidet man Code-Duplizierung und verlangsamt die Kompilierung nicht?
\n\nIn diesem Artikel beantworten wir nicht nur diese Frage – wir zeigen Ihnen, wie Sie den Build mehrerer Binärdateien von einem Problem in ein leistungsstarkes Optimierungswerkzeug verwandeln. Sie erfahren mehr über Best Practices, Leistung und sogar geheime Tricks von Cargo, die erfahrene Rust-Entwickler verwenden.
\n\nWarum mehrere Binärdateien? Das Problem einer einzigen ausführbaren Datei
\n\nStellen Sie sich vor: Sie haben eine hervorragende Bibliothek für die Datenverarbeitung geschrieben. Dann haben Sie ein CLI-Interface hinzugefügt. Dann einen Webserver. Dann einen Aufgabenplaner. Alles in einem Projekt. Das Ergebnis? Ein Monolith, der:
\n\n- \n
- Ewig kompiliert, selbst wenn Sie nur eine einzige Zeile im CLI ändern. \n
- Einen Neustart der gesamten Anwendung erfordert, wenn eine Komponente aktualisiert wird. \n
- Schwer zu testen und bereitzustellen ist. \n
Die Lösung: Teilen Sie das Projekt in mehrere Binärdateien auf. Aber wie macht man das richtig in Rust?
\n\nGrundlagen: Cargo.toml und der Abschnitt [[bin]]
\n\nDer einfachste Weg ist, mehrere Binärziele in Ihrer Cargo.toml zu deklarieren. Lassen Sie uns ein einfaches Beispiel durchgehen.
// Cargo.toml\n[package]\nname = "my_project"\nversion = "0.1.0"\nedition = "2021"\n\n[[bin]]\nname = "analyzer"\npath = "src/bin/analyzer.rs"\n\n[[bin]]\nname = "reporter"\npath = "src/bin/reporter.rs"\n\n[[bin]]\nname = "server"\npath = "src/bin/server.rs"\n\n[dependencies]\nserde = { version = "1.0", features = ["derive"] }\ntokio = { version = "1", features = ["full"] }\n\n\nJetzt haben Sie im Ordner src/bin/ drei Dateien: analyzer.rs, reporter.rs und server.rs. Jede davon ist eine vollwertige Binärdatei mit eigener main()-Funktion.
Um alle auf einmal zu erstellen:
\ncargo build --release\n\nOder eine bestimmte Binärdatei:
\ncargo build --release --bin analyzer\n\nEinfach? Ja. Aber darin liegt der Haken. Wenn Sie den Build nicht optimieren, wird jede Binärdatei neu kompiliert, selbst wenn sie dieselben Abhängigkeiten verwenden. Und das ist der direkte Weg zu Leistungseinbußen.
\n\nOptimierung der Build-Leistung: Cargo-Profile
\n\nDas Geheimnis eines effizienten Builds mehrerer Binärdateien liegt in den Cargo-Profilen. Dies ist ein leistungsstarkes Werkzeug, mit dem Sie Kompilierungsparameter für verschiedene Szenarien anpassen können.
\n\nBasisprofile: dev und release
\n\nStandardmäßig verwendet Cargo zwei Profile: dev (für die Entwicklung) und release (für die Produktion). Sie können jedoch Ihre eigenen Profile erstellen oder vorhandene modifizieren.
// Cargo.toml\n[profile.release]\nopt-level = 3 # Maximale Code-Optimierung\nlto = "fat" # Link-Time Optimization (Zusammenführen aller Crates)\ncodegen-units = 1 # Ein Codegen-Thread für bessere Optimierung\nstrip = true # Entfernen von Debug-Informationen\n\n\nDiese Einstellungen sind besonders wichtig für Binärdateien, die schnell arbeiten müssen. Aber es gibt einen Haken: Je aggressiver