不稳定特性

实验性的 Cargo 特性仅在 nightly 版本中可用。欢迎试用这些特性,看看它们是否满足您的需求,以及是否存在任何问题或麻烦。有关特性的更多信息,请查看下面链接的跟踪问题,如果您想接收未来的更新,请点击 GitHub 订阅按钮。

经过一段时间后,如果某个特性没有重大问题,就可以进行稳定化,这样一旦当前的 nightly 版本进入 stable 发布通道(大约 6 到 12 周),该特性就会在 stable 版本中可用。

根据特性的工作方式,可以通过三种不同的方式启用不稳定特性

  • Cargo.toml 中的新语法需要在 Cargo.toml 顶部、任何表格之前添加一个 cargo-features 键。例如:

    # This specifies which new Cargo.toml features are enabled.
    cargo-features = ["test-dummy-unstable"]
    
    [package]
    name = "my-package"
    version = "0.1.0"
    im-a-teapot = true  # This is a new option enabled by test-dummy-unstable.
    
  • 新的命令行标志、选项和子命令需要同时包含 -Z unstable-options CLI 选项。例如,新的 --artifact-dir 选项仅在 nightly 版本中可用

    cargo +nightly build --artifact-dir=out -Z unstable-options

  • -Z 命令行标志用于启用可能尚无接口、接口尚未设计或影响 Cargo 多个部分的更复杂的新功能。例如,可以使用以下命令启用 mtime-on-use 特性:

    cargo +nightly build -Z mtime-on-use

    运行 cargo -Z help 查看可用标志列表。

    任何可以通过 -Z 标志配置的内容也可以在 cargo 配置文件 (.cargo/config.toml) 的 unstable 表格中设置。例如:

    [unstable]
    mtime-on-use = true
    build-std = ["core", "alloc"]
    

下面描述的每个新特性都应解释如何使用它。

有关最新的 nightly 版本,请参见本页面的 nightly 版本

不稳定特性列表

  • 仅在不稳定版本中提供的特性
  • 构建脚本和链接
    • Metabuild — 提供声明式构建脚本。
  • 解析器和特性
  • 输出行为
    • artifact-dir — 添加一个目录,编译产物会复制到该目录。
    • build-dir — 添加一个目录,中间构建产物会存储在该目录。
    • 不同的二进制文件名 — 为构建的二进制文件指定一个与 crate 名称不同的文件名。
    • root-dir — 控制路径打印时参照的根目录。
  • 编译行为
    • mtime-on-use — 每次使用依赖项时更新其最后修改时间戳,提供一种删除未使用产物的机制。
    • doctest-xcompile — 支持使用 --target 标志运行文档测试(doctests)。
    • build-std — 构建标准库而非使用预构建的二进制文件。
    • build-std-features — 设置用于标准库的特性。
    • binary-dep-depinfo — 使 dep-info 文件跟踪二进制依赖项。
    • checksum-freshness — 启用后,判断 crate 是否需要重新构建的决策将使用文件校验和而非文件 mtime。
    • panic-abort-tests — 允许使用“abort”panic 策略运行测试。
    • host-config — 允许为 host 构建目标设置类似于 [target] 的配置。
    • target-applies-to-host — 改变某些标志是否会传递给 host 构建目标的行为。
    • gc — 全局缓存垃圾回收。
    • open-namespaces — 允许多个包参与同一个 API 命名空间。
  • rustdoc
  • Cargo.toml 扩展
  • 信息和元数据
    • 构建计划 — 输出 JSON 信息,说明将要运行哪些命令。
    • unit-graph — 输出 Cargo 内部图结构的 JSON 表示。
    • cargo rustc --print — 调用 rustc 并带上 --print 标志以显示来自 rustc 的信息。
  • 配置
    • config-include — 增加了配置文件包含其他文件的能力。
    • cargo config — 添加了一个用于查看配置文件的新的子命令。
  • 注册表
    • publish-timeout — 控制从上传 crate 到在索引中可用之间的超时时间。
    • asymmetric-token — 添加了对使用非对称加密进行身份验证令牌的支持 (cargo:paseto 提供者)。
  • 其他
    • gitoxide — 对于一组操作,使用 gitoxide 代替 git2
    • script — 启用对单文件 .rs 包的支持。
    • lockfile-path — 允许指定锁定文件的路径,而不是默认路径 <workspace_root>/Cargo.lock
    • package-workspace — 允许在一个工作空间中打包和发布多个 crate。
    • native-completions — 将 cargo shell 补全移动到原生补全。
    • warnings — 控制警告行为;提供允许或拒绝警告的选项。
    • 包消息格式cargo package 的消息格式。

allow-features

此永久不稳定的标志使得只能使用列出的不稳定特性集。具体来说,如果您传递 -Zallow-features=foo,bar,您将能够继续向 cargo 传递 -Zfoo-Zbar,但无法传递 -Zbaz。您可以传递一个空字符串(-Zallow-features=)来禁用所有不稳定特性。

-Zallow-features 还限制哪些不稳定特性可以传递给 Cargo.toml 中的 cargo-features 条目。例如,如果您想允许

cargo-features = ["test-dummy-unstable"]

其中 test-dummy-unstable 是不稳定特性,那么 -Zallow-features= 也会禁用该特性,而 -Zallow-features=test-dummy-unstable 会允许它。

传递给 cargo 的 -Zallow-features 特性列表也会传递给 cargo 最终调用的任何 Rust 工具(如 rustcrustdoc)。因此,如果您运行 cargo -Zallow-features=,则无法使用任何不稳定的 Cargo 或 Rust 特性。

no-index-update

-Z no-index-update 标志确保 Cargo 不尝试更新注册表索引。这适用于 Crater 等会发出许多 Cargo 命令的工具,您希望避免每次更新索引的网络延迟。

mtime-on-use

  • Original Issue: #6477
  • Cache usage meta tracking issue: #7150

-Z mtime-on-use 标志是一个实验性特性,让 Cargo 更新已使用文件的 mtime,以便像 cargo-sweep 这样的工具更容易检测哪些文件已过时。对于许多工作流程,这需要在所有 cargo 调用中设置。为了更实用,在 .cargo/config.toml 中设置 unstable.mtime_on_use 标志或相应的环境变量会将 -Z mtime-on-use 应用于所有 nightly cargo 调用。(stable 版本会忽略此配置标志)

avoid-dev-deps

在运行 cargo installcargo build 等命令时,Cargo 目前要求下载开发依赖(dev-dependencies),即使它们未被使用。-Z avoid-dev-deps 标志允许 Cargo 在不需要开发依赖时避免下载它们。如果跳过开发依赖,将不会生成 Cargo.lock 文件。

minimal-versions

注意:不建议使用此特性。因为它强制所有传递性依赖都使用最低版本,所以其用处有限,因为并非所有外部依赖都声明了正确的最低版本边界。未来的计划是修改此特性,使其仅对直接依赖项强制使用最低版本。

生成 Cargo.lock 文件时,-Z minimal-versions 标志会将依赖项解析到满足要求的最低 SemVer 版本(而非最高版本)。

此标志的预期用例是在持续集成期间检查 Cargo.toml 中指定的版本是否正确反映了您实际使用的最低版本。也就是说,如果 Cargo.toml 中写着 foo = "1.0.0",您不会意外依赖于仅在 foo 1.5.0 中添加的特性。

direct-minimal-versions

生成 Cargo.lock 文件时,-Z direct-minimal-versions 标志仅对直接依赖项将依赖项解析到满足要求的最低 SemVer 版本(而非最高版本)。

此标志的预期用例是在持续集成期间检查 Cargo.toml 中指定的版本是否正确反映了您实际使用的最低版本。也就是说,如果 Cargo.toml 中写着 foo = "1.0.0",您不会意外依赖于仅在 foo 1.5.0 中添加的特性。

间接依赖项照常解析,以免被其最低版本验证阻塞。

artifact-dir

此特性允许您指定构建后将产物复制到的目录。通常,产物仅写入 target/releasetarget/debug 目录。然而,确定确切的文件名可能很棘手,因为您需要解析 JSON 输出。--artifact-dir 标志使您可以更容易地按预期访问产物。请注意,产物是被复制的,因此原始文件仍位于 target 目录中。示例:

cargo +nightly build --artifact-dir=out -Z unstable-options

这也可以在 .cargo/config.toml 文件中指定。

[build]
artifact-dir = "out"

build-dir

中间构建产物将存储的目录。中间产物是在构建过程中由 Rustc/Cargo 生成的。

[build]
build-dir = "out"

build.build-dir

  • 类型:字符串(路径)
  • 默认值:默认为 build.target-dir 的值
  • 环境变量:CARGO_BUILD_BUILD_DIR

构建过程中使用的内部文件的存放路径。

此选项支持路径模板。

可用模板变量

  • {workspace-root} 解析为当前工作空间的根目录。
  • {cargo-cache-home} 解析为 CARGO_HOME
  • {workspace-path-hash} 解析为清单文件路径的哈希值

root-dir

  • Original Issue: #9887
  • Tracking Issue: None (not currently slated for stabilization)

-Zroot-dir 标志设置了路径打印时参照的根目录。这会影响诊断信息以及 file!() 宏输出的路径。

doctest-xcompile

当传递目标平台时,此标志改变 cargo test 处理文档测试(doctests)的行为。目前,如果传递的目标平台与 host 平台不同,cargo 会直接跳过文档测试。如果存在此标志,cargo 将照常继续,将测试传递给 doctest,同时也会向其传递一个 --target 选项,并启用 -Zunstable-features --enable-per-target-ignores 并传递来自 .cargo/config.toml 的信息。有关更多信息,请参见 rustc 的相关 issue。

cargo test --target foo -Zdoctest-xcompile

构建计划

构建计划特性已弃用,并可能在未来版本中移除。参见 https://github.com/rust-lang/cargo/issues/7614

build 命令的 --build-plan 参数将输出 JSON 格式的信息,说明会运行哪些命令,而不实际执行任何操作。这在与另一个构建工具集成时很有用。示例:

cargo +nightly build --build-plan -Z unstable-options

Metabuild

Metabuild 是一种实现声明式构建脚本的特性。您无需编写 build.rs 脚本,而是在 Cargo.tomlmetabuild 键中指定构建依赖项列表。Cargo 会自动生成一个构建脚本,按顺序运行每个构建依赖项。Metabuild 包随后可以读取 Cargo.toml 中的元数据来指定其行为。

Cargo.toml 顶部包含 cargo-features,在 package 中添加 metabuild 键,在 build-dependencies 中列出依赖项,并在 package.metadata 下添加 metabuild 包所需的任何元数据。例如:

cargo-features = ["metabuild"]

[package]
name = "mypackage"
version = "0.0.1"
metabuild = ["foo", "bar"]

[build-dependencies]
foo = "1.0"
bar = "1.0"

[package.metadata.foo]
extra-info = "qwerty"

Metabuild 包应包含一个名为 metabuild 的公共函数,该函数执行与常规 build.rs 脚本相同的操作。

public-dependency

‘public-dependency’ 特性允许将依赖项标记为‘公共’或‘私有’。启用此特性后,会将附加信息传递给 rustc,以便 exported_private_dependencies lint 可以正常工作。

要启用此特性,您可以使用 -Zpublic-dependency

cargo +nightly run -Zpublic-dependency

[unstable] 表格,例如,

# .cargo/config.toml
[unstable]
public-dependency = true

public-dependency 也可以在 cargo-features 中启用,但此方式已弃用并将很快移除

cargo-features = ["public-dependency"]

[dependencies]
my_dep = { version = "1.2.3", public = true }
private_dep = "2.0.0" # Will be 'private' by default

文档更新

  • 对于工作空间的“dependencies 表格”部分,将 public 作为 workspace.dependencies 的一个不支持字段包含进去。

msrv-policy

RFC 2495 下 MSRV 感知的 cargo 特性的总括性不稳定特性。

MSRV 感知的 cargo add

这已在 1.79 版本中稳定,参见 #13608

MSRV 感知的解析器

这已在 1.84 版本中稳定,参见 #14639

incompatible_toolchain 错误转换为 lint

未实现

cargo add, cargo update--update-rust-version 标志

未实现

package.rust-version = "toolchain"

未实现

更新 cargo new 模板以设置 package.rust-version = "toolchain"

未实现

precise-pre-release

即使项目的 Cargo.toml 未指定预发布版本,precise-pre-release 特性也允许使用 update --precise 选择预发布版本。

例如,考虑以下 Cargo.toml

[dependencies]
my-dependency = "0.1.1"

可以使用 update -Zunstable-options my-dependency --precise 0.1.2-pre.0my-dependency 更新到预发布版本。这是因为 0.1.2-pre.0 被认为与 0.1.1 兼容。无法以同样的方式从 0.1.1 升级到 0.2.0-pre.0

sbom

sbom 构建配置允许在每个编译产物旁边生成所谓的 SBOM 前置文件。软件物料清单(SBOM)工具可以整合这些生成的文件,从 cargo 构建过程中收集通过其他方式难以或不可能获取的重要信息。

要启用此特性,可以在 .cargo/config.toml 中设置 sbom 字段

[unstable]
sbom = true

[build]
sbom = true

或将 CARGO_BUILD_SBOM 环境变量设置为 true。该功能隐藏在 -Z sbom 标志后面。

生成的输出文件是 JSON 格式,遵循命名约定 <产物>.cargo-sbom.json。JSON 文件包含有关依赖项、目标、特性和所用 rustc 编译器的信息。

SBOM 前置文件会为所有提升到 target 或 artifact 目录的可执行和可链接输出生成。

Cargo 为 crate 设置的环境变量

  • CARGO_SBOM_PATH – 生成的 SBOM 前置文件列表,由平台路径分隔符分隔。可以使用 std::env::split_paths 分割列表。

SBOM 前置文件 schema

{
  // Schema version.
  "version": 1,
  // Index into the crates array for the root crate.
  "root": 0,
  // Array of all crates. There may be duplicates of the same crate if that
  // crate is compiled differently (different opt-level, features, etc).
  "crates": [
    {
      // Package ID specification
      "id": "path+file:///sample-package#0.1.0",
      // List of target kinds: bin, lib, rlib, dylib, cdylib, staticlib, proc-macro, example, test, bench, custom-build
      "kind": ["bin"],
      // Enabled feature flags.
      "features": [],
      // Dependencies for this crate.
      "dependencies": [
        {
          // Index in to the crates array.
          "index": 1,
          // Dependency kind: 
          // Normal: A dependency linked to the artifact produced by this crate.
          // Build: A compile-time dependency used to build this crate (build-script or proc-macro).
          "kind": "normal"
        },
        {
          // A crate can depend on another crate with both normal and build edges.
          "index": 1,
          "kind": "build"
        }
      ]
    },
    {
      "id": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.16",
      "kind": ["bin"],
      "features": [],
      "dependencies": []
    }
  ],
  // Information about rustc used to perform the compilation.
  "rustc": {
    // Compiler version
    "version": "1.86.0-nightly",
    // Compiler wrapper
    "wrapper": null,
    // Compiler workspace wrapper
    "workspace_wrapper": null,
    // Commit hash for rustc
    "commit_hash": "bef3c3b01f690de16738b1c9f36470fbfc6ac623",
    // Host target triple
    "host": "x86_64-pc-windows-msvc",
    // Verbose version string: `rustc -vV`
    "verbose_version": "rustc 1.86.0-nightly (bef3c3b01 2025-02-04)\nbinary: rustc\ncommit-hash: bef3c3b01f690de16738b1c9f36470fbfc6ac623\ncommit-date: 2025-02-04\nhost: x86_64-pc-windows-msvc\nrelease: 1.86.0-nightly\nLLVM version: 19.1.7\n"
  }
}

update-breaking

允许使用 --breaking 标志在 Cargo.toml 中升级跨越 SemVer 不兼容版本的依赖项版本要求。

这仅适用于符合以下条件的依赖项:

  • 该包是工作空间成员的依赖项
  • 该依赖项未被重命名
  • 存在 SemVer 不兼容的版本
  • 使用了“SemVer 运算符”(默认为 ^

用户可以通过在命令行上指定包来进一步限制哪些包被升级。

示例:

$ cargo +nightly -Zunstable-options update --breaking
$ cargo +nightly -Zunstable-options update --breaking clap

这旨在扮演与 cargo-upgrade 类似的角色

build-std

build-std 特性使 Cargo 能够将标准库本身作为 crate 图编译的一部分进行编译。此特性在历史上也被称为“std-aware Cargo”。此特性仍处于非常早期的开发阶段,也可能是 Cargo 的一项大规模特性添加。这是一个非常庞大且难以文档化的特性,即使是其目前的最小形式也是如此,因此如果您想了解最新进展,会需要关注其跟踪仓库及其相关 issue。

目前实现的功能隐藏在名为 -Z build-std 的标志后面。此标志表示 Cargo 应使用与主构建本身相同的 profile 从源代码编译标准库。请注意,要使其工作,您需要提供标准库的源代码,目前唯一支持的方法是添加 rust-src rustup 组件

$ rustup component add rust-src --toolchain nightly

用法如下:

$ cargo new foo
$ cd foo
$ cargo +nightly run -Z build-std --target x86_64-unknown-linux-gnu
   Compiling core v0.0.0 (...)
   ...
   Compiling foo v0.1.0 (...)
    Finished dev [unoptimized + debuginfo] target(s) in 21.00s
     Running `target/x86_64-unknown-linux-gnu/debug/foo`
Hello, world!

这里我们在 debug 模式下重新编译了标准库,并带有 debug 断言(就像编译 src/main.rs 一样),最后所有内容都链接在一起。

使用 -Z build-std 会隐式编译稳定的 crate,包括 corestdallocproc_macro。如果您使用 cargo test,它还会编译 test crate。如果您在不支持其中一些 crate 的环境中使用,也可以向 -Zbuild-std 传递参数

$ cargo +nightly build -Z build-std=core,alloc

这里的值是用逗号分隔的标准库 crate 列表,表示要构建哪些 crate。

要求

总而言之,目前使用 -Z build-std 的要求列表如下:

  • 您必须通过 rustup component add rust-src 安装标准库(libstd)的源代码。
  • 您必须同时使用 nightly 版本的 Cargo 和 nightly 版本的 rustc。
  • -Z build-std 标志必须传递给所有 cargo 调用。

报告 bug 和提供帮助

-Z build-std 特性处于非常早期的开发阶段!Cargo 的这项特性历史悠久且范围非常广阔,这只是一个开始。如果您想报告 bug,请将其报告到:

此外,如果您想看到尚未实现的特性,或者有什么地方不完全符合您的期望,请随时查看跟踪仓库的问题跟踪器,如果其中没有您的问题,请提交一个新问题!

build-std-features

此标志是 -Zbuild-std 特性标志的同级标志。这将配置构建标准库时为标准库本身启用的特性。目前默认启用的特性是 backtracepanic-unwind。此标志需要一个逗号分隔的列表,如果提供了该列表,它将覆盖默认启用的特性列表。

binary-dep-depinfo

  • Tracking rustc issue: #63012

-Z binary-dep-depinfo 标志使 Cargo 将相同的标志转发给 rustc,从而使 rustc 将所有二进制依赖项的路径包含在“dep info”文件(扩展名为 .d)中。Cargo 随后使用这些信息进行变更检测(如果任何二进制依赖项发生变化,则 crate 将被重新构建)。主要用例是构建编译器本身,编译器对标准库有隐式依赖,否则这些依赖将不会被跟踪以进行变更检测。

checksum-freshness

-Z checksum-freshness 标志将用文件校验和值替换 Cargo 指纹中使用的文件 mtime。这对于 mtime 实现较差的系统或 CI/CD 环境中最有用。校验和算法可能会在 Cargo 版本之间发生变化,恕不另行通知。Cargo 使用指纹来确定何时需要重新构建 crate。

目前,构建脚本导入的文件将继续使用 mtime,即使启用了 checksum-freshness 也是如此。这不是一个长期的解决方案。

panic-abort-tests

-Z panic-abort-tests 标志将启用 nightly 支持,以便使用 -Cpanic=abort 编译测试 harness crate。如果没有此标志,Cargo 将使用 -Cpanic=unwind 编译测试及其所有依赖项,因为这是 test 这个 crate 知道如何操作的唯一方式。然而,截至 rust-lang/rust#64158test crate 支持使用 test-per-process 的 -C panic=abort,这有助于避免多次编译 crate 图。

目前尚不清楚此特性将如何在 Cargo 中稳定化,但我们希望以某种方式将其稳定化!

config-include

此特性需要 -Zconfig-include 命令行选项。

配置文件中的 include 键可用于加载另一个配置文件。它可以接受一个字符串,表示相对于当前配置文件的另一个文件路径,或者一个配置文件路径数组。只接受以 .toml 结尾的路径。

# a path ending with `.toml`
include = "path/to/mordor.toml"

# or an array of paths
include = ["frodo.toml", "samwise.toml"]

与其他配置值不同,include 键的合并行为有所不同。当配置文件包含 include 键时:

  1. 首先从 include 路径加载配置值。
    • 如果 include 键的值是路径数组,则按从左到右的顺序加载并合并每个路径中的配置值。
    • 如果从 include 路径加载的配置值也包含 include 键,则递归执行此步骤。
  2. 然后,将当前配置文件的值合并到从 include 路径加载的配置之上。

target-applies-to-host

  • Original Pull Request: #9322
  • Tracking Issue: #9453

历史上,Cargo 对于来自环境变量和 [target]linkerrustflags 配置选项是否应用于构建脚本、插件以及始终为 host 平台构建的其他产物的行为一直有些不一致。当不传递 --target 时,Cargo 对构建脚本和其他所有编译产物应用相同的 linkerrustflags。然而,当传递 --target 时,Cargo 会应用 [target.<host triple>] 中的 linker,但不拾取任何 rustflags 配置。这种双重行为令人困惑,同时也使得正确配置构建变得困难,尤其当 host triple 和 target triple 恰好相同时,但旨在构建主机上运行的产物仍需要以不同的方式配置。

-Ztarget-applies-to-host 启用了 Cargo 配置文件中的顶级 target-applies-to-host 设置,允许用户选择对这些属性采用不同的(更一致的)行为。当配置文件中未设置或设置为 true 时,保留现有的 Cargo 行为(但请参阅 -Zhost-config,它改变了此默认值)。当设置为 false 时,无论是否向 Cargo 传递 --target[target.<host triple>]RUSTFLAGS[build] 中的任何选项都不会应用于 host 产物。要自定义旨在在 host 上运行的产物,请使用 [host]host-config)。

将来,target-applies-to-host 可能会默认为 false,以提供更合理和一致的默认行为。

# config.toml
target-applies-to-host = false
cargo +nightly -Ztarget-applies-to-host build --target x86_64-unknown-linux-gnu

host-config

  • Original Pull Request: #9322
  • Tracking Issue: #9452

配置文件中的 host 键可用于将标志传递给 host 构建目标,例如在交叉编译时必须在 host 系统而非 target 系统上运行的构建脚本。它支持通用表格和 host 架构特定表格。匹配的 host 架构特定表格优先于通用 host 表格。

它需要设置 -Zhost-config-Ztarget-applies-to-host 命令行选项,并且在 Cargo 配置文件中设置 target-applies-to-host = false

# config.toml
[host]
linker = "/path/to/host/linker"
[host.x86_64-unknown-linux-gnu]
linker = "/path/to/host/arch/linker"
rustflags = ["-Clink-arg=--verbose"]
[target.x86_64-unknown-linux-gnu]
linker = "/path/to/target/linker"

x86_64-unknown-linux-gnu host 上构建时,上面的通用 host 表格将被完全忽略,因为 host.x86_64-unknown-linux-gnu 表格具有优先权。

设置 -Zhost-config 会将 target-applies-to-host 的默认值从 true 改为 false

cargo +nightly -Ztarget-applies-to-host -Zhost-config build --target x86_64-unknown-linux-gnu

unit-graph

可以将 --unit-graph 标志传递给任何构建命令(buildcheckruntestbenchdoc 等),以向标准输出(stdout)输出一个 JSON 对象,该对象表示 Cargo 的内部单元图(unit graph)。不会实际构建任何东西,命令打印后立即返回。每个“单元”对应一次编译器的执行。这些对象还包括每个单元所依赖的单元。

cargo +nightly build --unit-graph -Z unstable-options

这种结构提供了 Cargo 所见依赖关系更完整的视图。特别是,“features”字段支持新的特性解析器,依赖项可以针对不同的特性多次构建。cargo metadata 从根本上无法表示不同类型依赖项之间特性的关系,并且特性现在取决于运行的命令以及选择的包和目标。此外,它还可以提供关于包内依赖项(如构建脚本或测试)的详细信息。

以下是 JSON 结构的描述

{
  /* Version of the JSON output structure. If any backwards incompatible
     changes are made, this value will be increased.
  */
  "version": 1,
  /* Array of all build units. */
  "units": [
    {
      /* An opaque string which indicates the package.
         Information about the package can be obtained from `cargo metadata`.
      */
      "pkg_id": "my-package 0.1.0 (path+file:///path/to/my-package)",
      /* The Cargo target. See the `cargo metadata` documentation for more
         information about these fields.
         https://doc.rust-lang.net.cn/cargo/commands/cargo-metadata.html
      */
      "target": {
        "kind": ["lib"],
        "crate_types": ["lib"],
        "name": "my_package",
        "src_path": "/path/to/my-package/src/lib.rs",
        "edition": "2018",
        "test": true,
        "doctest": true
      },
      /* The profile settings for this unit.
         These values may not match the profile defined in the manifest.
         Units can use modified profile settings. For example, the "panic"
         setting can be overridden for tests to force it to "unwind".
      */
      "profile": {
        /* The profile name these settings are derived from. */
        "name": "dev",
        /* The optimization level as a string. */
        "opt_level": "0",
        /* The LTO setting as a string. */
        "lto": "false",
        /* The codegen units as an integer.
           `null` if it should use the compiler's default.
        */
        "codegen_units": null,
        /* The debug information level as an integer.
           `null` if it should use the compiler's default (0).
        */
        "debuginfo": 2,
        /* Whether or not debug-assertions are enabled. */
        "debug_assertions": true,
        /* Whether or not overflow-checks are enabled. */
        "overflow_checks": true,
        /* Whether or not rpath is enabled. */
        "rpath": false,
        /* Whether or not incremental is enabled. */
        "incremental": true,
        /* The panic strategy, "unwind" or "abort". */
        "panic": "unwind"
      },
      /* Which platform this target is being built for.
         A value of `null` indicates it is for the host.
         Otherwise it is a string of the target triple (such as
         "x86_64-unknown-linux-gnu").
      */
      "platform": null,
      /* The "mode" for this unit. Valid values:

         * "test" --- Build using `rustc` as a test.
         * "build" --- Build using `rustc`.
         * "check" --- Build using `rustc` in "check" mode.
         * "doc" --- Build using `rustdoc`.
         * "doctest" --- Test using `rustdoc`.
         * "run-custom-build" --- Represents the execution of a build script.
      */
      "mode": "build",
      /* Array of features enabled on this unit as strings. */
      "features": ["somefeat"],
      /* Whether or not this is a standard-library unit,
         part of the unstable build-std feature.
         If not set, treat as `false`.
      */
      "is_std": false,
      /* Array of dependencies of this unit. */
      "dependencies": [
        {
          /* Index in the "units" array for the dependency. */
          "index": 1,
          /* The name that this dependency will be referred as. */
          "extern_crate_name": "unicode_xid",
          /* Whether or not this dependency is "public",
             part of the unstable public-dependency feature.
             If not set, the public-dependency feature is not enabled.
          */
          "public": false,
          /* Whether or not this dependency is injected into the prelude,
             currently used by the build-std feature.
             If not set, treat as `false`.
          */
          "noprelude": false
        }
      ]
    },
    // ...
  ],
  /* Array of indices in the "units" array that are the "roots" of the
     dependency graph.
  */
  "roots": [0],
}

Profile rustflags 选项

此特性在 [profile] 部分提供了一个新选项,用于指定直接传递给 rustc 的标志。可以这样启用:

cargo-features = ["profile-rustflags"]

[package]
# ...

[profile.release]
rustflags = [ "-C", "..." ]

要在 Cargo 配置中设置此 profile,需要使用 -Z profile-rustflags[unstable] 表格来启用它。例如,

# .cargo/config.toml
[unstable]
profile-rustflags = true

[profile.release]
rustflags = [ "-C", "..." ]

rustdoc-map

此特性添加了传递给 rustdoc 的配置设置,以便在依赖项未被文档化时,rustdoc 可以生成链接到其文档托管在其他位置的依赖项。首先,将其添加到 .cargo/config 中:

[doc.extern-map.registries]
crates-io = "https://docs.rs/"

然后,在构建文档时,使用以下标志使依赖项的链接指向 docs.rs

cargo +nightly doc --no-deps -Zrustdoc-map

registries 表格包含注册表名称到链接 URL 的映射。URL 中可以包含标记 {pkg_name}{version},它们将被替换为相应的值。如果两者都未指定,则 Cargo 默认在 URL 末尾追加 {pkg_name}/{version}/

另一个配置设置可用于重定向标准库链接。默认情况下,rustdoc 会创建指向 https://doc.rust-lang.net.cn/nightly/ 的链接。要改变此行为,请使用 doc.extern-map.std 设置

[doc.extern-map]
std = "local"

值为 "local" 表示链接到 rustc sysroot 中找到的文档。如果您使用 rustup,可以使用 rustup component add rust-docs 安装此文档。

默认值为 "remote"

该值也可以接受一个用于自定义位置的 URL。

per-package-target

per-package-target 特性在清单文件(manifest)中添加了两个键:package.default-targetpackage.forced-target。第一个键使包在默认情况下(即未传递 --target 参数时)为某个目标编译。第二个键使包始终为该目标编译。

示例:

[package]
forced-target = "wasm32-unknown-unknown"

在此示例中,该 crate 始终为 wasm32-unknown-unknown 目标构建,例如因为它可以作为插件用于在 host 目标(或命令行指定目标)上运行的主程序。

artifact dependencies

  • Tracking Issue: #9096
  • Original Pull Request: #9992

Artifact 依赖项允许 Cargo 包依赖于 bincdylibstaticlib crate,并在编译时使用这些 crate 构建的产物。

使用 -Z bindeps 运行 cargo 来启用此功能。

artifact dependencies: 依赖项声明

Artifact 依赖项在 Cargo.toml 的依赖项声明中添加了以下键:

  • artifact — 这指定了要构建的 Cargo Target。通常,如果没有此字段,Cargo 只会从依赖项中构建 [lib] 目标。此字段允许指定将构建哪个目标,并在构建时作为二进制文件可用

    • "bin" — 编译后的可执行二进制文件,对应于依赖项清单文件中所有 [[bin]] 部分。
    • "bin:<bin-name>" — 编译后的可执行二进制文件,对应于由给定 <bin-name> 指定的特定二进制目标。
    • "cdylib" — C 兼容的动态库,对应于依赖项清单文件中包含 crate-type = ["cdylib"][lib] 部分。
    • "staticlib" — C 兼容的静态库,对应于依赖项清单文件中包含 crate-type = ["staticlib"][lib] 部分。

    artifact 的值可以是一个字符串,也可以是一个字符串数组,用于指定多个目标。

    示例:

    [dependencies]
    bar = { version = "1.0", artifact = "staticlib" }
    zoo = { version = "1.0", artifact = ["bin:cat", "bin:dog"]}
    
  • lib — 这是一个布尔值,指示是否也将依赖项的库构建为正常的 Rust lib 依赖项。此字段只能在指定 artifact 时指定。

    当指定 artifact 时,此字段的默认值为 false。如果设置为 true,则依赖项的 [lib] 目标也将为声明包正在构建的平台目标构建。这允许该包除了作为 artifact 依赖项外,还可以像普通依赖项一样在 Rust 代码中使用该依赖项。

    示例:

    [dependencies]
    bar = { version = "1.0", artifact = "bin", lib = true }
    
  • target — 要为依赖项构建的平台目标。此字段只能在指定 artifact 时指定。

    如果未指定此字段,默认值取决于依赖项的类型。对于构建依赖项(build dependencies),它将为 host 目标构建。对于所有其他依赖项,它将为声明包正在构建的相同目标构建。

    对于构建依赖项,它还可以采用特殊值 "target",这意味着为该包正在构建的相同目标构建依赖项。

    [build-dependencies]
    bar = { version = "1.0", artifact = "cdylib", target = "wasm32-unknown-unknown"}
    same-target = { version = "1.0", artifact = "bin", target = "target" }
    

artifact dependencies: 环境变量

构建 artifact 依赖项后,Cargo 提供以下环境变量,您可以使用它们来访问 artifact

  • CARGO_<ARTIFACT-TYPE>_DIR_<DEP> — 这是包含来自依赖项的所有 artifact 的目录。

    <ARTIFACT-TYPE> 是为依赖项指定的 artifact 类型(大写,如 CDYLIBSTATICLIBBIN),而 <DEP> 是依赖项的名称。与其他 Cargo 环境变量一样,依赖项名称会被转换为大写,并将破折号替换为下划线。

    如果您的清单文件重命名了依赖项,<DEP> 对应于您指定的名称,而非原始包名。

  • CARGO_<ARTIFACT-TYPE>_FILE_<DEP>_<NAME> — 这是 artifact 的完整路径。

    <ARTIFACT-TYPE> 是为依赖项指定的 artifact 类型(如上所示大写),<DEP> 是依赖项的名称(如上所示转换),而 <NAME> 是来自依赖项的 artifact 名称。

    请注意,<NAME> 不会以任何方式修改自提供 artifact 的 crate 中指定的 name,如果未指定 name,则使用 crate 名称;例如,它可能是小写,或包含破折号。

    为了方便起见,如果 artifact 名称与原始包名匹配,cargo 还会提供此变量的一个副本,并省略 _<NAME> 后缀。例如,如果 cmake crate 提供了一个名为 cmake 的二进制文件,Cargo 会同时提供 CARGO_BIN_FILE_CMAKECARGO_BIN_FILE_CMAKE_cmake

对于每种类型的依赖项,这些变量会被提供给构建过程中可以访问该类型依赖项的相应部分

  • 对于构建依赖项(build-dependencies),这些变量提供给 build.rs 脚本,并且可以使用 std::env::var_os 访问。(与任何操作系统文件路径一样,这些路径可能不是有效的 UTF-8。)
  • 对于普通依赖项,这些变量在 crate 编译期间提供,并且可以使用 env! 宏访问。
  • 对于开发依赖项(dev-dependencies),这些变量在示例、测试和基准测试编译期间提供,并且可以使用 env! 宏访问。

artifact dependencies: 示例

示例:在构建脚本中使用可执行二进制文件

Cargo.toml 文件中,您可以指定对一个二进制文件的依赖,使其可供构建脚本使用

[build-dependencies]
some-build-tool = { version = "1.0", artifact = "bin" }

然后,在构建脚本内部,可以在构建时执行该二进制文件

fn main() {
    let build_tool = std::env::var_os("CARGO_BIN_FILE_SOME_BUILD_TOOL").unwrap();
    let status = std::process::Command::new(build_tool)
        .arg("do-stuff")
        .status()
        .unwrap();
    if !status.success() {
        eprintln!("failed!");
        std::process::exit(1);
    }
}

示例:在构建脚本中使用 cdylib artifact

使用该 artifact 的包中的 Cargo.toml 文件,为特定构建目标构建 bar 库作为 cdylib

[build-dependencies]
bar = { artifact = "cdylib", version = "1.0", target = "wasm32-unknown-unknown" }

…以及 build.rs 中的构建脚本。

fn main() {
    wasm::run_file(std::env::var("CARGO_CDYLIB_FILE_BAR").unwrap());
}

示例:在二进制文件自身中使用 binary artifact 及其对应的库

使用该 artifact 的包中的 Cargo.toml 文件,构建 bar 二进制文件以作为 artifact 包含,同时使其也可用作库…

[dependencies]
bar = { artifact = "bin", version = "1.0", lib = true }

…以及使用 main.rs 的可执行文件。

fn main() {
    bar::init();
    command::run(env!("CARGO_BIN_FILE_BAR"));
}

publish-timeout

配置文件中的 publish.timeout 键可用于控制 cargo publish 从发布包到注册表到其在本地索引中可用之间等待的时间。

超时时间设置为 0 将阻止任何检查发生。当前默认值为 60 秒。

它需要设置 -Zpublish-timeout 命令行选项。

# config.toml
[publish]
timeout = 300  # in seconds

asymmetric-token

-Z asymmetric-token 标志启用 cargo:paseto 凭证提供者,它允许 Cargo 向注册表进行身份验证,而无需在网络上传输秘密信息。

config.tomlcredentials.toml 文件中,有一个名为 private-key 的字段,它是使用 PASERK 的 secret 子集 格式化的私钥,用于签署非对称令牌。

可以使用 cargo login --generate-keypair 命令生成密钥对,该命令将

  • 以当前推荐的方式生成一个公钥/私钥对。
  • 将私钥保存在 credentials.toml 中。
  • PASERK public 格式 打印公钥。

建议将 private-key保存在 credentials.toml 中。config.toml 也支持该字段,主要是为了可以通过关联的环境变量进行设置,这是在 CI 环境中提供它的推荐方式。这种设置方式与我们用于设置秘密令牌的 token 字段类似。

还有一个可选字段名为 private-key-subject,它是注册表选择的字符串。此字符串将作为非对称令牌的一部分包含,并且不应该是秘密信息。它适用于罕见的用例,例如“证明中央 CA 服务器授权了此操作的加密证据”。Cargo 要求它必须是无空格的可打印 ASCII 字符。需要非 ASCII 数据的注册表应对其进行 base64 编码。

这两个字段都可以通过 cargo login --registry=name --private-key --private-key-subject="subject" 命令设置,该命令将提示您输入键值。

一个注册表最多只能设置 private-keytoken 中的一个。

所有 PASETO 都将包含 iat,即当前时间的 ISO 8601 格式表示。Cargo 将在适当的情况下包含以下信息:

  • sub 一个可选的非秘密字符串,由注册表选择,预计在每个请求中声明。其值将是 config.toml 文件中的 private-key-subject
  • mutation 如果存在,表示此请求是一个修改操作(如果不存在则是只读操作),必须是字符串 publishyankunyank 之一。
    • name 与此请求相关的 crate 名称。
    • vers 与此请求相关的 crate 版本字符串。
    • cksum crate 内容的 SHA256 哈希值,一个 64 个小写十六进制数字组成的字符串,仅当 mutation 等于 publish 时必须存在。
  • challenge 本次会话中从该服务器收到 401/403 响应时附带的 challenge 字符串。发布 challenge 的注册表必须跟踪哪些 challenge 已被发布/使用,并且在同一有效期内绝不接受同一 challenge 多次(避免需要跟踪所有已发布的 challenge)。

“footer”(签名的一部分)将是一个 UTF-8 编码的 JSON 字符串,并包含:

  • url Cargo 获取 config.json 文件的符合 RFC 3986 的 URL,
    • 如果这是带有 HTTP 索引的注册表,那么这是所有索引查询的基 URL。
    • 如果这是带有 GIT 索引的注册表,那么这是 Cargo 克隆索引时使用的 URL。
  • kid 用于签署请求的私钥标识符,使用 PASERK IDs 标准。

PASETO 包含被签署的消息,因此服务器无需从请求中重构准确的字符串即可检查签名。服务器确实需要检查 PASETO 中的签名对于其中的字符串是否有效,以及该字符串的内容是否与请求匹配。如果请求应包含某个 claim 但 PASETO 中缺失,则必须拒绝该请求。

cargo config

cargo config 子命令提供了一种查看 cargo 加载的配置文件的方式。它目前包含 get 子命令,该子命令可以接受一个可选的配置值进行显示。

cargo +nightly -Zunstable-options config get build.rustflags

如果未包含配置值,它将显示所有配置值。请查看 --help 输出以了解更多可用选项。

rustc --print

cargo rustc --print=VAL--print 标志转发给 rustc,以便从 rustc 提取信息。这会运行 rustc 并带上相应的 --print 标志,然后立即退出而不进行编译。将此作为 Cargo 标志暴露,允许 Cargo 根据当前配置注入正确的目标平台和 RUSTFLAGS。

主要用例是运行 cargo rustc --print=cfg 来获取适当目标的配置值,并受任何其他 RUSTFLAGS 的影响。

不同的二进制文件名

different-binary-name 特性允许设置二进制文件的文件名,而无需遵守对 crate 名称的限制。例如,crate 名称必须只使用字母数字字符或 -_,并且不能为空。

filename 参数应包含二进制文件扩展名,cargo 会自行确定适当的扩展名并用于二进制文件。

filename 参数仅在清单文件(manifest)的 [[bin]] 部分中可用。

cargo-features = ["different-binary-name"]

[package]
name =  "foo"
version = "0.0.1"

[[bin]]
name = "foo"
filename = "007bar"
path = "src/main.rs"

scrape-examples

-Z rustdoc-scrape-examples 标志告诉 Rustdoc 在当前工作空间中搜索函数调用。然后将这些调用点包含到文档中。可以这样使用此标志:

cargo doc -Z unstable-options -Z rustdoc-scrape-examples

默认情况下,Cargo 会从被文档化的包的示例目标(example targets)中抓取示例。您可以使用 doc-scrape-examples 标志单独启用或禁用从目标中抓取示例,例如:

# Enable scraping examples from a library
[lib]
doc-scrape-examples = true

# Disable scraping examples from an example target
[[example]]
name = "my-example"
doc-scrape-examples = false

关于测试的注意:目前在测试目标上启用 doc-scrape-examples 不会有任何效果。从测试中抓取示例正在开发中。

关于开发依赖的注意:文档化一个库通常不需要 crate 的开发依赖(dev-dependencies)。然而,示例目标需要开发依赖。为了向后兼容,-Z rustdoc-scrape-examples 不会cargo doc 引入开发依赖的要求。因此,在以下情况下,不会从示例目标中抓取示例:

  1. 没有需要文档化的目标需要开发依赖,并且
  2. 至少一个包含需要文档化的目标的 crate 具有开发依赖,并且
  3. 所有 [[example]] 目标的 doc-scrape-examples 参数未设置或为 false。

如果您希望从示例目标中抓取示例,则必须不满足上述条件之一。例如,您可以将某个示例目标的 doc-scrape-examples 设置为 true,这将向 Cargo 发出信号,表明您允许为 cargo doc 构建开发依赖。

rustdoc 的 output-format

此标志决定 cargo rustdoc 的输出格式,接受 htmljson,为工具提供了一种依赖 rustdoc 的实验性 JSON 格式 的方式。

可以这样使用此标志:

cargo rustdoc -Z unstable-options --output-format json

codegen-backend

codegen-backend 特性使得可以使用 profile 选择 rustc 使用的代码生成后端。

示例:

[package]
name = "foo"

[dependencies]
serde = "1.0.117"

[profile.dev.package.foo]
codegen-backend = "cranelift"

要在 Cargo 配置中设置此 profile,需要使用 -Z codegen-backend[unstable] 表格来启用它。例如,

# .cargo/config.toml
[unstable]
codegen-backend = true

[profile.dev.package.foo]
codegen-backend = "cranelift"

gitoxide

启用‘gitoxide’不稳定特性后,所有或指定的 git 操作将由 gitoxide crate 执行,而不是 git2

虽然 -Zgitoxide 启用了所有当前已实现的特性,但可以使用 -Zgitoxide=operation[,operationN] 语法单独选择使用 gitoxide 运行哪些 git 操作。

有效的操作如下:

  • fetch - 所有 fetch 操作都使用 gitoxide 完成,包括 git 依赖以及 crate 索引。
  • checkout (计划中) - checkout 工作树,支持过滤器和子模块。

git

启用‘git’不稳定特性后,gitoxidegit2 都会对 crate 索引和 git 依赖执行浅层 fetch(shallow fetch)。

虽然 -Zgit 启用了所有当前已实现的特性,但可以使用 -Zgit=operation[,operationN] 语法单独选择何时执行浅层 fetch。

有效的操作如下:

  • shallow-index - 对索引执行浅层克隆。
  • shallow-deps - 对 git 依赖执行浅层克隆。

关于浅层克隆的细节

  • 要启用浅层克隆,请添加 -Zgit=shallow-deps 用于 fetch git 依赖项,或添加 -Zgit=shallow-index 用于 fetch 注册表索引。
  • 浅层克隆和浅层 checkout 的 git 仓库位于其带有 -shallow 后缀的目录中,例如:
    • ~/.cargo/registry/index/*-shallow
    • ~/.cargo/git/db/*-shallow
    • ~/.cargo/git/checkouts/*-shallow
  • 启用此不稳定特性后,fetch/克隆一个 git 仓库总是进行浅层 fetch。这大致相当于在任何地方执行 git fetch --depth 1
  • 即使存在 Cargo.lock 文件或指定了提交 { rev = "…" },gitoxide 和 libgit2 仍然足够智能,可以在不解除现有仓库的浅层状态下进行浅层 fetch。

script

Cargo 可以直接运行 .rs 文件,例如:

$ cargo +nightly -Zscript file.rs

其中 file.rs 可以很简单,例如:

fn main() {}

用户可以选择在模块级注释中的 cargo 代码块(code fence)中指定清单文件(manifest),例如:

#!/usr/bin/env -S cargo +nightly -Zscript
---cargo
[dependencies]
clap = { version = "4.2", features = ["derive"] }
---

use clap::Parser;

#[derive(Parser, Debug)]
#[clap(version)]
struct Args {
    #[clap(short, long, help = "Path to config")]
    config: Option<std::path::PathBuf>,
}

fn main() {
    let args = Args::parse();
    println!("{:?}", args);
}

单文件包

除了当前的多文件包(带有其他 .rs 文件的 Cargo.toml 文件)之外,我们正在添加单文件包的概念,它可以包含嵌入式清单文件(embedded manifest)。单文件 .rs 包与任何其他 .rs 文件之间没有必需的区分。

可以通过 --manifest-path 选择单文件包,例如 cargo test --manifest-path foo.rs。与 Cargo.toml 不同,这些文件不能被自动发现。

单文件包可以包含嵌入式清单文件。嵌入式清单文件使用 TOML 格式存储在 rust 的“frontmatter”中,即文件顶部以 cargo 开头的信息字符串(infostring)的 markdown 代码块(code-fence)内。

推断/默认的清单文件字段

  • package.name = <slugified 文件名基础>
  • package.edition = <current> 以避免总是需要添加嵌入式清单文件,代价是 Rust 升级时可能破坏脚本。
    • edition 未指定时发出警告,以提高对此的认识。

不允许的清单文件字段

  • [workspace], [lib], [[bin]], [[example]], [[test]], [[bench]]
  • package.workspace, package.build, package.links, package.autolib, package.autobins, package.autoexamples, package.autotests, package.autobenches

单文件包的默认 CARGO_TARGET_DIR 位于 $CARGO_HOME/target/<hash>

  • 避免同一目录中多个单文件包的冲突
  • 避免单文件包的父目录是只读引起的问题
  • 避免用户目录混乱

单文件包的 lockfile 将放置在 CARGO_TARGET_DIR 中。将来支持工作空间时,这将允许用户拥有持久的 lockfile。

Manifest-commands

您可以直接将清单文件(manifest)传递给不带子命令的 cargo 命令,例如 foo/Cargo.toml 或单文件包,如 foo.rs。这主要用于放置在 #! 行中。

解释 cargo <子命令> 的优先级如下:

  1. 内置子命令或单文件包(二者择一)
  2. 别名
  3. 外部子命令

如果参数具有以下特征之一,则将其识别为 manifest-command:

  • 路径分隔符
  • .rs 扩展名
  • 文件名为 Cargo.toml

cargo run --manifest-path <路径>cargo <路径> 之间的区别

  • cargo <路径> 使用 <路径> 的配置运行,而不是当前目录的配置,更类似于 cargo install --path <路径>
  • cargo <路径> 的详细级别低于常规默认值。传递 -v 以获得正常输出。

文档更新

Profile trim-paths 选项

这添加了一个新的 profile 设置,用于控制生成的二进制文件中路径的清理(sanitization)。可以这样启用:

cargo-features = ["trim-paths"]

[package]
# ...

[profile.release]
trim-paths = ["diagnostics", "object"]

要在 Cargo 配置中设置此 profile,需要使用 -Z trim-paths[unstable] 表格来启用它。例如,

# .cargo/config.toml
[unstable]
trim-paths = true

[profile.release]
trim-paths = ["diagnostics", "object"]

文档更新

trim-paths

作为新的“Profiles settings”条目

trim-paths 是一个 profile 设置,用于启用和控制构建输出中文件路径的清理(sanitization)。它接受以下值:

  • "none"false — 禁用路径清理
  • "macro" — 清理 std::file!() 宏展开中的路径。嵌入式 panic 消息中的路径由此生成
  • "diagnostics" — 清理打印的编译器诊断信息中的路径。
  • "object" — 清理编译的可执行文件或库中的路径。
  • "all"true — 清理所有可能位置的路径。

它还可以接受一个数组,包含 "macro""diagnostics""object" 的组合。

对于 dev profile,默认值为 none;对于 release profile,默认值为 object。您可以通过在 Cargo.toml 中指定此选项来手动覆盖它

[profile.dev]
trim-paths = "all"

[profile.release]
trim-paths = ["object", "diagnostics"]

默认的 release profile 设置 (object) 仅清理生成的的可执行文件或库文件中的路径。它总是影响来自宏(如 panic 消息)的路径,以及调试信息中的路径(仅当它们嵌入在二进制文件一起时;这是带有 ELF 二进制文件的平台(如 Linux 和 windows-gnu)的默认设置),但如果它们位于单独的文件中则不会影响(这是 Windows MSVC 和 macOS 的默认设置)。但这些单独文件本身的路径会被清理。

如果 trim-paths 不是 nonefalse,则如果以下路径出现在选定范围内,它们将被清理:

  1. 标准库和核心库(sysroot)源代码文件的路径将以 /rustc/[rustc commit hash] 开头,例如:/home/username/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs -> /rustc/fe72845f7bb6a77b9e671e6a4f32fe714962cec4/library/core/src/result.rs
  2. 当前包的路径将被剥离,相对于当前工作空间根目录,例如:/home/username/crate/src/lib.rs -> src/lib.rs
  3. 依赖包的路径将被替换为 [包名]-[版本]。例如:/home/username/deps/foo/src/lib.rs -> foo-0.1.0/src/lib.rs

当标准库和核心库的源代码文件路径不在清理范围内时,输出的路径将取决于是否存在 rust-src 组件。如果存在,则某些路径将指向您文件系统上的源代码文件副本;如果不存在,则它们将显示为 /rustc/[rustc commit hash]/library/...(就像选择清理时一样)。所有其他源代码文件的路径将不受影响。

这不会影响源代码中任何硬编码的路径,例如字符串中的路径。

环境变量

作为“Cargo 为构建脚本设置的环境变量”的新条目

  • CARGO_TRIM_PATHStrim-paths profile 选项的值。false"none" 和空数组将被转换为 nonetrue"all" 将变为 all。非空数组中的值将连接成一个逗号分隔的列表。如果构建脚本引入了构建产物的绝对路径(例如通过调用编译器),用户可以请求在不同类型的产物中清理这些路径。常见的需要清理的路径包括 OUT_DIRCARGO_MANIFEST_DIRCARGO_MANIFEST_PATH,以及构建脚本引入的任何其他路径,例如 include 目录。

gc

-Zgc 标志启用 Cargo 主目录中 Cargo 全局缓存的垃圾回收(garbage-collection)。这包括下载的依赖项,例如压缩的 .crate 文件、解压的 src 目录、注册表索引缓存和 git 依赖项。存在 -Zgc 时,Cargo 会跟踪任何索引和依赖项上次使用的时间,然后使用这些时间戳手动或自动删除一段时间未使用的缓存条目。

cargo build -Zgc

自动垃圾回收

自动删除发生在已经执行大量工作的命令上,例如所有构建命令(cargo buildcargo testcargo check 等)和 cargo fetch。删除发生在解析和包下载之后。自动删除每天只执行一次(参见 gc.auto.frequency 进行配置)。如果 cargo 处于离线状态(例如使用 --offline--frozen),自动删除将被禁用,以避免删除您长期离线时可能需要使用的 artifact。

自动 gc 配置

自动 gc 行为可以通过 cargo 配置设置指定。可用设置如下:

# Example config.toml file.

# This table defines the behavior for automatic garbage collection.
[gc.auto]
# The maximum frequency that automatic garbage collection happens.
# Can be "never" to disable automatic-gc, or "always" to run on every command.
frequency = "1 day"
# Anything older than this duration will be deleted in the source cache.
max-src-age = "1 month"
# Anything older than this duration will be deleted in the compressed crate cache.
max-crate-age = "3 months"
# Any index older than this duration will be deleted from the index cache.
max-index-age = "3 months"
# Any git checkout older than this duration will be deleted from the checkout cache.
max-git-co-age = "1 month"
# Any git clone older than this duration will be deleted from the git cache.
max-git-db-age = "3 months"

Manual garbage collection with cargo clean

使用 cargo clean 手动垃圾回收

  • 可以使用 cargo clean gc 命令进行手动删除。可以通过传递以下缓存选项之一来执行缓存内容的删除
  • --max-src-age=DURATION — 删除自给定时长以来未使用的源文件缓存。
  • --max-crate-age=DURATION — 删除自给定时长以来未使用的 crate 缓存文件。
  • --max-index-age=DURATION — 删除自给定时长以来未使用的注册表索引(包括其 .cratesrc 文件)。
  • --max-git-co-age=DURATION — 删除自给定时长以来未使用的 git 依赖项 checkout。
  • --max-git-db-age=DURATION — 删除自给定时长以来未使用的 git 依赖项克隆。
  • --max-download-age=DURATION — 删除自给定时长以来未使用的任何下载缓存数据。
  • --max-src-size=SIZE — 删除最旧的源文件缓存,直到缓存大小低于给定值。
  • --max-crate-size=SIZE — 删除最旧的 crate 缓存文件,直到缓存大小低于给定值。
  • --max-git-size=SIZE — 删除最旧的 git 依赖项缓存,直到缓存大小低于给定值。

--max-download-size=SIZE — 删除最旧的下载缓存数据,直到缓存大小低于给定值。

DURATION 的格式为“N 秒/分钟/天/周/月”,其中 N 是一个整数。

cargo clean gc
cargo clean gc --max-download-age=1week
cargo clean gc --max-git-size=0 --max-download-size=100MB

SIZE 的格式为“N 后缀”,其中 后缀 是 B、kB、MB、GB、kiB、MiB 或 GiB,N 是整数或浮点数。如果未指定后缀,则该数字表示字节数。

  • open-namespaces

Tracking Issue: #13576

允许多个包参与同一个 API 命名空间

cargo-features = ["open-namespaces"]

[package]
# ...

[lints.cargo]

用于 cargo 的新的 lints 工具表,当使用 -Zcargo-lints 时,可用于配置 cargo 本身发出的 lint 警告。

[lints.cargo]
implicit-features = "warn"

这将与 RFC 2906 workspace-deduplicate 一起工作

[workspace.lints.cargo]
implicit-features = "warn"

[lints]
workspace = true

路径基础

一个 path 依赖项可以选择性地指定一个基础(base),方法是在配置或其中一个内置路径基础[path-bases] 表中,将 base 键设置为路径基础的名称。该路径基础的值将附加到 path 值之前(如果需要,还会添加路径分隔符),以生成 Cargo 查找依赖项的实际位置。

例如,如果 Cargo.toml 包含

cargo-features = ["path-bases"]

[dependencies]
foo = { base = "dev", path = "foo" }

给定配置中包含 [path-bases] 表格:

[path-bases]
dev = "/home/user/dev/rust/libraries/"

这将产生一个 path 依赖 foo,位于 /home/user/dev/rust/libraries/foo

路径基可以是绝对路径或相对路径。相对路径基是相对于声明该路径基的配置文件的父目录。

路径基的名称必须只使用 字母数字 字符、-_,必须以 字母 字符开头,且不能为空。

如果依赖项中使用的路径基名称既不在配置中,也不是内置路径基之一,Cargo 将会引发错误。

内置路径基

Cargo 提供了隐式的路径基,无需在 [path-bases] 表格中指定即可使用。

如果内置路径基名称也在配置中声明,Cargo 将优先使用配置中的值。这使得 Cargo 可以在不引入兼容性问题的情况下添加新的内置路径基(因为现有的使用会覆盖内置名称)。

lockfile-path(锁文件路径)

此功能允许您指定锁文件 Cargo.lock 的路径。默认情况下,锁文件写入到 <workspace_root>/Cargo.lock。然而,当源代码存储在只读目录中时,大多数 cargo 命令会因尝试写入锁文件而失败。--lockfile-path 标志使得处理只读源更加容易。请注意,当前路径必须以 Cargo.lock 结尾。这意味着,如果您想在多个项目中使用此功能,锁文件应存储在不同的目录中。示例

cargo +nightly metadata --lockfile-path=$LOCKFILES_ROOT/my-project/Cargo.lock -Z unstable-options

package-workspace(打包工作空间)

这允许 cargo 在工作空间中打包(或发布)多个 crate,即使它们之间存在相互依赖。例如,考虑一个包含包 foodep 的工作空间,其中 foo 依赖于 dep。那么

cargo +nightly -Zpackage-workspace package -p foo -p dep

将打包 foodep,而

cargo +nightly -Zpackage-workspace publish -p foo -p dep

将发布 foodep。如果 foodep 是工作空间中唯一的 crate,您可以使用 --workspace 标志代替单独指定 crate

cargo +nightly -Zpackage-workspace package --workspace
cargo +nightly -Zpackage-workspace publish --workspace

锁文件行为

当打包二进制文件及其某个依赖项时,二进制文件将随附一个锁文件,指向该依赖项的注册表条目,仿佛该依赖项已经发布一样,即使它尚未发布。在这种情况下,cargo 需要知道该依赖项最终将在哪个注册表上发布。cargo 将通过检查 publish 字段来尝试推断此注册表,如果没有设置 publish 字段,则回退到 crates.io。要明确设置注册表,请传递 --registry--index 标志。

cargo +nightly -Zpackage-workspace --registry=my-registry package -p foo -p dep
cargo +nightly -Zpackage-workspace --index=https://example.com package -p foo -p dep

native-completions(原生补全)

此功能将手写的补全脚本迁移到 Rust 原生实现,使我们更容易添加、扩展和测试新的补全功能。此功能在 nightly channel 中启用,无需额外的 -Z 选项。

特别需要反馈的方面

  • 需要转义或引用的参数但未正确处理
  • 信息不准确
  • 命令行解析中的错误
  • 未报告其补全信息的参数
  • 如果已知问题正在引起麻烦

反馈可以分为

如有疑问,可以在 #14520zulip 上讨论。

如何使用 native-completions 功能

  • bash: 将 source <(CARGO_COMPLETE=bash cargo +nightly) 添加到您的 .bashrc 文件中。

  • zsh: 将 source <(CARGO_COMPLETE=zsh cargo +nightly) 添加到您的 .zshrc 文件中。

  • fish: 将 source (CARGO_COMPLETE=fish cargo +nightly | psub) 添加到 $XDG_CONFIG_HOME/fish/completions/cargo.fish 文件中。

  • elvish: 将 eval (E:CARGO_COMPLETE=elvish cargo +nightly | slurp) 添加到 $XDG_CONFIG_HOME/elvish/rc.elv 文件中。

  • powershell: 将 CARGO_COMPLETE=powershell cargo +nightly | Invoke-Expression 添加到 $PROFILE 中。

warnings(警告)

-Z warnings 功能启用了 build.warnings 配置选项来控制 Cargo 如何处理警告。如果未启用 -Z warnings 不稳定标志,则 build.warnings 配置将被忽略。

此设置目前仅适用于 rustc 警告。将来可能会适用于其他警告(如 Cargo lint 或 Cargo 警告)。

build.warnings

  • 类型:字符串
  • 默认值:warn
  • 环境变量:CARGO_BUILD_WARNINGS

控制 Cargo 如何处理警告。允许的值有

  • warn:警告作为警告发出(默认)。
  • allow:警告被隐藏。
  • deny:如果发出警告,操作结束时将引发错误,并且进程将以失败的退出码退出。

feature unification(特性统一)

-Z feature-unification 功能启用了 resolver.feature-unification 配置选项,以控制特性在工作空间中如何统一。如果未启用 -Z feature-unification 不稳定标志,则 resolver.feature-unification 配置将被忽略。

resolver.feature-unification

  • 类型:字符串
  • 默认值:"selected"
  • 环境变量:CARGO_RESOLVER_FEATURE_UNIFICATION

指定哪些包参与 特性统一

  • selected:合并为当前构建指定的所有包的依赖特性。
  • workspace:合并所有工作空间成员的依赖特性,无论当前构建指定了哪些包。
  • package (未实现):依赖特性按包逐个考虑,当包激活不同的特性集时,倾向于对依赖项进行重复构建。

Package message format(打包消息格式)

cargo package 中的 --message-format 标志控制输出消息格式。目前,它只与 --list 标志一起使用并影响文件列表格式,需要 -Zunstable-options。更多信息请参阅 cargo package --message-format

已稳定和已移除的功能

编译进度

compile-progress 功能已在 1.30 版本中稳定。进度条现在默认启用。有关控制此功能的更多信息,请参阅 term.progress

Edition(版本)

Cargo.toml 中指定 edition 已在 1.31 版本中稳定。有关指定此字段的更多信息,请参阅 edition 字段

rename-dependency(依赖重命名)

Cargo.toml 中指定重命名的依赖项已在 1.31 版本中稳定。有关重命名依赖项的更多信息,请参阅重命名依赖项

Alternate Registries(备用注册表)

对备用注册表的支持已在 1.34 版本中稳定。有关备用注册表的更多信息,请参阅注册表章节

Offline Mode(离线模式)

离线功能已在 1.36 版本中稳定。有关使用离线模式的更多信息,请参阅 --offline 标志

publish-lockfile(发布锁文件)

publish-lockfile 功能已在 1.37 版本中移除。如果包包含二进制目标,则在发布包时始终包含 Cargo.lock 文件。cargo install 需要 --locked 标志才能使用 Cargo.lock 文件。更多信息请参阅 cargo packagecargo install

default-run(默认运行目标)

default-run 功能已在 1.37 版本中稳定。有关指定默认运行目标的更多信息,请参阅 default-run 字段

cache-messages(缓存消息)

编译器消息缓存已在 1.40 版本中稳定。编译器警告现在默认缓存,并在重新运行 Cargo 时自动回放。

install-upgrade(安装升级)

install-upgrade 功能已在 1.41 版本中稳定。cargo install 现在会检查包是否过期,并自动升级它们。有关更多信息,请参阅 cargo install 文档。

Profile Overrides(配置文件覆盖)

配置文件覆盖已在 1.41 版本中稳定。有关使用覆盖的更多信息,请参阅配置文件覆盖

Config Profiles(配置文件的 profiles)

在 Cargo 配置文件和环境变量中指定 profiles 已在 1.43 版本中稳定。有关在配置文件中指定 profiles 的更多信息,请参阅 config [profile] 表格

crate-versions(crate 版本)

-Z crate-versions 标志已在 1.47 版本中稳定。crate 版本现在会自动包含在 cargo doc 文档侧边栏中。

Features(特性)

-Z features 标志已在 1.51 版本中稳定。有关使用新特性解析器的更多信息,请参阅 特性解析器版本 2

package-features(包特性)

-Z package-features 标志已在 1.51 版本中稳定。有关使用特性 CLI 选项的更多信息,请参阅 解析器版本 2 命令行标志

Resolver(解析器)

Cargo.toml 中的 resolver 功能已在 1.51 版本中稳定。有关指定解析器的更多信息,请参阅 解析器版本

用于在构建脚本中指定额外链接器参数的 extra-link-arg 功能已在 1.56 版本中稳定。有关指定额外链接器参数的更多信息,请参阅 构建脚本文档

configurable-env(可配置环境变量)

用于在 Cargo 配置中指定环境变量的 configurable-env 功能已在 1.56 版本中稳定。有关配置环境变量的更多信息,请参阅 配置文档

rust-version(Rust 版本)

Cargo.toml 中的 rust-version 字段已在 1.56 版本中稳定。有关使用 rust-version 字段和 --ignore-rust-version 选项的更多信息,请参阅 rust-version 字段

patch-in-config(配置中的 patch)

-Z patch-in-config 标志以及 Cargo 配置文件中对应的 [patch] 部分支持已在 1.56 版本中稳定。有关更多信息,请参阅 patch 字段

edition 2021(2021 版本)

2021 版本已在 1.56 版本中稳定。有关设置版本的更多信息,请参阅 edition 字段。有关迁移现有项目的更多信息,请参阅 cargo fix --edition版本指南

Custom named profiles(自定义命名 profiles)

自定义命名 profiles 已在 1.57 版本中稳定。有关更多信息,请参阅 profiles 章节

Profile strip option(profile 的 strip 选项)

profile 的 strip 选项已在 1.59 版本中稳定。有关更多信息,请参阅 profiles 章节

Future incompat report(未来不兼容报告)

支持生成未来不兼容报告已在 1.59 版本中稳定。有关更多信息,请参阅 未来不兼容报告章节

Namespaced features(命名空间特性)

命名空间特性已在 1.60 版本中稳定。有关更多信息,请参阅 特性章节

Weak dependency features(弱依赖特性)

弱依赖特性已在 1.60 版本中稳定。有关更多信息,请参阅 特性章节

timings(计时)

-Ztimings 选项已在 1.60 版本中稳定为 --timings。(--timings=html 和机器可读的 --timings=json 输出仍然不稳定,需要 -Zunstable-options。)

config-cli(命令行配置)

--config CLI 选项已在 1.63 版本中稳定。有关更多信息,请参阅 配置文档

multitarget(多目标)

-Z multitarget 选项已在 1.64 版本中稳定。有关设置默认目标平台三元组的更多信息,请参阅 build.target

crate-type(crate 类型)

cargo rustc--crate-type 标志已在 1.64 版本中稳定。有关更多信息,请参阅 cargo rustc 文档

Workspace Inheritance(工作空间继承)

工作空间继承已在 1.64 版本中稳定。有关更多信息,请参阅 workspace.packageworkspace.dependencies从工作空间继承依赖项

terminal-width(终端宽度)

-Z terminal-width 选项已在 1.68 版本中稳定。当从 Cargo 可以自动检测宽度的终端运行时,终端宽度总是会传递给编译器。

sparse-registry(稀疏注册表)

稀疏注册表支持已在 1.68 版本中稳定。有关更多信息,请参阅 注册表协议

cargo logout

cargo logout 命令已在 1.70 版本中稳定。

doctest-in-workspace(工作空间中的 doctest)

cargo test-Z doctest-in-workspace 选项已在 1.72 版本中稳定并默认启用。有关编译和运行测试的工作目录的更多信息,请参阅 cargo test 文档

keep-going(继续进行)

--keep-going 选项已在 1.74 版本中稳定。更多详情可参考 cargo build 中的 --keep-going 标志

[lints]

[lints](通过 -Zlints 启用)已在 1.74 版本中稳定。

credential-process(凭据进程)

-Z credential-process 功能已在 1.74 版本中稳定。

详情请参阅 注册表认证 文档。

registry-auth(注册表认证)

-Z registry-auth 功能已在 1.74 版本中稳定,并附加要求配置凭据提供程序。

详情请参阅 注册表认证 文档。

check-cfg

-Z check-cfg 功能已在 1.80 版本中通过使其成为默认行为而稳定。

有关指定自定义 cfgs 的信息,请参阅 构建脚本文档

Edition 2024(2024 版本)

2024 版本已在 1.85 版本中稳定。有关设置版本的更多信息,请参阅 edition 字段。有关迁移现有项目的更多信息,请参阅 cargo fix --edition版本指南