不稳定特性

实验性的 Cargo 特性仅在 nightly channel 上可用。我们鼓励您尝试这些特性,看看它们是否满足您的需求,以及是否存在任何问题。请查看下面列出的相关跟踪问题,以获取有关该特性的更多信息,如果您想了解未来的更新,请点击 GitHub 的订阅按钮。

经过一段时间后,如果该特性没有任何重大问题,它就可以被稳定化,这将使其在当前的 nightly 版本到达 stable channel 后可用(大约需要 6 到 12 周)。

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

  • 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 版本

不稳定特性列表

  • 不稳定特定特性
    • -Z allow-features — 提供一种限制可以使用哪些不稳定特性的方法。
  • 构建脚本和链接
    • Metabuild — 提供声明式构建脚本。
  • 解析器和特性
  • 输出行为
  • 编译行为
    • mtime-on-use — 每次使用时更新每个依赖项的最后修改时间戳,以提供一种删除未使用工件的机制。
    • doctest-xcompile — 支持使用 --target 标志运行 doctests。
    • build-std — 构建标准库而不是使用预构建的二进制文件。
    • build-std-features — 设置要与标准库一起使用的特性。
    • binary-dep-depinfo — 使 dep-info 文件跟踪二进制依赖项。
    • checksum-freshness — 传递此标志后,将使用文件校验和而不是文件修改时间来决定是否需要重建 crate。
    • panic-abort-tests — 允许使用 “abort” panic 策略运行测试。
    • host-config — 允许为 host 构建目标设置类似 [target] 的配置设置。
    • target-applies-to-host — 更改是否将某些标志传递给 host 构建目标。
    • gc — 全局缓存垃圾回收。
    • open-namespaces — 允许多个包参与同一个 API 命名空间
  • rustdoc
  • Cargo.toml 扩展
  • 信息和元数据
    • 构建计划 — 输出有关将要运行的命令的 JSON 信息。
    • 单元图 — 为 Cargo 的内部图结构输出 JSON。
    • cargo rustc --print — 使用 --print 调用 rustc 以显示来自 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 — 控制警告行为;允许或拒绝警告的选项。

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

  • 原始问题:#6477
  • 缓存使用元跟踪问题:#7150

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

avoid-dev-deps

当运行诸如 cargo installcargo build 之类的命令时,Cargo 当前需要下载 dev-dependencies,即使它们没有被使用。-Z avoid-dev-deps 标志允许 Cargo 避免下载不需要的 dev-dependencies。如果跳过 dev-dependencies,则不会生成 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"

root-dir

  • 原始问题:#9887
  • 跟踪问题:无(目前尚未计划稳定化)

-Zroot-dir 标志设置打印路径所基于的根目录。这会影响诊断信息和 file!() 宏发出的路径。

doctest-xcompile

当传递目标时,此标志会更改 cargo test 处理文档测试的行为。目前,如果传递的目标与主机不同,cargo 将简单地跳过测试文档测试。如果存在此标志,cargo 将像往常一样继续,将测试传递给 doctest,同时也会传递 --target 选项,并启用 -Zunstable-features --enable-per-target-ignores,并传递来自 .cargo/config.toml 的信息。有关更多信息,请参阅 rustc 问题。

cargo test --target foo -Zdoctest-xcompile

Build-plan

build-plan 功能已弃用,可能会在未来的版本中删除。请参阅 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.toml 中的 metabuild 键中指定构建依赖项的列表。会自动生成一个构建脚本,该脚本按顺序运行每个构建依赖项。然后,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” 功能允许将依赖项标记为“public”或“private”。启用此功能后,会将其他信息传递给 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

文档更新

  • 对于工作区的“The dependencies table”部分,请将 public 作为 workspace.dependencies 的不受支持字段包含在内。

msrv-policy

针对 RFC 2495 下的 MSRV 感知 cargo 功能的全部不稳定功能。

MSRV 感知 cargo add

此功能已在 1.79 版本中通过 #13608 稳定。

MSRV 感知解析器

此功能已在 1.83 版本中通过 #14639 稳定。

incompatible_toolchain 错误转换为 lint

未实现

cargo addcargo update--update-rust-version 标志

未实现

package.rust-version = "toolchain"

未实现

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

未实现

precise-pre-release

precise-pre-release 功能允许使用 update --precise 选择预发布版本,即使项目的 Cargo.toml 中未指定预发布版本也是如此。

例如,考虑以下 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

update-breaking

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

这仅适用于以下情况下的依赖项:

  • 该包是工作区成员的依赖项
  • 依赖项未重命名
  • SemVer 不兼容版本可用
  • 使用“SemVer 运算符”(^,这是默认值)

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

示例:

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

这旨在发挥与 cargo-upgrade 类似的作用

build-std

build-std 功能使 Cargo 能够将标准库本身编译为 crate 图编译的一部分。此功能在历史上也称为“std 感知 Cargo”。此功能仍处于开发的非常早期阶段,并且也可能是对 Cargo 的一项重大功能添加。这是一个非常大的功能,需要进行文档化,即使以今天存在的最小形式也是如此,因此,如果您想及时了解最新信息,则需要关注 跟踪存储库 及其一系列问题。

今天实现的功能位于名为 -Z build-std 的标志后面。此标志表示 Cargo 应该使用与主构建本身相同的配置文件从源代码编译标准库。请注意,要使此功能正常工作,您需要拥有标准库的源代码,并且目前唯一支持的方法是添加 rust-src rust 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!

在这里,我们使用调试断言(如编译 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 的逗号分隔列表。

要求

总结一下,今天使用 -Z build-std 的要求列表如下:

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

报告错误和提供帮助

-Z build-std 功能处于开发的非常早期阶段!Cargo 的此功能具有极其漫长的历史,并且范围非常大,而这仅仅是开始。如果您想报告错误,请将它们报告给

另外,如果您想看到尚未实现的功能,并且/或者如果某些功能无法完全按照您想要的方式工作,请随时查看跟踪存储库的 问题跟踪器,如果它不在那里,请提交一个新问题!

build-std-features

此标志是 -Zbuild-std 功能标志的同级标志。在构建标准库时,这将配置为标准库本身启用的功能。此时,默认启用的功能是 backtracepanic-unwind。此标志需要一个逗号分隔的列表,如果提供,则会覆盖默认启用的功能列表。

binary-dep-depinfo

  • 跟踪 rustc 问题:#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。

目前,即使启用了 checksum-freshness,构建脚本摄取的文件仍将继续使用 mtime。这并非旨在作为长期解决方案。

panic-abort-tests

-Z panic-abort-tests 标志将启用 nightly 支持,以使用 -Cpanic=abort 编译测试 harness crate。如果没有此标志,Cargo 将使用 -Cpanic=unwind 编译测试及其依赖的所有内容,因为这是 test-the-crate 知道如何操作的唯一方法。但是,从 rust-lang/rust#64158 开始,test crate 支持使用 -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

从历史上看,Cargo 对于是否尊重环境变量和 [target] 中的 linkerrustflags 配置选项的行为,对于构建脚本、插件和其他始终为宿主平台构建的工件,一直有些不一致。当没有传递 --target 时,Cargo 会为构建脚本以及所有其他编译工件使用相同的 linkerrustflags。然而,当传递了 --target 时,Cargo 会尊重来自 [target.<host triple>]linker,并且不会选取任何 rustflags 配置。这种双重行为令人困惑,同时也使得在宿主三元组和 目标三元组 恰好相同时,正确配置构建变得困难,因为意图在构建主机上运行的工件仍然应该进行不同的配置。

-Ztarget-applies-to-host 启用了 Cargo 配置文件中的顶层 target-applies-to-host 设置,允许用户选择这些属性的不同(且更一致)的行为。当在配置文件中 target-applies-to-host 未设置或设置为 true 时,现有的 Cargo 行为将被保留(但请参阅 -Zhost-config,它会更改该默认值)。当设置为 false 时,无论是否将 --target 传递给 Cargo,都不会为宿主工件尊重来自 [target.<host triple>]RUSTFLAGS[build] 的任何选项。要自定义旨在在主机上运行的工件,请使用 [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

配置文件中的 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.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 等),以将表示 Cargo 内部单元图的 JSON 对象输出到 stdout。实际上没有构建任何东西,并且该命令在打印后立即返回。每个“单元”对应于编译器的一次执行。这些对象还包括每个单元所依赖的单元。

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 配置文件的配置文件中设置此项,您需要使用 -Z profile-rustflags[unstable] 表来启用它。例如,

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

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

rustdoc-map

此功能添加了传递给 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 功能在清单中添加了两个键:package.default-targetpackage.forced-target。第一个使包默认针对某个目标进行编译(即,当没有传递 --target 参数时)。第二个使包始终针对该目标进行编译。

示例:

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

在此示例中,该 crate 始终针对 wasm32-unknown-unknown 构建,例如,因为它将用作在主机(或在命令行上提供)目标上运行的主程序的插件。

artifact-dependencies

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

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

artifact-dependencies:依赖项声明

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

  • artifact — 这指定要构建的 Cargo 目标。通常,如果没有此字段,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] 目标。这允许包从 Rust 代码中使用依赖项,就像一个普通的依赖项以及工件依赖项一样。

    示例:

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

    如果未指定此项,则默认值取决于依赖项类型。对于构建依赖项,它将为宿主目标构建。对于所有其他依赖项,它将为构建声明包的相同目标构建。

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

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

artifact-dependencies:环境变量

构建工件依赖项后,Cargo 提供以下环境变量,您可以使用这些变量访问该工件

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

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

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

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

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

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

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

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

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

构件依赖项:示例

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

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 构件

在消费包中的 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 构件及其库

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

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

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

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

发布超时

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

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

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

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

非对称令牌

-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 接收到的质询字符串。发出质询的注册表必须跟踪已发出/使用的质询,并且在同一有效期内永远不要接受给定质询多次(避免需要跟踪曾经发出的每个质询)。

“页脚”(它是签名的一部分)将是 UTF-8 中的 JSON 字符串,并且包含

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

PASETO 包含已签名的消息,因此服务器不必从请求中重建确切的字符串以检查签名。服务器确实需要检查签名的字符串在 PASETO 中是否有效,并且该字符串的内容是否与请求匹配。如果请求应该期望某个声明,但 PASETO 中缺少该声明,则必须拒绝该请求。

cargo 配置

cargo config 子命令提供了一种显示 Cargo 加载的配置文件的方法。它目前包括 get 子命令,该子命令可以采用可选的配置值进行显示。

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

如果不包含配置值,它将显示所有配置值。有关更多可用选项,请参阅 --help 输出。

rustc --print

cargo rustc --print=VAL--print 标志转发到 rustc 以便从 rustc 中提取信息。这将使用相应的 --print 标志运行 rustc,然后立即退出而不进行编译。将其公开为 cargo 标志允许 cargo 根据当前配置注入正确的目标和 RUSTFLAGS。

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

不同的二进制名称

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

filename 参数**不应**包含二进制扩展名,cargo 将自行找出合适的扩展名并将其用于二进制文件。

filename 参数仅在清单的 [[bin]] 部分中可用。

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

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

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

抓取示例

-Z rustdoc-scrape-examples 标志告诉 Rustdoc 在当前工作区中搜索对函数的调用。这些调用点然后被包含为文档。你可以像这样使用该标志

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

默认情况下,Cargo 将从正在记录的包的示例目标中抓取示例。你可以使用 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 的开发依赖项。但是,示例目标需要开发依赖项。为了向后兼容,-Z rustdoc-scrape-examples不会cargo doc 引入开发依赖项要求。因此,在以下情况下,示例将不会从示例目标中抓取

  1. 没有正在记录的目标需要开发依赖项,并且
  2. 至少一个具有正在记录的目标的 crate 具有开发依赖项,并且
  3. 所有 [[example]] 目标的 doc-scrape-examples 参数都未设置或为 false。

如果要从示例目标中抓取示例,则不能满足上述条件之一。例如,你可以为一个示例目标将 doc-scrape-examples 设置为 true,这向 Cargo 发出信号,表明你接受为 cargo doc 构建开发依赖项。

rustdoc 的输出格式

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

你可以像这样使用该标志

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

codegen-backend

codegen-backend 功能使得可以使用配置文件选择 rustc 使用的代码生成后端。

示例:

[package]
name = "foo"

[dependencies]
serde = "1.0.117"

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

要在 Cargo 配置文件的配置文件中设置此项,你需要使用 -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 - 所有获取都使用 gitoxide 完成,其中包括 git 依赖项以及 crates 索引。
  • checkout (计划中) - 检出工作树,支持过滤器和子模块。

git

使用 'git' 不稳定功能,gitoxidegit2 都将对 crate 索引和 git 依赖项执行浅层获取。

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

有效的操作如下

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

关于浅层克隆的详细信息

  • 要启用浅层克隆,添加 -Zgit=shallow-deps 用于获取 git 依赖项,或添加 -Zgit=shallow-index 用于获取注册表索引。
  • 浅层克隆和浅层检出的 git 仓库位于它们自己的带有 -shallow 后缀的目录中,例如:
    • ~/.cargo/registry/index/*-shallow
    • ~/.cargo/git/db/*-shallow
    • ~/.cargo/git/checkouts/*-shallow
  • 当不稳定的功能开启时,获取/克隆 git 仓库始终是浅层获取。这大致相当于在任何地方都执行 git fetch --depth 1
  • 即使存在 Cargo.lock 或指定了提交 { rev = "…" },gitoxide 和 libgit2 仍然足够智能,可以进行浅层获取,而无需取消现有仓库的浅层状态。

脚本

Cargo 可以直接运行 .rs 文件,就像这样:

$ cargo +nightly -Zscript file.rs

其中 file.rs 可以像下面这样简单:

fn main() {}

用户可以选择在模块级注释的 cargo 代码围栏中指定清单,例如:

#!/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 文件)之外,我们还添加了单文件包的概念,其中可能包含嵌入的清单。对于单文件 .rs 包,没有要求将其与任何其他 .rs 文件区分开来。

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

单文件包可能包含嵌入的清单。嵌入的清单使用 TOML 存储在 rust “前置信息”中,这是一个 markdown 代码围栏,在文件顶部的 infostring 开头处带有 cargo

推断/默认的清单字段

  • package.name = <slugified file stem>
  • 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>

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

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

清单命令

您可以将清单直接传递给 cargo 命令,而无需子命令,例如 foo/Cargo.toml 或像 foo.rs 这样的单文件包。这主要用于放在 #! 行中。

解释 cargo <subcommand> 的优先级是:

  1. 内置异或单文件包
  2. 别名
  3. 外部子命令

如果一个参数具有以下特征之一,则将其标识为清单命令:

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

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

  • cargo <path> 使用 <path> 的配置运行,而不是当前目录的配置,更像 cargo install --path <path>
  • cargo <path> 的详细程度低于正常的默认值。传递 -v 以获取正常输出。

文档更新

Edition 2024

可以通过将 edition2024 不稳定功能添加到 Cargo.toml 的顶部来启用对 2024 版本 的支持

cargo-features = ["edition2024"]

[package]
name = "my-package"
version = "0.1.0"
edition = "2024"

如果要将现有项目从以前的版本过渡,则可以在 nightly 通道上使用 cargo fix --edition。运行 cargo fix 后,您可以如上所示将版本切换到 2024。

此功能非常不稳定,仅用于早期测试和实验。未来的 nightly 版本可能会为 2024 版本引入更改,这可能会破坏您的构建。

Profile trim-paths 选项

这增加了一个新的 profile 设置,以控制在生成的二进制文件中如何清理路径。可以像这样启用它:

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

作为新的“Profile 设置”条目

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

  • "none"false — 禁用路径清理
  • "macro" — 清理 std::file!() 宏扩展中的路径。这是嵌入的 panic 消息中的路径的来源
  • "diagnostics" — 清理打印的编译器诊断中的路径
  • "object" — 清理已编译的可执行文件或库中的路径
  • "all"true — 清理所有可能位置的路径

它还接受包含 "macro""diagnostics""object" 组合的数组。

dev profile 的默认值为 nonerelease 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. 依赖包的路径将被替换为 [package name]-[version]。例如:/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,以及构建脚本引入的任何其他路径,例如包含目录。

gc

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

cargo build -Zgc

自动垃圾回收

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

自动 gc 配置

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

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

使用 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 依赖项检出。
  • --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 seconds/minutes/days/weeks/months”,其中 N 是一个整数。

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

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

open-namespaces

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

可以通过以下方式启用此功能

cargo-features = ["open-namespaces"]

[package]
# ...

[lints.cargo]

一个新的用于 cargolints 工具表,可用于配置当使用 -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] 表中的路径基址名称来指定基址。 该路径基址的值将附加到 path 值的前面(必要时附加路径分隔符),以生成 Cargo 将查找依赖项的实际位置。

例如,如果 Cargo.toml 包含

cargo-features = ["path-bases"]

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

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

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

这将产生位于 /home/user/dev/rust/libraries/foopath 依赖项 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 渠道启用,无需额外的 -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:如果发出警告,则会在操作结束时引发错误,并且进程将以失败的退出代码退出。

已稳定和已删除的功能

编译进度

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

版本

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

rename-dependency

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

备用注册表

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

离线模式

离线功能已在 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 文档。

配置文件覆盖

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

配置配置文件

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

crate-versions

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

功能

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

package-features

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

解析器

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

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

configurable-env

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

rust-version

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

patch-in-config

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

edition 2021

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

自定义命名配置文件

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

配置文件 strip 选项

配置文件 strip 选项已在 1.59 版本中稳定。有关更多信息,请参阅配置文件章节

未来不兼容报告

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

命名空间功能

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

弱依赖功能

弱依赖功能已在 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

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

工作区继承

工作区继承已在 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

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

keep-going

--keep-going 选项已在 1.74 版本中稳定。有关更多详细信息,请参阅 cargo build 中的--keep-going 标志作为示例。

[lints]

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

credential-process

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

有关详细信息,请参阅注册表身份验证文档。

registry-auth

在配置了凭据提供程序的情况下,-Z registry-auth 功能已在 1.74 版本中稳定。

有关详细信息,请参阅注册表身份验证文档。

check-cfg

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

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