407 Stimmen

Paket mit sowohl einer Bibliothek als auch einer binären Datei?

Ich möchte ein Rust-Paket erstellen, das sowohl eine wiederverwendbare Bibliothek (in der der Großteil des Programms implementiert ist) als auch ein ausführbares Programm enthält.

Angenommen, ich habe keine Semantik im Rust-Modulsystem durcheinander gebracht, wie sollte meine Cargo.toml-Datei aussehen?

390voto

Doug Punkte 28922
Tok:tmp doug$ du -a

8   ./Cargo.toml
8   ./src/bin.rs
8   ./src/lib.rs
16  ./src

Cargo.toml:

[package]
name = "mything"
version = "0.0.1"
authors = ["me "]

[lib]
name = "mylib"
path = "src/lib.rs"

[[bin]]
name = "mybin"
path = "src/bin.rs"

src/lib.rs:

pub fn test() {
    println!("Test");
}

src/bin.rs:

extern crate mylib; // nicht erforderlich seit Rust Edition 2018

use mylib::test;

pub fn main() {
    test();
}

282voto

Shepmaster Punkte 324212

Einfach

Erstellen Sie eine src/main.rs, die als Standardausführbare Datei verwendet wird. Sie müssen Ihre Cargo.toml nicht ändern, und diese Datei wird zu einem Binärprogramm mit dem gleichen Namen wie die Bibliothek kompiliert.

Der Projektinhalt:

% tree
.
 Cargo.toml
 src
     lib.rs
     main.rs

Cargo.toml

[package]
name = "example"
version = "0.1.0"
edition = "2018"

src/lib.rs

use std::error::Error;

pub fn really_complicated_code(a: u8, b: u8) -> Result> {
    Ok(a + b)
}

src/main.rs

fn main() {
    println!(
        "Ich verwende die Bibliothek: {:?}",
        example::really_complicated_code(1, 2)
    );
}

Und führen Sie es aus:

% cargo run -q
Ich verwende die Bibliothek: Ok(3)

Flexibel

Wenn Sie den Namen des Binärprogramms kontrollieren oder mehrere Binärdateien haben möchten, können Sie mehrere Binärquellendateien in src/bin erstellen und den Rest Ihrer Bibliotheksquellen in src. Sie können ein Beispiel in meinem Projekt sehen. Sie müssen Ihre Cargo.toml überhaupt nicht ändern, und jede Quelldatei in src/bin wird zu einem Binärprogramm mit dem gleichen Namen kompiliert.

Der Projektinhalt:

% tree
.
 Cargo.toml
 src
     bin
        mybin.rs
     lib.rs

Cargo.toml

[package]
name = "example"
version = "0.1.0"
edition = "2018"

src/lib.rs

use std::error::Error;

pub fn really_complicated_code(a: u8, b: u8) -> Result> {
    Ok(a + b)
}

src/bin/mybin.rs

fn main() {
    println!(
        "Ich verwende die Bibliothek: {:?}",
        example::really_complicated_code(1, 2)
    );
}

Und führen Sie es aus:

% cargo run --bin mybin -q
Ich verwende die Bibliothek: Ok(3)

Siehe auch:

122voto

Shepmaster Punkte 324212

Eine alternative Lösung besteht darin, nicht zu versuchen, beide Dinge in ein Paket zu quetschen. Für etwas größere Projekte mit einem freundlichen Executable habe ich es sehr schön gefunden, ein Workspace zu verwenden.

Hier erstelle ich ein Binärprojekt, das eine Bibliothek darin enthält, aber es gibt viele mögliche Arten, den Code zu organisieren:

 % tree the-binary
the-binary
 Cargo.toml
 src
    main.rs
 the-library
     Cargo.toml
     src
         lib.rs

Cargo.toml

Dies verwendet den [workspace] Schlüssel und hängt von der Bibliothek ab:

[package]
name = "the-binary"
version = "0.1.0"
edition = "2018"

[workspace]

[dependencies]
the-library = { path = "the-library" }

src/main.rs

fn main() {
    println!(
        "Ich verwende die Bibliothek: {:?}",
        the_library::really_complicated_code(1, 2)
    );
}

the-library/Cargo.toml

[package]
name = "the-library"
version = "0.1.0"
edition = "2018"

the-library/src/lib.rs

use std::error::Error;

pub fn really_complicated_code(a: u8, b: u8) -> Result> {
    Ok(a + b)
}

Und führen Sie es aus:

% cargo run -q
Ich verwende die Bibliothek: Ok(3)

Es gibt zwei große Vorteile dieses Schemas:

  1. Das Binär kann jetzt Abhängigkeiten verwenden, die nur auf es zutreffen. Zum Beispiel können Sie viele Crates einschließen, um die Benutzererfahrung zu verbessern, wie z.B. Command-Line-Parser oder Terminalformatierung. Keines davon wird die Bibliothek "infizieren".

  2. Das Workspace verhindert redundante Builds jedes Komponenten. Wenn wir cargo build sowohl im Verzeichnis the-library als auch im Verzeichnis the-binary ausführen, wird die Bibliothek nicht beide Male gebaut - sie wird zwischen beiden Projekten geteilt.

26voto

DenisKolodin Punkte 10678

Sie können lib.rs und main.rs gemeinsam in den Quellordner legen. Es gibt keinen Konflikt und Cargo wird beide Dinge erstellen.

Um den Dokumentationskonflikt zu lösen, fügen Sie Ihrem Cargo.toml Folgendes hinzu:

[[bin]]
name = "main"
doc = false

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X