303

我想制作一个 Rust 包,其中包含一个可重用的库(大部分程序都在其中实现),以及一个使用它的可执行文件。

假设我没有混淆 Rust 模块系统中的任何语义,我的Cargo.toml文件应该是什么样的?

4

4 回答 4

306
Tok:tmp doug$ du -a

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

货物.toml:

[package]
name = "mything"
version = "0.0.1"
authors = ["me <me@gmail.com>"]

[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();
}
于 2014-11-15T14:11:34.303 回答
215

简单的

创建一个src/main.rs将用作事实上的可执行文件。您不需要修改您的Cargo.toml文件,该文件将被编译为与库同名的二进制文件。

项目内容:

% tree
.
├── Cargo.toml
└── src
    ├── lib.rs
    └── main.rs

货运.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<u8, Box<dyn Error>> {
    Ok(a + b)
}

src/main.rs

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

并执行它:

% cargo run -q
I'm using the library: Ok(3)

灵活的

如果您希望控制二进制文件的名称或拥有多个二进制文件,您可以src/binsrc. 您可以在我的项目中看到一个示例。你根本不需要修改你Cargo.toml的,每个源文件src/bin都会被编译成同名的二进制文件。

项目内容:

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

货运.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<u8, Box<dyn Error>> {
    Ok(a + b)
}

src/bin/mybin.rs

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

并执行它:

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

也可以看看:

于 2014-11-16T03:10:29.503 回答
85

另一种解决方案是不要试图将这两种东西都塞进一个包中。对于具有友好可执行文件的稍微大一点的项目,我发现使用工作区非常好。

在这里,我创建了一个二进制项目,其中包含一个库,但是有许多可能的方法来组织代码:

 % tree the-binary
the-binary
├── Cargo.toml
├── src
│   └── main.rs
└── the-library
    ├── Cargo.toml
    └── src
        └── lib.rs

货运.toml

这使用[workspace]密钥并取决于库:

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

[workspace]

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

src/main.rs

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

图书馆/Cargo.toml

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

图书馆/src/lib.rs

use std::error::Error;

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

并执行它:

% cargo run -q
I'm using the library: Ok(3)

该计划有两大好处:

  1. 二进制文件现在可以使用仅适用于它的依赖项。例如,您可以包含许多 crate 来改善用户体验,例如命令行解析器或终端格式化。这些都不会“感染”图书馆。

  2. 工作区可防止每个组件的冗余构建。如果我们cargo build同时在the-librarythe-binary目录中运行,则不会两次都构建库——它在两个项目之间共享。

于 2018-05-18T01:48:01.063 回答
24

您可以将lib.rsmain.rs源文件夹放在一起。没有冲突,货物将建立这两个东西。

要解决文档冲突,请添加到您的Cargo.toml

[[bin]]
name = "main"
doc = false
于 2015-10-03T11:04:33.500 回答