02-工作空间
4 分钟阅读
译文 · 基于 The Cargo Book
工作空间
原文链接: https://doc.rust-lang.org/cargo/reference/workspaces.html
工作空间(workspace) 是一个或多个包的集合,这些包称为 工作空间成员(workspace members),被一起管理。
工作空间的要点是:
- 常用命令可跨所有工作空间成员运行,例如
cargo check --workspace。 - 所有包共享一份位于 工作空间根 的公共
Cargo.lock文件。 - 所有包共享一个公共[输出目录],默认是 工作空间根 下名为
target的目录。 - 可共享包元数据,例如通过
workspace.package。 Cargo.toml中的[patch]、[replace]与[profile.*]节仅在 根 清单中被识别,成员 crate 清单中的会被忽略。
工作空间的根 Cargo.toml 支持以下节:
[workspace]—— 定义工作空间。resolver—— 设置要使用的依赖解析器。members—— 要包含在工作空间中的包。exclude—— 要从工作空间中排除的包。default-members—— 未选择特定包时要操作的包。package—— 供包继承的键。dependencies—— 供包依赖继承的键。lints—— 供包 lint 继承的键。metadata—— 供外部工具使用的额外设置。
[patch]—— 覆盖依赖。[replace]—— 覆盖依赖(已弃用)。[profile]—— 编译器设置与优化。
[workspace] 节
要创建工作空间,向 Cargo.toml 添加 [workspace] 表:
| |
工作空间至少要有一个成员,可以是根包,也可以是虚拟清单。
根包
若将 [workspace] 节 添加到已定义 [package] 的 Cargo.toml,则该包是工作空间的 根包。工作空间根 是工作空间 Cargo.toml 所在的目录。
| |
虚拟工作空间
或者,可以创建带有 [workspace] 节但不含 [package] 节 的 Cargo.toml 文件。这称为 虚拟清单(virtual manifest)。当没有「主」包,或你希望将所有包组织在独立目录中时,这通常很有用。
| |
| |
通过使用没有根包的工作空间,
- 虚拟工作空间中必须显式设置
resolver,因为它们没有可用于推断解析器版本的package.edition。 - 在工作空间根运行的命令默认会对所有工作空间成员运行,见
default-members。
members 与 exclude 字段
members 与 exclude 字段定义哪些包是工作空间的成员:
| |
位于工作空间目录中的所有 [path 依赖]会自动成为成员。可用 members 键列出额外成员,它应是包含带有 Cargo.toml 文件的目录的字符串数组。
members 列表还支持 glob 以匹配多条路径,使用典型的文件名 glob 模式如 * 与 ?。
建议: 将所有成员包放在扁平目录中(通常为 crates/),
并为 members 字段使用 glob 模式,例如
members = ["crates/*"]。这可最大限度地减少维护 members 列表的变动。
exclude 键可用于阻止路径被包含在工作空间中。若某些 path 依赖完全不希望加入工作空间,或在使用 glob 模式时想移除某个目录,这会很有用。
当位于工作空间内的子目录中时,Cargo 会自动向上搜索父目录中带有 [workspace] 定义的 Cargo.toml 文件,以确定使用哪个工作空间。成员 crate 中可使用 package.workspace 清单键指向工作空间根,以覆盖此自动搜索。若成员不在工作空间根的子目录内,手动设置会很有用。
包选择
在工作空间中,像 cargo build 这样与包相关的 Cargo 命令可使用 -p / --package 或 --workspace 命令行标志来确定要对哪些包操作。若未指定这些标志,Cargo 将使用当前工作目录中的包。然而,若当前目录是工作空间根,则将使用 default-members。
default-members 字段
default-members 字段指定:当位于工作空间根且未使用包选择标志时,要操作的成员路径:
| |
注意:当存在根包时, 只能使用
--package与--workspace标志对其进行操作。
未指定时,将使用根包。
对于虚拟工作空间,将使用所有成员
(如同在命令行上指定了 --workspace)。
package 表
workspace.package 表用于定义可由工作空间成员继承的键。成员包可通过以 {key}.workspace = true 定义这些键来继承它们。
支持的键:
authors | categories |
description | documentation |
edition | exclude |
homepage | include |
keywords | license |
license-file | publish |
readme | repository |
rust-version | version |
license-file与readme相对于工作空间根include与exclude相对于你的包根
示例:
| |
| |
MSRV: 需要 1.64+
dependencies 表
workspace.dependencies 表用于定义可由工作空间成员继承的依赖。
指定工作空间依赖与包依赖类似,但有以下区别:
- 此表中的依赖不能声明为
optional - 此表中声明的
features与[dependencies]中的features是累加的
然后你可以将工作空间依赖继承为包依赖
示例:
| |
| |
MSRV: 需要 1.64+
lints 表
workspace.lints 表用于定义可由工作空间成员继承的 lint 配置。
指定工作空间 lint 配置与包 lint 类似。
示例:
| |
| |
MSRV: 自 1.74 起生效
metadata 表
workspace.metadata 表会被 Cargo 忽略,且不会发出警告。本节可供希望在 Cargo.toml 中存储工作空间配置的工具使用。例如:
| |
包级别也有类似的一组表:
package.metadata。虽然 Cargo 并未规定这两个表内容的格式,但建议外部工具以一致的方式使用它们,例如在 package.metadata 缺少数据时引用 workspace.metadata 中的数据(若对该工具合理)。