Подтвердить что ты не робот

Пакет ржавчины с библиотекой и двоичным?

Я хотел бы сделать пакет Rust, содержащий как многократно используемую библиотеку (где большая часть программы реализована), так и исполняемый файл, который его использует.

Предполагая, что я не путал какую-либо семантику в модульной системе Rust, должен ли выглядеть файл Cargo.toml?

4b9b3361

Ответ 1

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; // not needed since Rust edition 2018

use mylib::test;

pub fn main() {
    test();
}

Ответ 2

Вы также можете просто поместить двоичные источники в src/bin а остальные источники - в src. Вы можете увидеть пример в моем проекте. Вам вообще не нужно изменять ваш Cargo.toml, и каждый исходный файл будет скомпилирован в двоичный файл с тем же именем.

Затем конфигурация других ответов заменяется на:

$ 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)
}

ЦСИ /bin/mybin.rs

extern crate example;

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

И выполнить это:

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

Кроме того, вы можете просто создать src/main.rs который будет использоваться в качестве исполняемого файла defacto. К сожалению, это конфликтует с командой cargo doc:

Невозможно задокументировать пакет, в котором библиотека и двоичный файл имеют одинаковые имена. Подумайте о переименовании или пометке цели как doc = false

Ответ 3

Альтернативное решение - на самом деле не пытаться собрать обе вещи в один пакет. Для проектов немного больших размеров с дружественным исполняемым файлом я нахожу очень полезным использовать рабочее пространство

Мы создаем бинарный проект, который включает в себя библиотеку:

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

Cargo.toml

Это использует ключ [workspace] и зависит от библиотеки:

[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)
}

И выполнить это:

$ 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)

У этой схемы есть два больших преимущества:

  1. Двоичный файл теперь может использовать зависимости, которые применяются только к нему. Например, вы можете включить множество ящиков для улучшения взаимодействия с пользователем, таких как анализаторы командной строки или форматирование терминала. Ни один из них не "заразит" библиотеку.

  2. Рабочая область предотвращает избыточные сборки каждого компонента. Если мы запустим cargo build как в mylibrary и the-binary каталоге, библиотека не будет собрана оба раза - она будет разделена между обоими проектами.

Ответ 4

Вы можете поместить lib.rs и main.rs в папку источников вместе. Нет конфликта, и груз будет строить обе вещи.

Чтобы разрешить конфликт documentaion, добавьте в свой Cargo.toml:

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