Cargo 是 Rust 软件包管理器。Cargo 可以下载 Rust 软件包的依赖项、编译软件包、制作可分发的软件包,并将它们上传到 Rust 社区的软件包注册中心(Package Registry ) 。
0x01. 快速上手 1.1 创建二进制项目
1 2 3 4 5 6 7 8 9 cd hello_world/tree .
1 2 3 4 fn main () { println! ("Hello, world!" ); }
1 2 3 4 5 6 7 // cat Cargo.toml [package] name = "hello_world" version = "0.1.0" edition = "2021" [dependencies]
1.2 创建依赖库项目 1 cargo new hello_world --lib
1 2 3 4 5 6 7 8 9 cd hello_world/tree .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 pub fn add (left: u64 , right: u64 ) -> u64 { left + right } #[cfg(test)] mod tests { use super::*; #[test] fn it_works () { let result = add (2 , 2 ); assert_eq! (result, 4 ); } }
1 2 3 4 5 6 7 // Cargo.toml [package] name = "hello_world" version = "0.1.0" edition = "2021" [dependencies]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 cargo test
1.3 下载项目并构建 1 2 3 4 5 6 7 8 9 10 git clone https://github.com/rust-lang/regex.git cd regex
0x02. 核心概念 2.1 Module
模块(Module):可以用来将代码分层地拆分为逻辑单元(模块),并管理它们之间的可见性(公共/私有)
模块中包含:函数、结构、特征、实现块,甚至其他模块。
一个文件可以多个模块,也可以一个文件一个模块,模块可以被认为是真实项目中的代码组织单元
2.2 Crate
板条箱 (Crate) 是 Rust 中的编译单元 。
2.3 Package
包(package)是一个包含一个或多个 crate 的集合,用于提供一组功能。
一个包(package)包含一个 Cargo.toml
文件,该文件描述了如何构建这些 crate。
一个包(package)可以包含任意多个二进制 crate,但最多只能包含一个库 crate。
一个包(package)必须至少包含一个 crate,无论是库 crate 还是二进制 crate。
2.3.1 Package 目录布局 Cargo 使用约定来放置文件,以便轻松进入新的 Cargo Package
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 . ├── Cargo.lock ├── Cargo.toml ├── src/ │ ├── lib.rs │ ├── main.rs │ └── bin/ │ ├── named-executable.rs │ ├── another-executable.rs │ └── multi-file-executable/ │ ├── main.rs │ └── some_module.rs ├── benches/ │ ├── large-input.rs │ └── multi-file-bench/ │ ├── main.rs │ └── bench_module.rs ├── examples/ │ ├── simple.rs │ └── multi-file-example/ │ ├── main.rs │ └── ex_module.rs └── tests/ ├── some-integration-tests.rs └── multi-file-test/ ├── main.rs └── test_module.rs
Cargo.toml
和 Cargo.lock
存储在包的根目录中(包根目录)。
源代码放在 src
目录中。
默认库文件是 src/lib.rs
。
默认可执行文件是 src/main.rs
。
基准测试放在 benches
目录中。
示例放在 examples
目录中。
集成测试放在 tests
目录中。
2.4 Workspace 工作区(Workspace)是一个或多个包(Package)的集合,这些包称为工作区成员,它们一起进行管理。
0x03. 基础包管理 3.1 包含一个 crate
1 2 3 4 5 6 7 8 9 cd hello_world/tree .
1 2 3 4 5 6 7 8 9 cd hello_world/tree .
3.2 包含多个 crate 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 cargo new mutil_crate --lib mkdir src/binvim src/bin/main1.rs vim src/bin/main2.rs tree . . ├── Cargo.toml └── src ├── bin │ ├── main1.rs │ └── main2.rs └── lib.rs 3 directories, 4 files cargo run --bin main1 cargo test --lib
0x04. 进阶工作空间 工作区是一个或多个包的集合,这些包称为工作区成员,它们一起进行管理。
4.1 功能要点
通用命令可以在所有工作区成员中运行,例如 cargo check --workspace
。
所有包共享一个位于工作区根目录中的通用 Cargo.lock
文件。
所有包共享一个通用输出目录,该目录默认为工作区根目录中名为 target
的目录。
共享包元数据,例如与 workspace.package
。
Cargo.toml
中的 [patch]
、[replace]
和 [profile.*]
部分仅在根清单中被识别,并在成员包的清单中被忽略。
4.2 支持配置 工作区的根 Cargo.toml
支持以下部分:
[workspace] — 定义工作区。
resolver — 设置要使用的依赖项解析器。
members — 工作区中要包含的软件包。
exclude — 从工作区中排除的软件包。
default-members — 未选择特定软件包时要操作的软件包。
package — 软件包中用于继承的键。
dependency — 软件包依赖项中用于继承的键。
lints — 软件包 lints 中用于继承的键。
metadata — 外部工具的额外设置。
[patch] — 覆盖依赖项。
[replace] — 覆盖依赖项(已弃用)。
[profile] — 编译器设置和优化。
4.3 创建工作空间 工作区至少必须有一个成员,要么是根包,要么是虚拟清单。
要创建工作区,请将 [workspace]
表添加到 Cargo.toml
:
4.3.1 有根 Package 的工作空间 如果在已经定义 [package]
的 Cargo.toml
中添加了 [workspace]
部分,则该包是工作区的根包。工作区根目录是工作区的 Cargo.toml
所在的目录。
1 2 3 4 5 6 7 [workspace] [package] name = "hello_world" version = "0.1.0" authors = ["Alice <a@example.com>" , "Bob <b@example.com>" ]
4.3.2 虚拟工作空间 或者,可以创建一个包含 [workspace]
部分但不包含 [package]
部分的 Cargo.toml
文件。这称为虚拟清单。当没有“主”包或您希望将所有包组织在单独的目录中时,这通常很有用。
1 2 3 4 [workspace] members = ["hello_world" ] resolver = "2"
1 2 3 4 5 6 7 [package] name = "hello_world" version = "0.1.0" edition = "2021" authors = ["Alice <a@example.com>" , "Bob <b@example.com>" ]
必须在虚拟工作区中明确设置解析器,因为它们没有 package.edition
来从解析器版本推断它。
默认情况下,在工作区根目录中运行的命令将针对所有工作区成员运行,请参阅 default-members
。
4.4 小结
创建工作空间就是在 Cargo.toml
中添加了 [workspace]
部分。
成员 Package
对 Workspace
的数据继承。
cargo
通用命令可以对空间成员进行统一管理。
具体 [workspace]
部分配置,详情请查看官方指南: Workspaces