清单格式
每个包的 Cargo.toml 文件称为其 清单(manifest)。它采用 TOML 格式编写。它包含编译包所需的元数据。请查阅 cargo locate-project 部分,了解 Cargo 如何查找清单文件的更多详细信息。
每个清单文件都包含以下部分
cargo-features— 不稳定、仅限 nightly 版本的特性。[package]— 定义一个包。name— 包的名称。version— 包的版本。authors— 包的作者。edition— Rust 版本。rust-version— 支持的最低 Rust 版本。description— 包的描述。documentation— 包文档的 URL。readme— 包的 README 文件路径。homepage— 包主页的 URL。repository— 包源代码仓库的 URL。license— 包许可证。license-file— 许可证文本文件的路径。keywords— 包的关键词。categories— 包的分类。workspace— 包所属工作空间的路径。build— 包构建脚本的路径。links— 包链接的本地库名称。exclude— 发布时要排除的文件。include— 发布时要包含的文件。publish— 可用于阻止包的发布。metadata— 外部工具的额外设置。default-run—cargo run默认运行的二进制文件。autolib— 禁用库自动发现。autobins— 禁用二进制文件自动发现。autoexamples— 禁用示例自动发现。autotests— 禁用测试自动发现。autobenches— 禁用基准测试自动发现。resolver— 设置要使用的依赖解析器。
- 目标表:(有关设置请参阅配置)
[lib]— 库目标设置。[[bin]]— 二进制目标设置。[[example]]— 示例目标设置。[[test]]— 测试目标设置。[[bench]]— 基准测试目标设置。
- 依赖表
[dependencies]— 包库依赖。[dev-dependencies]— 示例、测试和基准测试的依赖。[build-dependencies]— 构建脚本的依赖。[target]— 平台特定依赖。
[badges]— 在注册表上显示的徽章。[features]— 条件编译特性。[lints]— 配置此包的 linter。[patch]— 覆盖依赖。[replace]— 覆盖依赖(已弃用)。[profile]— 编译器设置和优化。[workspace]— 工作空间定义。
[package] 部分
Cargo.toml 中的第一个部分是 [package]。
[package]
name = "hello_world" # the name of the package
version = "0.1.0" # the current version, obeying semver
Cargo 唯一要求的字段是 name。如果要发布到注册表,注册表可能会要求额外的字段。请参阅下面的注意事项和发布章节,了解发布到 crates.io 的要求。
name 字段
包名称是用于引用包的标识符。它在作为另一个包的依赖项列出时使用,也用作推断的 lib 和 bin 目标的默认名称。
名称只能使用字母数字字符或 - 或 _,且不能为空。
注意 cargo new 和 cargo init 对包名称施加了一些额外的限制,例如要求它是有效的 Rust 标识符且不是关键字。crates.io 甚至施加了更多限制,例如
- 只允许使用 ASCII 字符。
- 不要使用保留名称。
- 不要使用特殊的 Windows 名称,例如 “nul”。
- 最大长度为 64 个字符。
version 字段
version 字段根据 SemVer(语义化版本)规范进行格式化
版本必须包含三个数字部分:主版本、次版本和补丁版本。
可以在短划线后添加预发布部分,例如 1.0.0-alpha。预发布部分可以使用句点分隔以区分不同的组件。数字组件将使用数字比较,而其他组件将按字典顺序比较。例如,1.0.0-alpha.11 高于 1.0.0-alpha.4。
可以在加号后添加元数据部分,例如 1.0.0+21AF26D3。这仅用于提供信息,Cargo 通常会忽略它。
Cargo 内置了 Semantic Versioning(语义化版本控制)的概念,因此如果版本的最左边非零的主/次/补丁部分相同,则认为版本是兼容的。请参阅解析器章节,了解 Cargo 如何使用版本解析依赖的更多信息。
此字段是可选的,默认为 0.0.0。发布包时此字段是必需的。
MSRV: 在 1.75 版本之前,此字段是必需的
authors 字段
警告:此字段已弃用
可选的 authors 字段以数组形式列出了被视为包“作者”的个人或组织。每个作者条目的末尾可以在尖括号内包含一个可选的电子邮件地址。
[package]
# ...
authors = ["Graydon Hoare", "Fnu Lnu <no-reply@rust-lang.org>"]
为了向后兼容,此字段会出现在包元数据和 build.rs 内的 CARGO_PKG_AUTHORS 环境变量中。
edition 字段
edition 键是一个可选键,影响您的包使用哪个Rust Edition 进行编译。在 [package] 中设置 edition 键将影响包中的所有目标/crate,包括测试套件、基准测试、二进制文件、示例等。
[package]
# ...
edition = '2024'
大多数清单文件会由 cargo new 自动填写 edition 字段,使用最新的稳定版本。目前,默认情况下 cargo new 会创建一个使用 2024 edition 的清单文件。
如果 Cargo.toml 中不存在 edition 字段,则出于向后兼容性考虑,假定使用 2015 edition。请注意,使用 cargo new 创建的所有清单文件都不会使用此历史回退,因为它们将明确指定 edition 为一个较新的值。
rust-version 字段
rust-version 字段告诉 Cargo 您的包支持哪个版本的 Rust 工具链。请参阅Rust 版本章节了解更多详细信息。
description 字段
description 是对包的简短介绍。crates.io 将随您的包一起显示此信息。这应该是纯文本(不是 Markdown)。
[package]
# ...
description = "A short description of my package"
注意:crates.io 要求设置
description字段。
documentation 字段
documentation 字段指定了托管 crate 文档的网站 URL。如果在清单文件中未指定 URL,crates.io 将在文档构建并可用后自动将您的 crate 链接到相应的 docs.rs 页面(参阅 docs.rs 队列)。
[package]
# ...
documentation = "https://docs.rs/bitflags"
readme 字段
readme 字段应指向包根目录中(相对于此 Cargo.toml 文件)包含有关包的一般信息的文件路径。发布时此文件将传输到注册表。crates.io 将其解释为 Markdown 并在 crate 页面上渲染。
[package]
# ...
readme = "README.md"
如果未为此字段指定值,并且包根目录下存在名为 README.md、README.txt 或 README 的文件,则将使用该文件的名称。通过将此字段设置为 false 可以抑制此行为。如果此字段设置为 true,则假定默认值为 README.md。
homepage 字段
homepage 字段应为您的包主页网站的 URL。
[package]
# ...
homepage = "https://serde.rs"
仅当 crate 有专门的网站(而非源代码仓库或 API 文档)时,才应为 homepage 设置值。不要让 homepage 的值与 documentation 或 repository 的值重复。
repository 字段
repository 字段应为您的包源代码仓库的 URL。
[package]
# ...
repository = "https://github.com/rust-lang/cargo"
license 和 license-file 字段
license 字段包含包发布的软件许可证名称。license-file 字段包含包含许可证文本文件的路径(相对于此 Cargo.toml 文件)。
crates.io 将 license 字段解释为 SPDX 2.3 许可证表达式。名称必须是 SPDX 许可证列表 3.20 中的已知许可证。请参阅 SPDX 网站了解更多信息。
SPDX 许可证表达式支持 AND 和 OR 运算符来组合多个许可证。1
[package]
# ...
license = "MIT OR Apache-2.0"
使用 OR 表示用户可以选择其中一个许可证。使用 AND 表示用户必须同时遵守这两个许可证。WITH 运算符表示附带特殊例外的许可证。一些示例
MIT OR Apache-2.0LGPL-2.1-only AND MIT AND BSD-2-ClauseGPL-2.0-or-later WITH Bison-exception-2.2
如果包使用的是非标准许可证,则可以指定 license-file 字段而不是 license 字段。
[package]
# ...
license-file = "LICENSE.txt"
注意:crates.io 要求设置
license或license-file字段。
以前可以使用 / 分隔多个许可证,但该用法已弃用。
keywords 字段
keywords 字段是一个字符串数组,用于描述此包。这有助于在注册表上搜索包,您可以选择任何有助于他人找到此 crate 的词汇。
[package]
# ...
keywords = ["gamedev", "graphics"]
注意:crates.io 最多允许 5 个关键词。每个关键词必须是 ASCII 文本,最多 20 个字符,以字母数字字符开头,且只包含字母、数字、
_、-或+。
categories 字段
categories 字段是一个字符串数组,表示此包所属的分类。
categories = ["command-line-utilities", "development-tools::cargo-plugins"]
注意:crates.io 最多有 5 个分类。每个分类应与 https://crates.io/category_slugs 上可用的字符串之一匹配,并且必须完全匹配。
workspace 字段
workspace 字段可用于配置此包所属的工作空间。如果未指定,则会向上在文件系统中寻找第一个包含 [workspace] 的 Cargo.toml 文件来推断。如果成员不在工作空间根目录的子目录中,设置此字段很有用。
[package]
# ...
workspace = "path/to/workspace/root"
如果清单文件已定义了 [workspace] 表,则不能指定此字段。也就是说,一个 crate 不能既是工作空间中的根 crate(包含 [workspace]),又是另一个工作空间的成员 crate(包含 package.workspace)。
有关更多信息,请参阅工作空间章节。
build 字段
build 字段指定包根目录中一个文件,该文件是用于构建原生代码的构建脚本。更多信息可在构建脚本指南中找到。
[package]
# ...
build = "build.rs"
默认值是 "build.rs",它从包根目录中名为 build.rs 的文件加载脚本。使用 build = "custom_build_name.rs" 指定不同文件的路径,或使用 build = false 禁用构建脚本的自动检测。
links 字段
links 字段指定要链接的本地库的名称。更多信息可在构建脚本指南的 links 部分找到。
例如,一个链接名为“git2”的本地库(例如 Linux 上的 libgit2.a)的 crate 可以指定
[package]
# ...
links = "git2"
exclude 和 include 字段
exclude 和 include 字段可用于明确指定将项目打包发布时要包含哪些文件,以及某些类型的更改跟踪(如下所述)。exclude 字段中指定的模式标识一组不包含的文件,而 include 中的模式指定明确包含的文件。您可以运行 cargo package --list 来验证包中将包含哪些文件。
[package]
# ...
exclude = ["/ci", "images/", ".*"]
[package]
# ...
include = ["/src", "COPYRIGHT", "/examples", "!/examples/big_example"]
如果未指定任一字段,默认是将包根目录中的所有文件包含在内,但以下列出的排除项除外。
如果未指定 include 字段,则将排除以下文件
- 如果包不在 Git 仓库中,所有以点开头的“隐藏”文件将被跳过。
- 如果包在 Git 仓库中,则将跳过仓库的 gitignore 规则和全局 Git 配置所忽略的任何文件。
无论是否指定了 exclude 或 include,以下文件总是被排除
- 任何子包(任何包含
Cargo.toml文件的子目录)将被跳过。 - 包根目录中名为
target的目录将被跳过。
以下文件总是被包含
- 包自身的
Cargo.toml文件总是被包含,无需在include中列出。 - 一个最小化的
Cargo.lock会自动包含。请参阅cargo package了解更多信息。 - 如果指定了
license-file字段,则该文件总是会被包含。
这些选项是互斥的;设置 include 将覆盖 exclude。如果您需要在 include 的文件集合中进行排除,请使用下面描述的 ! 运算符。
模式应为 gitignore 风格的模式。简而言之
foo匹配包中任何位置名称为foo的文件或目录。这等效于模式**/foo。/foo仅匹配包根目录中名称为foo的文件或目录。foo/匹配包中任何位置名称为foo的目录。- 支持常见的 glob 模式,如
*、?和[]*匹配零个或多个字符,但不包括/。例如,*.html匹配包中任何位置具有.html扩展名的文件或目录。?匹配除/外的任何字符。例如,foo?匹配food,但不匹配foo。[]允许匹配字符范围。例如,[ab]匹配a或b。[a-z]匹配字母 a 到 z。
**/前缀匹配任何目录。例如,**/foo/bar匹配直接位于目录foo下的任意位置的文件或目录bar。/**后缀匹配内部的所有内容。例如,foo/**匹配目录foo内的所有文件,包括foo下子目录中的所有文件。/**/匹配零个或多个目录。例如,a/**/b匹配a/b、a/x/b、a/x/y/b等等。!前缀否定一个模式。例如,模式src/*.rs和!foo.rs将匹配src目录中所有扩展名为.rs的文件,但名为foo.rs的文件除外。
包含/排除列表在某些情况下也用于更改跟踪。对于使用 rustdoc 构建的目标,它用于确定要跟踪的文件列表,以判断是否应该重新构建目标。如果包有一个没有发出任何 rerun-if-* 指令的构建脚本,则包含/排除列表用于跟踪如果其中任何文件发生更改是否应重新运行构建脚本。
publish 字段
publish 字段可用于控制包可以发布到哪些注册表
[package]
# ...
publish = ["some-registry-name"]
为了防止包意外发布到注册表(如 crates.io),例如在公司内部保持包私有,您可以省略 version 字段。如果您想更明确,可以禁用发布
[package]
# ...
publish = false
如果 publish 数组包含一个注册表,当未指定 --registry 标志时,cargo publish 命令将使用它。
metadata 表
Cargo 默认会警告 Cargo.toml 中未使用的键,以帮助检测拼写错误等。然而,package.metadata 表完全被 Cargo 忽略,不会发出警告。此部分可用于希望在 Cargo.toml 中存储包配置的工具。例如
[package]
name = "..."
# ...
# Metadata used when generating an Android APK, for example.
[package.metadata.android]
package-name = "my-awesome-android-app"
assets = "path/to/static"
您需要查阅您的工具文档,了解如何使用此字段。对于使用 package.metadata 表的 Rust 项目,请参阅
在工作空间级别有一个类似的表,位于 workspace.metadata。虽然 Cargo 未指定这两个表内容的格式,但建议外部工具以一致的方式使用它们,例如,如果 package.metadata 中缺少数据,则引用 workspace.metadata 中的数据,如果这对相关工具来说是合理的。
default-run 字段
清单文件 [package] 部分的 default-run 字段可用于指定 cargo run 选择的默认二进制文件。例如,当同时存在 src/bin/a.rs 和 src/bin/b.rs 时
[package]
default-run = "a"
[lints] 部分
通过在表中将来自不同工具的 lint 分配给新的级别来覆盖其默认级别,例如
[lints.rust]
unsafe_code = "forbid"
这是以下内容的简写
[lints.rust]
unsafe_code = { level = "forbid", priority = 0 }
level 对应于 rustc 中的lint 级别
forbiddenywarnallow
priority 是一个有符号整数,用于控制哪些 lint 或 lint 组覆盖其他 lint 组
- 较低(特别是负数)的优先级较低,会被较高的数字覆盖,并在命令行上先于
rustc等工具显示
要知道特定的 lint 属于 [lints] 下的哪个表,它是 lint 名称中 :: 之前的部分。如果没有 ::,则工具是 rust。例如,关于 unsafe_code 的警告将是 lints.rust.unsafe_code,而关于 clippy::enum_glob_use 的 lint 将是 lints.clippy.enum_glob_use。
例如
[lints.rust]
unsafe_code = "forbid"
[lints.clippy]
enum_glob_use = "deny"
通常,这些设置只会影响当前包的本地开发。Cargo 只会将这些设置应用于当前包,而不应用于依赖项。对于依赖当前包的其他包,Cargo 会使用 --cap-lints 等特性来抑制来自非路径依赖的 lint。
MSRV: 自 1.74 版本开始生效
[badges] 部分
[badges] 部分用于指定发布包时可在注册表网站上显示的状态徽章。
注意:crates.io 以前在其网站上 crate 旁边显示徽章,但该功能已移除。包应将徽章放在其 README 文件中,该文件将在 crates.io 上显示(参见
readme字段)。
[badges]
# The `maintenance` table indicates the status of the maintenance of
# the crate. This may be used by a registry, but is currently not
# used by crates.io. See https://github.com/rust-lang/crates.io/issues/2437
# and https://github.com/rust-lang/crates.io/issues/2438 for more details.
#
# The `status` field is required. Available options are:
# - `actively-developed`: New features are being added and bugs are being fixed.
# - `passively-maintained`: There are no plans for new features, but the maintainer intends to
# respond to issues that get filed.
# - `as-is`: The crate is feature complete, the maintainer does not intend to continue working on
# it or providing support, but it works for the purposes it was designed for.
# - `experimental`: The author wants to share it with the community but is not intending to meet
# anyone's particular use case.
# - `looking-for-maintainer`: The current maintainer would like to transfer the crate to someone
# else.
# - `deprecated`: The maintainer does not recommend using this crate (the description of the crate
# can describe why, there could be a better solution available or there could be problems with
# the crate that the author does not want to fix).
# - `none`: Displays no badge on crates.io, since the maintainer has not chosen to specify
# their intentions, potential crate users will need to investigate on their own.
maintenance = { status = "..." }
依赖项部分
请参阅指定依赖项页面,了解关于 [dependencies]、[dev-dependencies]、[build-dependencies] 以及目标特定 [target.*.dependencies] 部分的信息。
[profile.*] 部分
[profile] 表提供了一种自定义编译器设置(如优化和调试设置)的方式。请参阅配置文件章节了解更多详细信息。