清单格式
每个包的 Cargo.toml
文件称为其*清单*。它使用 TOML 格式编写。它包含编译包所需的元数据。查看 cargo locate-project
部分以获取有关 Cargo 如何查找清单文件的更多详细信息。
每个清单文件都包含以下部分
cargo-features
— 不稳定、仅限夜间版本的功能。[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
运行的默认二进制文件。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
authors = ["Alice <[email protected]>", "Bob <[email protected]>"]
Cargo 唯一需要的字段是 name
。如果发布到注册表,则注册表可能需要其他字段。有关发布到 crates.io 的要求,请参阅下面的注释和发布章节。
name
字段
包名称是用于引用包的标识符。当在另一个包中列为依赖项时,以及作为推断的 lib 和 bin 目标的默认名称时,将使用它。
名称只能使用字母数字字符或 -
或 _
,并且不能为空。
请注意,cargo new
和 cargo init
对包名称施加了一些额外的限制,例如强制它是一个有效的 Rust 标识符而不是关键字。crates.io 施加了更多限制,例如
- 只允许使用 ASCII 字符。
- 不要使用保留名称。
- 不要使用特殊的 Windows 名称,例如“nul”。
- 最多使用 64 个字符的长度。
version
字段
Cargo 融入了语义化版本控制的概念,因此请确保您遵循一些基本规则
- 在达到 1.0.0 之前,一切皆有可能,但如果您进行了重大更改,请增加次要版本号。在 Rust 中,重大更改包括向结构体添加字段或向枚举添加变体。
- 在 1.0.0 之后,仅当您增加主要版本号时才进行重大更改。不要破坏构建。
- 在 1.0.0 之后,不要在补丁级别版本中添加任何新的公共 API(没有新的
pub
任何内容)。如果您添加任何新的pub
结构体、特征、字段、类型、函数、方法或任何其他内容,请始终增加次要版本号。 - 使用具有三个数字部分的版本号,例如 1.0.0 而不是 1.0。
有关 Cargo 如何使用版本解析依赖项以及有关设置您自己的版本的指南,请参阅解析器章节。有关构成重大更改的确切内容的更多详细信息,请参阅语义化版本兼容性章节。
此字段是可选的,默认为 0.0.0
。发布包需要此字段。
authors
字段
可选的 authors
字段在一个数组中列出了被认为是包“作者”的人员或组织。确切的含义是开放性的解释——它可以列出原始或主要作者、当前维护者或包的所有者。每个作者条目末尾的尖括号内可以包含可选的电子邮件地址。
[package]
# ...
authors = ["Graydon Hoare", "Fnu Lnu <[email protected]>"]
此字段仅在包元数据和 build.rs
内的 CARGO_PKG_AUTHORS
环境变量中公开。它不会显示在 crates.io 用户界面中。
**警告**:包清单一旦发布就无法更改,因此此字段无法在已发布的包版本中更改或删除。
edition
字段
edition
键是一个可选键,它会影响您的包使用哪个 Rust 版本 进行编译。在 [package]
中设置 edition
键将影响包中的所有目标/crate,包括测试套件、基准测试、二进制文件、示例等。
[package]
# ...
edition = '2021'
大多数清单都通过 cargo new
自动填写了 edition
字段,并使用最新的稳定版本。默认情况下,cargo new
会创建一个使用当前 2021 版本的清单。
如果 Cargo.toml
中不存在 edition
字段,则为了向后兼容,将假定为 2015 版本。请注意,使用 cargo new
创建的所有清单都不会使用此历史回退,因为它们会将 edition
显式指定为较新的值。
rust-version
字段
rust-version
字段是一个可选键,用于告诉 Cargo 您的包可以使用哪个版本的 Rust 语言和编译器进行编译。如果当前选择的 Rust 编译器版本低于声明的版本,Cargo 将会报错退出,并告诉用户所需的版本。
第一个支持此字段的 Cargo 版本随 Rust 1.56.0 发布。在旧版本中,该字段将被忽略,Cargo 将会显示警告。
[package]
# ...
rust-version = "1.56"
Rust 版本必须是包含两个或三个组件的裸版本号;它不能包含语义化版本运算符或预发布标识符。检查 Rust 版本时,将忽略编译器预发布标识符(如 -nightly)。rust-version
必须等于或高于首次引入已配置 edition
的版本。
可以使用 --ignore-rust-version
选项忽略 rust-version
。
在 [package]
中设置 rust-version
键将影响包中的所有目标/crate,包括测试套件、基准测试、二进制文件、示例等。
要查找与您的项目兼容的最低 rust-version
,您可以使用第三方工具,例如 cargo-msrv
。
当用于发布的包时,我们建议 验证 rust-version
。
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.0
LGPL-2.1-only AND MIT AND BSD-2-Clause
GPL-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
如果发布数组包含单个注册表,则在未指定 --registry
标志时,cargo publish
命令将使用它。
metadata
表
默认情况下,Cargo 会警告 Cargo.toml
中未使用的键,以帮助检测拼写错误等。但是,Cargo 会完全忽略 package.metadata
表,并且不会发出警告。此部分可用于希望将包配置存储在 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 级别
forbid
deny
warn
allow
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。
[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]
表提供了一种自定义编译器设置的方法,例如优化和调试设置。有关更多详细信息,请参阅配置文件章节。