带有库和二进制文件的Rust包?

时间:2014-11-15 14:04:30

标签: rust rust-cargo

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

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

4 个答案:

答案 0 :(得分:121)

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 <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;

use mylib::test;

pub fn main() {
    test();
}

答案 1 :(得分:98)

您也可以将二进制来源放在src/bin中,将其余来源放在src中。您可以在my project中看到一个示例。您根本不需要修改Cargo.toml,每个源文件将被编译为同名的二进制文件。

然后将另一个答案的配置替换为:

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

<强> Cargo.toml

[package]
name = "example"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]

<强>的src / lib.rs

use std::error::Error;

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

<强>的src /斌/ 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即可。不幸的是,这与cargo doc命令冲突:

  

无法记录库和二进制文件具有相同名称的包。考虑重命名一个或将目标标记为doc = false

答案 2 :(得分:18)

另一种解决方案是实际上不尝试将两个东西塞进一个包中。对于具有友好可执行文件的稍大的项目,我发现使用workspace

非常好

我们创建一个二进制项目,其中包含一个库:

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 <an.devloper@example.com>"]

[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. 二进制文件现在可以使用仅适用于它的依赖项。例如,您可以包含许多包以改善用户体验,例如命令行解析器或终端格式。这些都不会感染&#34;图书馆。

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

答案 3 :(得分:17)

您可以将lib.rsmain.rs放在源文件夹中。 没有冲突,货物将构建两件事。

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

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