当前位置: 首页 > news >正文

《Cargo 参考手册》第一章:清单

本参考手册涵盖了 Cargo 各个方面的详细内容。

清单格式

每个包的 Cargo.toml 文件称为其清单(manifest)。它采用 TOML 格式编写,包含编译该包所需的元数据。有关 Cargo 如何查找清单文件的更多细节,请查看cargo locate-project部分。

每个清单文件都包含以下部分:

  • cargo-features — 不稳定的、仅夜间版(nightly)可用的特性。
  • [package] — 定义一个包。
    • name — 包的名称。
    • version — 包的版本。
    • authors — 包的作者。
    • edition — Rust 版本(edition)。
    • 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 — 设置要使用的依赖解析器。
  • 目标表(Target tables):(参见配置了解设置)
    • [lib] — 库目标设置。
    • [[bin]] — 二进制目标设置。
    • [[example]] — 示例目标设置。
    • [[test]] — 测试目标设置。
    • [[bench]] — 基准测试目标设置。
  • 依赖表(Dependency tables):
    • [dependencies] — 包的库依赖项。
    • [dev-dependencies] — 示例、测试和基准测试的依赖项。
    • [build-dependencies] — 构建脚本的依赖项。
    • [target] — 特定平台的依赖项。
    • [badges] — 在注册表上显示的徽章。
    • [features] — 条件编译特性。
    • [lints] — 配置该包的代码检查器。
    • [hints] — 提供编译该包的提示。
    • [patch] — 覆盖依赖项。
    • [replace] — 覆盖依赖项(已弃用)。
    • [profile] — 编译器设置和优化选项。
    • [workspace] — 工作区定义。

[package]部分

Cargo.toml 中的第一部分是[package]

toml

[package]
name = "hello_world" # 包的名称
version = "0.1.0"    # 当前版本,遵循semver规范

Cargo 唯一要求的字段是name。如果要发布到注册表,注册表可能还需要其他字段。有关发布到 crates.io 的要求,请参见下面的说明和发布章节。

name字段

包名称是用于引用该包的标识符。当在另一个包中列为依赖项时会用到它,也是推断出的库(lib)和二进制(bin)目标的默认名称。

名称只能使用字母数字字符、连字符(-)或下划线(_),且不能为空。

注意,cargo newcargo 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。发布包时需要此字段。

最低支持的 Rust 版本(MSRV):在 1.75 版本之前,此字段是必填的。

authors字段

警告:此字段已弃用

可选的authors字段以数组形式列出被视为该包 “作者” 的个人或组织。每个作者条目末尾的尖括号中可以包含可选的电子邮件地址。

toml

[package]
# ...
authors = ["Graydon Hoare", "Fnu Lnu <no-reply@rust-lang.org>"]

为了向后兼容,此字段会显示在包元数据中,以及 build.rs 中的CARGO_PKG_AUTHORS环境变量中。

edition字段

edition键是一个可选键,会影响包使用哪个 Rust 版本(Edition)进行编译。在[package]中设置edition键将影响包中的所有目标 /crate,包括测试套件、基准测试、二进制文件、示例等。

toml

[package]
# ...
edition = '2024'

大多数清单在通过cargo new创建时会自动填充edition字段,使用最新的稳定版本。目前,cargo new默认创建使用 2024 版本的清单。

如果 Cargo.toml 中没有edition字段,则为了向后兼容,会默认使用 2015 版本。注意,所有通过cargo new创建的清单不会使用这个历史默认值,因为它们会明确指定一个更新的版本值。

rust-version字段

rust-version字段告诉 cargo 你的包支持的 Rust 工具链版本。有关更多细节,请参见 Rust 版本章节。

description字段

description是关于包的简短说明。crates.io 会在你的包页面上显示它。这应该是纯文本(不是 Markdown)。

toml

[package]
# ...
description = "我的包的简短描述"

注意:crates.io 要求必须设置description

documentation字段

documentation字段指定托管该 crate 文档的网站 URL。如果清单文件中没有指定 URL,当文档构建完成并可用时,crates.io 会自动将你的 crate 链接到相应的 docs.rs 页面(参见 docs.rs 队列)。

toml

[package]
# ...
documentation = "https://docs.rs/bitflags"

readme字段

readme字段应该是包根目录中(相对于此 Cargo.toml)包含该包一般信息的文件路径。发布时,此文件会被传输到注册表。crates.io 会将其解释为 Markdown 并在 crate 页面上渲染。

toml

[package]
# ...
readme = "README.md"

如果未为此字段指定值,且包根目录中存在名为 README.md、README.txt 或 README 的文件,则会使用该文件的名称。你可以通过将此字段设置为false来抑制这种行为。如果此字段设置为true,则会默认使用README.md

homepage字段

homepage字段应该是该包主页的 URL。

toml

[package]
# ...
homepage = "https://serde.rs"

只有当该 crate 有专门的网站(不同于源代码仓库或 API 文档)时,才应该设置homepage的值。不要让homepagedocumentationrepository的值重复。

repository字段

repository字段应该是该包源代码仓库的 URL。

toml

[package]
# ...
repository = "https://github.com/rust-lang/cargo"

licenselicense-file字段

license字段包含该包发布所依据的软件许可证名称。license-file字段包含许可证文本文件的路径(相对于此 Cargo.toml)。

crates.io 将license字段解释为 SPDX 2.3 许可证表达式。名称必须是 SPDX 许可证列表 3.20 中的已知许可证。有关更多信息,请参见 SPDX 网站。

SPDX 许可证表达式支持ANDOR运算符来组合多个许可证。

toml

[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字段。

toml

[package]
# ...
license-file = "LICENSE.txt"

注意:crates.io 要求必须设置licenselicense-file

keywords字段

keywords字段是描述该包的字符串数组。这有助于在注册表上搜索该包,你可以选择任何有助于他人找到此 crate 的词语。

toml

[package]
# ...
keywords = ["gamedev", "graphics"]

注意:crates.io 允许最多 5 个关键词。每个关键词必须是 ASCII 文本,最多 20 个字符,以字母数字字符开头,且只能包含字母、数字、_、- 或 +。

categories字段

categories字段是该包所属类别的字符串数组。

toml

categories = ["command-line-utilities", "development-tools::cargo-plugins"]

注意:crates.io 最多允许 5 个类别。每个类别应与https://crates.io/category_slugs上的某个字符串完全匹配。

workspace字段

workspace字段可用于配置该包将加入的工作区。如果未指定,会向上查找文件系统中第一个包含[workspace]的 Cargo.toml 作为工作区。如果成员不在工作区根目录的子目录中,设置此字段会很有用。

toml

[package]
# ...
workspace = "path/to/workspace/root"

如果清单中已经定义了[workspace]表,则不能指定此字段。也就是说,一个 crate 不能既是工作区的根 crate(包含[workspace]),又是另一个工作区的成员 crate(包含package.workspace)。

有关更多信息,请参见工作区章节。

build字段

build字段指定包根目录中用于构建原生代码的构建脚本文件。更多信息可以在构建脚本指南中找到。

toml

[package]
# ...
build = "build.rs"

默认值是build.rs,即从包根目录中名为build.rs的文件加载脚本。使用build = "custom_build_name.rs"指定不同文件的路径,或使用build = false禁用构建脚本的自动检测。

links字段

links字段指定要链接的原生库的名称。更多信息可以在构建脚本指南的 links 部分找到。

例如,一个链接名为 “git2” 的原生库(例如 Linux 上的libgit2.a)的 crate 可以指定:

toml

[package]
# ...
links = "git2"

excludeinclude字段

excludeinclude字段可用于明确指定打包发布项目时包含哪些文件,以及某些类型的变更跟踪(如下所述)。exclude字段中指定的模式标识不包含的文件集,include中的模式指定明确包含的文件。你可以运行cargo package --list来验证哪些文件将包含在包中。

toml

[package]
# ...
exclude = ["/ci", "images/", ".*"]

toml

[package]
# ...
include = ["/src", "COPYRIGHT", "/examples", "!/examples/big_example"]

如果两个字段都未指定,默认是包含包根目录中的所有文件,但排除以下内容:

  • 如果包不在 git 仓库中,所有以点开头的 “隐藏” 文件会被跳过。
  • 如果包在 git 仓库中,任何被仓库的 gitignore 规则和全局 git 配置忽略的文件会被跳过。

无论是否指定excludeinclude,以下文件始终被排除:

  • 任何子包会被跳过(任何包含 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]匹配ab[a-z]匹配从az的字母。
    • **/前缀匹配任何目录。例如,**/foo/bar匹配任何直接位于foo目录下的bar文件或目录。
    • /**后缀匹配内部的所有内容。例如,foo/**匹配foo目录内的所有文件,包括foo下所有子目录中的文件。
    • /**/匹配零个或多个目录。例如,a/**/b匹配a/ba/x/ba/x/y/b等。
    • !前缀否定一个模式。例如,src/*.rs!foo.rs的模式组合会匹配src目录中所有带有.rs扩展名的文件,但不包括名为foo.rs的文件。

include/exclude列表在某些情况下也用于变更跟踪。对于使用rustdoc构建的目标,它用于确定要跟踪的文件列表,以判断是否需要重新构建目标。如果包的构建脚本没有发出任何rerun-if-*指令,则include/exclude列表用于跟踪如果这些文件中的任何一个发生变化,是否需要重新运行构建脚本。

publish字段

publish字段可用于控制包可以发布到哪些注册表名称:

toml

[package]
# ...
publish = ["some-registry-name"]

例如,为了防止包被误发布到注册表(如 crates.io),以保持包在公司内部私有,你可以省略version字段。如果你想更明确,可以禁用发布:

toml

[package]
# ...
publish = false

如果publish数组包含一个注册表,当未指定--registry标志时,cargo publish命令将使用该注册表。

metadata

默认情况下,Cargo 会警告 Cargo.toml 中未使用的键,以帮助检测拼写错误等。但是,package.metadata表完全被 Cargo 忽略,不会产生警告。此部分可用于希望在 Cargo.toml 中存储包配置的工具。例如:

toml

[package]
name = "..."
# ...# 例如,生成Android APK时使用的元数据。
[package.metadata.android]
package-name = "my-awesome-android-app"
assets = "path/to/static"

你需要查看工具的文档,了解如何使用此字段。对于使用package.metadata表的 Rust 项目,请参见:

  • docs.rs

在工作区级别有一个类似的表workspace.metadata。虽然 cargo 没有为这两个表的内容指定格式,但建议外部工具可以以一致的方式使用它们,例如,如果工具需要,当package.metadata中缺少数据时,可以引用workspace.metadata中的数据。

default-run字段

清单的[package]部分中的default-run字段可用于指定cargo run选择的默认二进制文件。例如,当同时存在src/bin/a.rssrc/bin/b.rs时:

toml

[package]
default-run = "a"

[lints]部分

通过在表中将不同工具的默认代码检查(lint)级别分配给新级别来覆盖它们,例如:

toml

[lints.rust]
unsafe_code = "forbid"

这是以下写法的简写:

toml

[lints.rust]
unsafe_code = { level = "forbid", priority = 0 }

level对应于 rustc 中的代码检查级别:

  • forbid(禁止)
  • deny(拒绝)
  • warn(警告)
  • allow(允许)

priority是一个有符号整数,控制哪些代码检查或代码检查组覆盖其他代码检查组:

  • 较小的(特别是负数)数字优先级较低,会被较大的数字覆盖,并且在命令行中先显示给rustc等工具。

要了解某个特定代码检查属于[lints]下的哪个表,查看代码检查名称中::之前的部分即可。如果没有::,则工具是rust。例如,关于unsafe_code的警告属于lints.rust.unsafe_code,而关于clippy::enum_glob_use的代码检查属于lints.clippy.enum_glob_use

例如:

toml

[lints.rust]
unsafe_code = "forbid"[lints.clippy]
enum_glob_use = "deny"

通常,这些设置只会影响当前包的本地开发。Cargo 仅将这些应用于当前包,而不应用于依赖项。对于依赖项,Cargo 通过--cap-lints等功能抑制非路径依赖项的代码检查。

最低支持的 Rust 版本(MSRV):从 1.74 版本开始支持。

[hints]部分

[hints]部分允许指定编译该包的提示。Cargo 在编译该包时默认会遵守这些提示,尽管正在构建的顶级包可以通过[profile]机制覆盖这些值。从设计上讲,Cargo 忽略这些提示总是安全的;如果 Cargo 遇到不理解的提示,或者理解但不理解其值的提示,会发出警告,但不会报错。因此,在 crate 中指定提示不会影响该 crate 的最低支持 Rust 版本(MSRV)。

个别提示可能有相关的不稳定特性门控,你需要传入这些门控才能应用它们指定的配置,但如果你没有指定该不稳定特性门控,同样只会收到警告,不会报错。

目前没有稳定的提示。有关不稳定提示的信息,请参见hint-mostly-unused文档。

最低支持的 Rust 版本(MSRV):从 1.90 版本开始支持。

[badges]部分

[badges]部分用于指定包发布时可在注册表网站上显示的状态徽章。

注意:crates.io 以前会在 crate 旁边显示徽章,但该功能已被移除。包应该在其 README 文件中放置徽章,这些徽章会在 crates.io 上显示(参见readme字段)。

toml

[badges]
# `maintenance`表指示该crate的维护状态。
# 注册表可能会使用它,但目前crates.io不使用。
# 更多细节请参见https://github.com/rust-lang/crates.io/issues/2437和https://github.com/rust-lang/crates.io/issues/2438。
#
# `status`字段是必填的。可用选项有:
# - `actively-developed`:正在添加新功能并修复错误。
# - `passively-maintained`:没有添加新功能的计划,但维护者会响应提交的问题。
# - `as-is`:该crate功能已完整,维护者不打算继续开发或提供支持,但它能满足设计时的用途。
# - `experimental`:作者希望与社区分享,但不打算满足任何人的特定用例。
# - `looking-for-maintainer`:当前维护者希望将该crate转让给其他人。
# - `deprecated`:维护者不建议使用该crate(crate的描述可以说明原因,可能有更好的解决方案,或者该crate存在作者不想修复的问题)。
# - `none`:在crates.io上不显示任何徽章,因为维护者没有选择说明他们的意图,潜在的crate用户需要自行调查。
maintenance = { status = "..." }

依赖部分

有关[dependencies][dev-dependencies][build-dependencies]和特定于目标的[target.*.dependencies]部分的信息,请参见指定依赖项页面。

[profile.*]部分

[profile]表提供了自定义编译器设置的方法,如优化和调试设置。有关更多细节,请参见配置文件(Profiles)章节。

以前,多个许可证可以用/分隔,但这种用法已被弃用。

Cargo 目标(Targets)

Cargo 包由目标(targets)组成,这些目标对应可以编译成 crate 的源文件。包可以有库、二进制文件、示例、测试和基准测试目标。目标列表可以在 Cargo.toml 清单中配置,通常通过源文件的目录结构自动推断。

有关配置目标设置的详细信息,请参见下面的 “配置目标”。

库(Library)

库目标定义了一个可以被其他库和可执行文件使用和链接的 “库”。文件名默认为src/lib.rs,库的名称默认为包的名称,其中所有连字符替换为下划线。一个包只能有一个库。库的设置可以在 Cargo.toml 的[lib]表中自定义。

toml

# 在Cargo.toml中自定义库的示例。
[lib]
crate-type = ["cdylib"]
bench = false

二进制文件(Binaries)

二进制目标是编译后可以运行的可执行程序。二进制文件的源可以是src/main.rs和 / 或存储在src/bin/目录中。对于src/main.rs,默认的二进制文件名称是包名称。每个二进制文件的设置可以在 Cargo.toml 的[[bin]]表中自定义。

二进制文件可以使用包的库的公共 API。它们还会与 Cargo.toml 中定义的[dependencies]链接。

你可以使用cargo run命令并加上--bin <bin-name>选项来运行单个二进制文件。cargo install可用于将可执行文件复制到一个公共位置。

toml

# 在Cargo.toml中自定义二进制文件的示例。
[[bin]]
name = "cool-tool"
test = false
bench = false[[bin]]
name = "frobnicator"
required-features = ["frobnicate"]

示例(Examples)

examples目录下的文件是该库功能的示例用法。编译后,它们会被放置在target/debug/examples目录中。

示例可以使用包的库的公共 API。它们还会与 Cargo.toml 中定义的[dependencies][dev-dependencies]链接。

默认情况下,示例是可执行的二进制文件(带有main()函数)。你可以指定crate-type字段,使示例被编译为库:

toml

[[example]]
name = "foo"
crate-type = ["staticlib"]

你可以使用cargo run命令并加上--example <example-name>选项来运行单个可执行示例。库示例可以使用cargo build命令并加上--example <example-name>选项来构建。cargo install加上--example <example-name>选项可用于将可执行二进制文件复制到一个公共位置。默认情况下,cargo test会编译示例以防止它们过时。如果你的示例中有要通过cargo test运行的#[test]函数,请将test字段设置为true

测试(Tests)

Cargo 项目中有两种测试风格:

  • 单元测试:在库或二进制文件(或任何启用了test字段的目标)中,用#[test]属性标记的函数。这些测试可以访问它们所定义的目标中的私有 API。
  • 集成测试:一个单独的可执行二进制文件,也包含#[test]函数,它与项目的库链接并可以访问其公共 API。

测试通过cargo test命令运行。默认情况下,Cargo 和 rustc 使用libtest测试框架,该框架负责收集用#[test]属性注释的函数并并行执行它们,报告每个测试的成功和失败。如果你想使用不同的测试框架或测试策略,请参见harness字段。

注意:Cargo 中还有另一种特殊的测试风格:文档测试。它们由rustdoc处理,执行模型略有不同。有关更多信息,请参见cargo test

集成测试

tests目录下的文件是集成测试。当你运行cargo test时,Cargo 会将这些文件中的每一个编译为单独的 crate,并执行它们。

集成测试可以使用包的库的公共 API。它们还会与 Cargo.toml 中定义的[dependencies][dev-dependencies]链接。

如果你想在多个集成测试之间共享代码,可以将其放在一个单独的模块中,例如tests/common/mod.rs,然后在每个测试中放入mod common;来导入它。

每个集成测试都会生成一个单独的可执行二进制文件,cargo test会串行运行它们。在某些情况下,这可能效率不高,因为编译时间可能更长,并且运行测试时可能无法充分利用多个 CPU。如果你有很多集成测试,可以考虑创建一个单独的集成测试,并将测试分成多个模块。libtest框架会自动找到所有带有#[test]注释的函数并并行运行它们。你可以将模块名称传递给cargo test,只运行该模块内的测试。

如果有集成测试,二进制目标会自动构建。这允许集成测试执行二进制文件以测试其行为。构建集成测试时,会设置CARGO_BIN_EXE_<name>环境变量,因此集成测试可以使用env宏来定位可执行文件。

基准测试(Benchmarks)

基准测试提供了一种使用cargo bench命令测试代码性能的方法。它们遵循与测试相同的结构,每个基准测试函数用#[bench]属性注释。与测试类似:

  • 基准测试放在benches目录中。
  • 在库和二进制文件中定义的基准测试函数可以访问它们所定义的目标中的私有 API。benches目录中的基准测试可以使用公共 API。
  • bench字段可用于定义默认要进行基准测试的目标。
  • harness字段可用于禁用内置测试框架。

注意:#[bench]属性目前是不稳定的,仅在夜间版(nightly)通道可用。crates.io 上有一些包可能有助于在稳定版通道上运行基准测试,例如 Criterion。

配置目标

Cargo.toml 中的[lib][[bin]][[example]][[test]][[bench]]部分都支持类似的配置,用于指定如何构建目标。像[[bin]]这样的双括号部分是 TOML 的表数组(array-of-table),这意味着你可以编写多个[[bin]]部分来在你的 crate 中创建多个可执行文件。你只能指定一个库,因此[lib]是一个普通的 TOML 表。

以下是每个目标的 TOML 设置概述,每个字段的详细描述如下。

toml

[lib]
name = "foo"           # 目标的名称。
path = "src/lib.rs"    # 目标的源文件。
test = true            # 默认是否进行测试。
doctest = true         # 默认是否测试文档示例。
bench = true           # 默认是否进行基准测试。
doc = true             # 默认是否生成文档。
proc-macro = false     # 对于过程宏库,设置为`true`。
harness = true         # 使用libtest测试框架。
crate-type = ["lib"]   # 要生成的crate类型。
required-features = [] # 构建此目标所需的特性(库不适用)。

name字段

name字段指定目标的名称,对应于将要生成的产物的文件名。对于库,这是依赖项用来引用它的 crate 名称。

对于库目标,默认值是包的名称,其中所有连字符替换为下划线。对于默认的二进制文件(src/main.rs),默认值也是包的名称,连字符不替换。对于自动发现的目标,默认值是目录或文件名。

[lib]外,所有目标都需要此字段。

path字段

path字段指定 crate 源文件的位置,相对于 Cargo.toml 文件。

如果未指定,则根据目标名称使用推断的路径。

test字段

test字段指示cargo test是否默认测试该目标。对于库、二进制文件和测试,默认值为true

注意:默认情况下,cargo test会编译示例以确保它们能继续编译,但不会默认测试它们。为示例设置test = true也会将其构建为测试,并运行示例中定义的任何#[test]函数。

doctest字段

doctest字段指示cargo test是否默认测试文档示例。这仅与库相关,对其他部分没有影响。库的默认值为true

bench字段

bench字段指示cargo bench是否默认对该目标进行基准测试。对于库、二进制文件和基准测试,默认值为true

doc字段

doc字段指示cargo doc生成文档时是否默认包含该目标。对于库和二进制文件,默认值为true

注意:如果二进制文件的名称与库目标的名称相同,该二进制文件会被跳过。

plugin字段

此选项已弃用且不再使用。

proc-macro字段

proc-macro字段指示该库是一个过程宏(参见参考)。这仅对[lib]目标有效。

harness字段

harness字段指示是否将--test标志传递给rustc,这将自动包含libtest库,该库是用于收集和运行用#[test]属性标记的测试或用#[bench]属性标记的基准测试的驱动程序。所有目标的默认值为true

如果设置为false,则你需要负责定义main()函数来运行测试和基准测试。

无论是否启用测试框架,测试都启用cfg(test)条件表达式。

crate-type字段

crate-type字段定义目标将生成的 crate 类型。它是一个字符串数组,允许你为单个目标指定多个 crate 类型。这只能为库和示例指定。二进制文件、测试和基准测试始终是 “bin” crate 类型。默认值如下:

目标crate 类型
普通库"lib"
过程宏库"proc-macro"
示例"bin"

可用选项有binlibrlibdylibcdylibstaticlibproc-macro。你可以在 Rust 参考手册中了解更多关于不同 crate 类型的信息。

required-features字段

required-features字段指定构建该目标所需的特性。如果任何所需的特性未启用,该目标会被跳过。这仅与[[bin]][[bench]][[test]][[example]]部分相关,对[lib]没有影响。

toml

[features]
# ...
postgres = []
sqlite = []
tools = [][[bin]]
name = "my-pg-tool"
required-features = ["postgres", "tools"]

edition字段

edition字段定义目标将使用的 Rust 版本(edition)。如果未指定,默认为[package]edition字段。

注意:此字段已弃用,将在未来的版本中移除。

目标自动发现

默认情况下,Cargo 根据文件系统的布局自动确定要构建的目标。目标配置表,如[lib][[bin]][[test]][[bench]][[example]],可用于添加不遵循标准目录布局的额外目标。

可以禁用目标自动发现,以便只构建手动配置的目标。在[package]部分中将autolibautobinsautoexamplesautotestsautobenches键设置为false,将禁用相应目标类型的自动发现。

toml

[package]
# ...
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false

只有在特殊情况下才需要禁用自动发现。例如,如果你有一个库,其中想要一个名为bin的模块,这会出现问题,因为 Cargo 通常会尝试将bin目录中的任何内容编译为可执行文件。以下是这种情况的示例布局:

plaintext

├── Cargo.toml
└── src├── lib.rs└── bin└── mod.rs

要防止 Cargo 将src/bin/mod.rs推断为可执行文件,请在 Cargo.toml 中设置autobins = false以禁用自动发现:

toml

[package]
# …
autobins = false

注意:对于 2015 版本的包,如果在 Cargo.toml 中至少手动定义了一个目标,则自动发现的默认值为false。从 2018 版本开始,默认值始终为true

最低支持的 Rust 版本(MSRV):autobinsautoexamplesautotestsautobenches从 1.27 版本开始支持。

最低支持的 Rust 版本(MSRV):autolib从 1.83 版本开始支持。

Rust 版本

rust-version字段是一个可选键,用于告诉 cargo 你的包支持的 Rust 工具链版本。

toml

[package]
# ...
rust-version = "1.56"

Rust 版本必须是至少包含一个组件的纯版本号;不能包含 semver 运算符或预发布标识符。检查 Rust 版本时,会忽略编译器的预发布标识符,如-nightly

最低支持的 Rust 版本(MSRV):从 1.56 版本开始支持。

用途

诊断:

当你的包在不支持的工具链上编译时,Cargo 会向用户报告错误。这明确了支持预期,避免报告不太直接的诊断信息,如无效语法或标准库中缺少功能。这会影响包中的所有 Cargo 目标,包括二进制文件、示例、测试套件、基准测试等。用户可以使用--ignore-rust-version标志选择对包进行不支持的构建。

开发辅助:

cargo add会自动选择与你的rust-version兼容的最新版本作为依赖项的版本要求。如果这不是最新版本,cargo add会通知用户,以便他们可以选择保留它或更新你的rust-version

解析器在选择依赖项时可能会考虑 Rust 版本。

其他工具也可能利用它,例如cargo clippyincompatible_msrv代码检查。

注意:可以使用--ignore-rust-version选项忽略rust-version

支持预期

这些是一般预期;有些包可能会在文档中说明不遵循这些预期。

完整性:

所有功能,包括二进制文件和 API,在支持的 Rust 版本上的每个特性下都可用。

已验证:

包的功能在其支持的 Rust 版本上经过验证,包括自动化测试。另请参见我们的 Rust 版本 CI 指南。

可补丁:

当许可证允许时,用户可以用你的包的分支覆盖他们的本地依赖项。在这种情况下,Cargo 可能会加载被补丁依赖项的整个工作区,该工作区应该在支持的 Rust 版本上工作,即使工作区中的其他包有不同的支持 Rust 版本。

依赖支持:

为了支持上述内容,期望每个依赖项的版本要求至少支持一个与你的rust-version兼容的版本。然而,并不期望依赖项规范排除与你的rust-version不兼容的版本。事实上,同时支持两者可以让你平衡支持旧 Rust 版本的用户和不支持旧版本的用户的需求。

设置和更新 Rust 版本

支持哪些 Rust 版本是一种权衡:

  • 维护者不使用 Rust 工具链或其依赖项的新特性的成本
  • 受益于包使用工具链新特性的用户的成本,例如通过从 polyfill 迁移到标准库中的特性来减少构建时间
  • 包对支持旧 Rust 版本的用户的可用性

注意:更改rust-version被视为次要不兼容。

建议:选择一个支持哪些 Rust 版本以及何时更改的策略,以便用户可以将其与自己的策略进行比较,如果不兼容,可以决定是接受失去一般改进,还是接受可能出现无法修复的阻塞性错误的风险。

最简单的支持策略是始终使用最新的 Rust 版本。

根据你的风险状况,下一个最简单的方法是继续支持你的包的旧主要或次要版本,这些版本支持旧的 Rust 版本。

选择支持的 Rust 版本

你的包的用户最有可能将其支持的 Rust 版本与以下内容挂钩:

  • 他们的 Rust 工具链供应商的支持政策,例如 Rust 项目或 Linux 发行版注意:Rust 项目仅为最新版本提供错误修复和安全更新。
  • 用户使用新工具链重新验证其包的固定时间表,例如每年的第一个版本,每 5 个版本。

此外,用户不太可能立即使用新的 Rust 版本,而是需要时间注意并重新验证,或者可能与确切的时间表不一致。

示例版本政策:

  • “N-2”,意思是 “最新版本,有 2 个版本的更新宽限期”
  • 每个偶数版本,有 2 个版本的更新宽限期
  • 本年度的每个版本,有一年的宽限期

注意:要找到当前项目兼容的最低rust-version,可以使用第三方工具,如cargo-msrv

更新时间线

当你的政策规定你不再需要支持某个 Rust 版本时,你可以立即更新rust-version,或在需要时更新。

允许rust-version偏离你的政策,可以为用户提供更长的升级宽限期。然而,这太不可预测,无法依赖于与用户跟踪的 Rust 版本保持一致。

rust-version与你指定的政策偏离得越远,用户就越有可能推断出你不打算的政策,导致对未满足的期望感到沮丧。

当允许偏离时,就会出现 “足够合理” 地放弃支持版本的问题。每个人都可以有不同的合理理由;解决这种讨论可能会让相关各方感到沮丧。这将使那些希望避免这种冲突的人失去权力,特别是新的或临时贡献者,他们要么觉得自己没有资格提出这个问题,要么觉得冲突可能会影响他们的变更被合并的机会。

工作区中的多个政策

Cargo 允许在一个工作区中支持多个政策。

在特定的 Rust 版本下验证特定的包可能会变得复杂。像cargo-hack这样的工具可能会有所帮助。

对于跨政策共享的任何依赖项,必须使用最低公共版本,因为 Cargo 会统一 SemVer 兼容的版本,这可能会限制工作区中具有较高rust-version的成员对共享依赖项特性的访问。

为了允许用户补丁工作区成员上的依赖项,工作区中的每个包都需要能够在工作区支持的最旧 Rust 版本中加载。

当使用incompatible-rust-versions = "fallback"时,一个包的 Rust 版本可能会影响为另一个具有不同 Rust 版本的包选择的依赖版本。有关更多细节,请参见解析器章节。

一个或多个政策

减轻支持旧 Rust 版本的缺点的一种方法是将你的政策应用于你继续支持的包的旧主要或次要版本。你可能仍然需要一个政策,说明开发分支与这些主要或次要版本的发布分支相比支持哪些 Rust 版本。

仅在 “需要时” 更新开发分支可以帮助减少支持的发布分支的数量。

关于可以向后移植到这些发布分支的内容存在疑问。通过在次要版本之间向后移植新功能,下一个可用版本将缺少该功能,这可能被视为破坏变更,违反 SemVer。向后移植变更也有引入错误的风险。

支持旧版本需要成本。此成本取决于包中错误的风险和影响,以及向后移植的可接受程度。按需创建发布分支并将向后移植的负担放在社区身上是平衡此成本的方法。

目前,依赖管理工具还无法报告非最新版本仍受支持,这将责任转移到用户身上,让他们在文档中注意到这一点。

例如,Rust 版本支持政策可能如下:

  • 开发分支跟踪 Rust 项目的最新稳定版本,在需要时更新
  • 更改rust-version时会提高次要版本
  • 项目支持本年度的每个版本,并有另外一年的宽限期
  • 支持某个 Rust 版本的最后一个次要版本将收到社区提供的错误修复
  • 修复必须向后移植到开发分支和所需支持的 Rust 版本之间的所有受支持次要版本
http://www.dtcms.com/a/453286.html

相关文章:

  • MVCC 多版本并发控制
  • 【AI智能体】Coze 打造AI数字人视频生成智能体实战详解:多模态情感计算与云边协同架构
  • 重庆网站建设培训机构学费重庆市官方网站
  • 关系建设的网站上海网站seo招聘
  • Vue router-view和router-link分开写在不同的组件中实现导航栏切换界面
  • Wan2.2-Animate V2版 - 一键替换视频角色,实现角色动作及表情同步迁移替换 支持50系显卡 ComfyUI工作流 一键整合包下载
  • Coordinate Attention for Efficient Mobile Network Design 学习笔记
  • 初识MYSQL —— 数据类型
  • 大型网站建设行情南通专业网站设计制作
  • 【AI智能体】Coze 打造AI数字人视频生成智能体实战详解:从0到1构建可交互虚拟主播
  • LabVIEW使用3D场景光照
  • 河北建设厅网站修改密码在哪wordpress 前台 很慢
  • 数字设计 综合工具 yosys 源码安装与应用简介
  • HikariCP 连接池完全指南
  • 绵竹网站建设大连装修公司
  • C++空值初始化利器:empty.h使用指南
  • 电子版康奈尔笔记写作方案对比
  • (3)SwiftUI 的状态之上:数据流与架构(MVVM in SwiftUI)
  • 郴州网站seo个人兴趣网站设计
  • wordpress企业站源码做qq群头像网站
  • Vue和React怎么选?全面比对
  • C++之再谈类与对象
  • 巫山做网站那家好企业网站的建立
  • 深度学习基础:从原理到实践——第一章感知机(中)
  • 企业网站策划怎么样揭阳模板网站建站
  • 计算机网络第四章(8)——网络层《ICMB网际控制协议》
  • 网络教育网站如何做营销推广做ppt必备网站
  • 移植到Linux,Avalonia初次尝试意外美好
  • asp网站管理系统源码免费申请163邮箱
  • 欧拉公式剖析