Workspaces - The Cargo Book (original) (raw)

The Cargo Book

Workspaces

A workspace is a collection of one or more packages, called workspace members, that are managed together.

The key points of workspaces are:

The root Cargo.toml of a workspace supports the following sections:

The [workspace] section

To create a workspace, you add the [workspace] table to a Cargo.toml:

[workspace]
# ...

At minimum, a workspace has to have a member, either with a root package or as a virtual manifest.

Root package

If the [workspace] section is added to aCargo.toml that already defines a [package], the package is the root package of the workspace. The workspace root is the directory where the workspace’s Cargo.toml is located.

[workspace]

[package]
name = "hello_world" # the name of the package
version = "0.1.0"    # the current version, obeying semver

Virtual workspace

Alternatively, a Cargo.toml file can be created with a [workspace] section but without a [package] section. This is called a virtual manifest. This is typically useful when there isn’t a “primary” package, or you want to keep all the packages organized in separate directories.

# [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 = "2024"     # the edition, will have no effect on a resolver used in the workspace

By having a workspace without a root package,

The members and exclude fields

The members and exclude fields define which packages are members of the workspace:

[workspace]
members = ["member1", "path/to/member2", "crates/*"]
exclude = ["crates/foo", "path/to/other"]

All path dependencies residing in the workspace directory automatically become members. Additional members can be listed with the members key, which should be an array of strings containing directories with Cargo.toml files.

The members list also supports globs to match multiple paths, using typical filename glob patterns like * and ?.

The exclude key can be used to prevent paths from being included in a workspace. This can be useful if some path dependencies aren’t desired to be in the workspace at all, or using a glob pattern and you want to remove a directory.

When inside a subdirectory within the workspace, Cargo will automatically search the parent directories for a Cargo.toml file with a [workspace]definition to determine which workspace to use. The package.workspacemanifest key can be used in member crates to point at a workspace’s root to override this automatic search. The manual setting can be useful if the member is not inside a subdirectory of the workspace root.

Package selection

In a workspace, package-related Cargo commands like cargo build can use the -p / --package or --workspace command-line flags to determine which packages to operate on. If neither of those flags are specified, Cargo will use the package in the current working directory. However, if the current directory is a workspace root, the default-members will be used.

The default-members field

The default-members field specifies paths of members to operate on when in the workspace root and the package selection flags are not used:

[workspace]
members = ["path/to/member1", "path/to/member2", "path/to/member3/*"]
default-members = ["path/to/member2", "path/to/member3/foo"]

Note: when a root package is present, you can only operate on it using --package and --workspace flags.

When unspecified, the root package will be used. In the case of a virtual workspace, all members will be used (as if --workspace were specified on the command-line).

The package table

The workspace.package table is where you define keys that can be inherited by members of a workspace. These keys can be inherited by defining them in the member package with {key}.workspace = true.

Keys that are supported:

authors categories
description documentation
edition exclude
homepage include
keywords license
license-file publish
readme repository
rust-version version

Example:

# [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

MSRV: Requires 1.64+

The dependencies table

The workspace.dependencies table is where you define dependencies to be inherited by members of a workspace.

Specifying a workspace dependency is similar to package dependencies except:

You can then inherit the workspace dependency as a package dependency

Example:

# [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

MSRV: Requires 1.64+

The lints table

The workspace.lints table is where you define lint configuration to be inherited by members of a workspace.

Specifying a workspace lint configuration is similar to package lints.

Example:

# [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

MSRV: Respected as of 1.74

The workspace.metadata table is ignored by Cargo and will not be warned about. This section can be used for tools that would like to store workspace configuration in Cargo.toml. For example:

[workspace]
members = ["member1", "member2"]

[workspace.metadata.webcontents]
root = "path/to/webproject"
tool = ["npm", "run", "build"]
# ...

There is a similar set of tables at the package level atpackage.metadata. While cargo does not specify a format for the content of either of these tables, it is suggested that external tools may wish to use them in a consistent fashion, such as referring to the data in workspace.metadata if data is missing from package.metadata, if that makes sense for the tool in question.