工作空间
工作空间 是一个或多个包的集合,称为 工作空间成员,它们一起管理。
工作空间的关键点是
- 通用命令可以跨所有工作空间成员运行,例如
cargo check --workspace
。 - 所有包共享一个通用的
Cargo.lock
文件,该文件位于 工作空间根目录 中。 - 所有包共享一个通用的 输出目录,默认为 工作空间根目录 中名为
target
的目录。 - 共享包元数据,例如使用
workspace.package
。 Cargo.toml
中的[patch]
、[replace]
和[profile.*]
部分仅在 根 清单中识别,而在成员 crates 的清单中被忽略。
工作空间的根 Cargo.toml
支持以下部分
[workspace]
— 定义工作空间。resolver
— 设置要使用的依赖项解析器。members
— 要包含在工作空间中的包。exclude
— 要从工作空间中排除的包。default-members
— 未选择特定包时要操作的包。package
— 包中要继承的键。dependencies
— 包依赖项中要继承的键。lints
— 包 lint 中要继承的键。metadata
— 外部工具的额外设置。
[patch]
— 覆盖依赖项。[replace]
— 覆盖依赖项(已弃用)。[profile]
— 编译器设置和优化。
[workspace]
部分
要创建工作空间,请将 [workspace]
表添加到 Cargo.toml
[workspace]
# ...
至少,工作空间必须有一个成员,可以是带有根包的成员,也可以是虚拟清单。
根包
如果将 [workspace]
部分 添加到已定义 [package]
的 Cargo.toml
中,则该包是工作空间的 根包。工作空间根目录 是工作空间的 Cargo.toml
所在的目录。
[workspace]
[package]
name = "hello_world" # the name of the package
version = "0.1.0" # the current version, obeying semver
authors = ["Alice <[email protected]>", "Bob <[email protected]>"]
虚拟工作空间
或者,可以使用 [workspace]
部分但没有 [package]
部分 来创建 Cargo.toml
文件。这称为 虚拟清单。当没有“主要”包,或者您想将所有包组织在单独的目录中时,这通常很有用。
# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["hello_world"]
resolver = "2"
# [PROJECT_DIR]/hello_world/Cargo.toml
[package]
name = "hello_world" # the name of the package
version = "0.1.0" # the current version, obeying semver
edition = "2021" # the edition, will have no effect on a resolver used in the workspace
authors = ["Alice <[email protected]>", "Bob <[email protected]>"]
通过拥有没有根包的工作空间,
- 必须在虚拟工作空间中显式设置
resolver
,因为它们没有package.edition
来从 解析器版本 推断它。 - 默认情况下,在工作空间根目录中运行的命令将针对所有工作空间成员运行,请参阅
default-members
。
members
和 exclude
字段
members
和 exclude
字段定义哪些包是工作空间的成员
[workspace]
members = ["member1", "path/to/member2", "crates/*"]
exclude = ["crates/foo", "path/to/other"]
位于工作空间目录中的所有 path
依赖项 自动成为成员。可以使用 members
键列出其他成员,该键应该是一个字符串数组,其中包含带有 Cargo.toml
文件的目录。
members
列表还支持 globs 来匹配多个路径,使用典型的文件名 glob 模式,如 *
和 ?
。
exclude
键可用于防止路径包含在工作空间中。如果某些路径依赖项根本不需要在工作空间中,或者使用 glob 模式并且您想删除目录,这将很有用。
当位于工作空间内的子目录中时,Cargo 将自动搜索父目录中是否存在带有 [workspace]
定义的 Cargo.toml
文件,以确定要使用哪个工作空间。成员 crates 中可以使用 package.workspace
清单键指向工作空间的根目录,以覆盖此自动搜索。如果成员不在工作空间根目录的子目录中,则手动设置可能很有用。
包选择
在工作空间中,与包相关的 Cargo 命令(如 cargo build
)可以使用 -p
/ --package
或 --workspace
命令行标志来确定要操作的包。如果未指定这些标志,Cargo 将使用当前工作目录中的包。但是,如果当前目录是工作空间根目录,则将使用 default-members
。
default-members
字段
default-members
字段指定在工作空间根目录中且未使用包选择标志时要操作的 成员 的路径
[workspace]
members = ["path/to/member1", "path/to/member2", "path/to/member3/*"]
default-members = ["path/to/member2", "path/to/member3/foo"]
注意:当存在 根包 时,您只能使用
--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
是相对于包根目录的
示例
# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["bar"]
[workspace.package]
version = "1.2.3"
authors = ["Nice Folks"]
description = "A short description of my package"
documentation = "https://example.com/bar"
# [PROJECT_DIR]/bar/Cargo.toml
[package]
name = "bar"
version.workspace = true
authors.workspace = true
description.workspace = true
documentation.workspace = true
dependencies
表
workspace.dependencies
表是您定义工作空间成员要继承的依赖项的地方。
指定工作空间依赖项类似于 包依赖项,除了
- 此表中的依赖项不能声明为
optional
- 此表中声明的
features
与[dependencies]
中的features
相加
然后,您可以 将工作空间依赖项继承为包依赖项
示例
# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["bar"]
[workspace.dependencies]
cc = "1.0.73"
rand = "0.8.5"
regex = { version = "1.6.0", default-features = false, features = ["std"] }
# [PROJECT_DIR]/bar/Cargo.toml
[package]
name = "bar"
version = "0.2.0"
[dependencies]
regex = { workspace = true, features = ["unicode"] }
[build-dependencies]
cc.workspace = true
[dev-dependencies]
rand.workspace = true
lints
表
workspace.lints
表是您定义工作空间成员要继承的 lint 配置的地方。
指定工作空间 lint 配置类似于 包 lint。
示例
# [PROJECT_DIR]/Cargo.toml
[workspace]
members = ["crates/*"]
[workspace.lints.rust]
unsafe_code = "forbid"
# [PROJECT_DIR]/crates/bar/Cargo.toml
[package]
name = "bar"
version = "0.1.0"
[lints]
workspace = true
metadata
表
Cargo 会忽略 workspace.metadata
表,并且不会发出警告。此部分可供希望在 Cargo.toml
中存储工作区配置的工具使用。例如
[workspace]
members = ["member1", "member2"]
[workspace.metadata.webcontents]
root = "path/to/webproject"
tool = ["npm", "run", "build"]
# ...
在 package.metadata
的包级别有一组类似的表。虽然 Cargo 没有为这两个表的任何一个指定内容格式,但建议外部工具可以考虑以一致的方式使用它们,例如在 package.metadata
中缺少数据时参考 workspace.metadata
中的数据,如果这对相关工具有意义的话。