And*_*ner 132 rust rust-cargo
我想制作一个包含可重用库(实现大部分程序)的Rust包,以及使用它的可执行文件.
假设我没有混淆Rust模块系统中的任何语义,我的Cargo.toml文件应该是什么样的?
Dou*_*oug 152
Tok:tmp doug$ du -a
8 ./Cargo.toml
8 ./src/bin.rs
8 ./src/lib.rs
16 ./src
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
SRC/lib.rs:
pub fn test() {
println!("Test");
}
Run Code Online (Sandbox Code Playgroud)
SRC/bin.rs:
extern crate mylib; // not needed since Rust edition 2018
use mylib::test;
pub fn main() {
test();
}
Run Code Online (Sandbox Code Playgroud)
She*_*ter 112
您也可以将二进制源src/bin和其他源放入其中src.您可以在我的项目中看到一个示例.您根本不需要修改Cargo.toml,每个源文件将被编译为同名的二进制文件.
然后将另一个答案的配置替换为:
$ tree
.
??? Cargo.toml
??? src
??? bin
? ??? mybin.rs
??? lib.rs
Run Code Online (Sandbox Code Playgroud)
Cargo.toml
[package]
name = "example"
version = "0.0.1"
authors = ["An Devloper <an.devloper@example.com>"]
Run Code Online (Sandbox Code Playgroud)
SRC/lib.rs
use std::error::Error;
pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> {
Ok(a + b)
}
Run Code Online (Sandbox Code Playgroud)
SRC /斌/ mybin.rs
extern crate example;
fn main() {
println!("I'm using the library: {:?}", example::really_complicated_code(1, 2));
}
Run Code Online (Sandbox Code Playgroud)
并执行它:
$ cargo run --bin mybin
I'm using the library: Ok(3)
Run Code Online (Sandbox Code Playgroud)
此外,您可以创建一个src/main.rs将用作事实可执行文件的程序.不幸的是,这与cargo doc命令冲突:
无法记录库和二进制文件具有相同名称的包.考虑重命名一个或将目标标记为
doc = false
She*_*ter 26
另一种解决方案是实际上不尝试将两个东西塞进一个包中.对于具有友好可执行文件的稍大的项目,我发现使用工作区非常好
我们创建一个二进制项目,其中包含一个库:
the-binary
??? Cargo.lock
??? Cargo.toml
??? mylibrary
? ??? Cargo.toml
? ??? src
? ??? lib.rs
??? src
??? main.rs
Run Code Online (Sandbox Code Playgroud)
Cargo.toml
这使用[workspace]密钥并依赖于库:
[package]
name = "the-binary"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]
[workspace]
[dependencies]
mylibrary = { path = "mylibrary" }
Run Code Online (Sandbox Code Playgroud)
SRC/main.rs
extern crate mylibrary;
fn main() {
println!("I'm using the library: {:?}", mylibrary::really_complicated_code(1, 2));
}
Run Code Online (Sandbox Code Playgroud)
在MyLibrary/SRC/lib.rs
use std::error::Error;
pub fn really_complicated_code(a: u8, b: u8) -> Result<u8, Box<Error>> {
Ok(a + b)
}
Run Code Online (Sandbox Code Playgroud)
并执行它:
$ 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)
Run Code Online (Sandbox Code Playgroud)
这个方案有两大好处:
二进制文件现在可以使用仅适用于它的依赖项.例如,您可以包含许多包以改善用户体验,例如命令行解析器或终端格式.这些都不会"感染"图书馆.
工作空间可防止每个组件的冗余构建.如果我们cargo build同时在mylibrary和the-binary目录中运行,那么两次都不会构建库 - 它在两个项目之间共享.
Den*_*din 17
你可以把lib.rs和main.rs到sources文件夹在一起.没有冲突,货物将构建两件事.
要解决文档冲突,请添加到您的Cargo.toml:
[[bin]]
name = "main"
doc = false
Run Code Online (Sandbox Code Playgroud)