rust rust-cargo

rust install dependencies



¿Paquete de óxido con una biblioteca y un binario? (4)

Puedes poner lib.rs y main.rs en la carpeta de fuentes juntos. No hay conflicto y la carga construirá ambas cosas.

Para resolver el conflicto de documentación, agregue a su Cargo.toml :

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

Me gustaría crear un paquete Rust que contenga una biblioteca reutilizable (donde se implementa la mayor parte del programa) y también un ejecutable que lo use.

Suponiendo que no haya confundido ninguna semántica en el sistema del módulo Rust, ¿cómo debería ser mi archivo Cargo.toml ?


También puede poner fuentes binarias en src/bin y el resto de sus fuentes en src . Puedes ver un ejemplo en mi proyecto . No necesita modificar su Cargo.toml en absoluto, y cada archivo de origen se compilará en un binario del mismo nombre.

La configuración de la otra respuesta se reemplaza por:

$ tree . ├── Cargo.toml └── src    ├── bin    │   └── mybin.rs    └── lib.rs

Cargo.toml

[package] name = "example" version = "0.0.1" authors = ["An Devloper <[email protected]>"]

src / lib.rs

use std::error::Error; pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> { Ok(a + b) }

src / bin / mybin.rs

extern crate example; fn main() { println!("I''m using the library: {:?}", example::really_complicated_code(1, 2)); }

Y ejecutarlo:

$ cargo run --bin mybin I''m using the library: Ok(3)

Además, simplemente puede crear un src/main.rs que se utilizará como ejecutable de facto. Desafortunadamente, esto entra en conflicto con el comando cargo doc cargo:

No se puede documentar un paquete donde una biblioteca y un binario tienen el mismo nombre. Considere cambiar el nombre de uno o marcar el objetivo como doc = false


Una solución alternativa es no intentar realmente agrupar ambas cosas en un solo paquete. Para proyectos un poco más grandes con un ejecutable amigable, me parece muy bueno usar un workspace

Creamos un proyecto binario que incluye una biblioteca dentro de él:

the-binary ├── Cargo.lock ├── Cargo.toml ├── mylibrary │   ├── Cargo.toml │   └── src │   └── lib.rs └── src └── main.rs

Cargo.toml

Esto usa la tecla [workspace] y depende de la biblioteca:

[package] name = "the-binary" version = "0.1.0" authors = ["An Devloper <[email protected]>"] [workspace] [dependencies] mylibrary = { path = "mylibrary" }

src / main.rs

extern crate mylibrary; fn main() { println!("I''m using the library: {:?}", mylibrary::really_complicated_code(1, 2)); }

mylibrary / src / lib.rs

use std::error::Error; pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> { Ok(a + b) }

Y ejecutarlo:

$ cargo run Compiling mylibrary v0.1.0 (file:///private/tmp/the-binary/mylibrary) Compiling the-binary v0.1.0 (file:///private/tmp/the-binary) Finished dev [unoptimized + debuginfo] target(s) in 0.73 secs Running `target/debug/the-binary` I''m using the library: Ok(3)

Hay dos grandes beneficios para este esquema:

  1. El binario ahora puede usar dependencias que solo se aplican a él. Por ejemplo, puede incluir muchas cajas para mejorar la experiencia del usuario, como los analizadores de línea de comandos o el formato de terminal. Ninguno de estos "infectará" la biblioteca.

  2. El espacio de trabajo evita construcciones redundantes de cada componente. Si ejecutamos cargo build tanto en el mylibrary como en the-binary directorio the-binary , la biblioteca no se construirá las dos veces, se comparte entre ambos proyectos.


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 <[email protected]>"] [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; use mylib::test; pub fn main() { test(); }