不稳定的特性

实验性的Cargo 特性只在nightly channel"每日构建"中提供。我们鼓励你尝试使用这些特性,看看它们是否符合你的需求,以及是否有问题或难题。请查看下面列出的链接的问题跟踪,了解更多关于该特性的信息,如果你想获得未来的更新,请点击GitHub订阅按钮。

经过一段时间后,如果该特性没有任何重大问题,它可以被stabilized,这将使它在当前每日构建发布的版本到达稳定通道后,就可以在稳定版上使用(6到12周不等)。

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

  • 按照 Cargo.toml 新语法,在顶部任意表之前设置 cargo-features 键。例如:

    # 这里指定启用哪些新的 Cargo.toml 特性。
    cargo-features = ["test-dummy-unstable"]
    
    [package]
    name = "my-package"
    version = "0.1.0"
    im-a-teapot = true  # 这是由 test-dummy-unstable 启用的新选项。
    
  • 新的命令行标志、选项和子命令需要同时包含 -Z unstable-options CLI选项。 例如,新的 --out-dir 选项只在每日构建中可用。

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

  • -Z命令行标志用于启用可能没有接口的新功能,或者接口还没有设计好,或者用于影响Cargo多个部分的更复杂功能。例如,mime-on-use功能可以用以下方式启用:

    cargo +nightly build -Z mtime-on-use

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

    可以用 -Z 标志配置的内容也可以在cargo config file (.cargo/config.toml)的 unstable 表中设置。比如说:

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

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

不稳定特性列表

  • 不稳定特定特性
  • 构建脚本和链接
    • Metabuild — 提供声明式的构建脚本。
  • 解析器和特性
  • 输出行为
    • out-dir — 添加一个目录,将制品复制到该目录。
    • Different binary name — 为构建的二进制文件指定一个与crate名称分开的名称。
  • 编译行为
    • mtime-on-use — 在每次使用依赖时,更新其最后修改的时间戳,以提供一种机制来删除未使用的制品。
    • doctest-xcompile — 支持运行带有 --target 标志的文档测试。
    • build-std — 构建标准库而不是使用预先构建的二进制文件。
    • build-std-features — 设置与标准库一起使用的特性。
    • binary-dep-depinfo — 致使dep-info文件跟踪二进制文件的依赖。
    • panic-abort-tests — 允许用 "中止" 恐慌策略运行测试。
    • crate-type — 支持向编译器传递crate类型。
    • keep-going — 尽可能多地构建,而不是在第一个错误时就中止。
  • rustdoc
  • Cargo.toml 扩展
  • 信息和元数据
    • Build-plan — 发送关于哪些命令将被运行的JSON信息。
    • unit-graph — 为Cargo的内部图结构发送JSON。
    • cargo rustc --print — 用 --print 调用rustc,以显示来自 rustc 的信息。
  • 配置
    • config-include — 增加配置文件包含其他文件的能力。
    • cargo config — 增加新的子命令用于查看配置文件。
  • 注册中心
    • credential-process — 增加对从外部认证程序获取注册中心令牌的支持。
    • cargo logout — 添加 logout 命令,以删除当前保存的注册中心令牌。
    • sparse-registry — 增加从静态文件HTTP注册中心获取的支持(sparse+)。
    • publish-timeout — 控制上传crate和在索引中可用之间的超时。
    • registry-auth — 增加对认证注册的支持,并使用非对称加密生成注册中心认证令牌。

接受特性

这个永久不稳定的标志使得可以使用只有列出的一组不稳定的特性。具体来说,如果你传递了 -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更新使用过的文件的时间戳,以便像cargo-sweep这样的工具更容易发现哪些文件是过时的。对于许多工作流程来说,这需要在 所有 cargo的调用中进行设置。为了更实用,在 .cargo/config.toml 中设置 unstable.mtime_on_use 标志或相应的环境变量,将对所有每日构建cargo的调用应用 -Z mtime-on-use 。(config标志在稳定版本中被忽略)

avoid-dev-deps

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

minimal-versions

注意: 不建议使用这个功能。因为它为所有的横向依赖强制执行最小版本,它的作用是有限的,因为不是所有的外部依赖都声明适当的版本下限。 我们打算在未来对其进行修改,只对直接依赖执行最小版本。

当生成 Cargo.lock 文件时, -Z minimal-versions 标志将把依赖解析为能满足要求的最小语义化版本(而不是最高版本)。

这个标志的用途是在持续集成过程中检查 Cargo.toml 中指定的版本是否正确反映了你实际使用的最小版本。 也就是说,如果 Cargo.toml 说明 foo = "1.0.0",就不会意外地依赖 foo 1.5.0 中增加的特性。

out-dir

这个特性允许你指定制品在构建后将被复制到的目录。通常,制品只被写入 target/releasetarget/debug 目录。然而,确定确切的文件名可能很棘手,因为你需要解析JSON输出。--out-dir 标志使其更容易预计访问制品。注意,制品是复制的,所以原件仍然在 target 目录中。例子:

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

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

[build]
out-dir = "out"

doctest-xcompile

这个标志改变了 cargo test 在传递目标时处理文档测试的行为。目前,如果传递的目标与主机不同,cargo将直接跳过文档测试。如果有这个标志,cargo将继续正常工作,将测试传给文档测试,同时也将 --target 选项传给它,以及启用 -Zunstable-features --enable-per-target-ignores,并将 .cargo/config.toml 的信息传给它。更多信息请参见 rustc issue。

cargo test --target foo -Zdoctest-xcompile

新的 dir-name 属性

target/ 下生成的一些路径是约定俗成的 "构建协议" , 被 cargo 作为更大的项目构建的一部分来调用。 因此,为了保留现有的行为,还有一个新的属性 dir-name ,当没有指定时,默认为配置文件的名称。比如说:

[profile.release-lto]
inherits = "release"
dir-name = "lto"  # 发送到target/lto,而不是target/release-lto
lto = true

Build-plan

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' 链接项能够正常工作。

这需要在 cargo-features 中设置适当的键。

cargo-features = ["public-dependency"]

[dependencies]
my_dep = { version = "1.2.3", public = true }
private_dep = "2.0.0" # 默认情况下,将是 'private' 。

build-std

build-std 特性使Cargo能够自己编译标准库,作为crate图编译的一部分。这个功能曾称为 "std-aware Cargo"。 这个功能仍处于开发的早期阶段,也是Cargo可能增加的重要特性。这是大的特性文档,即使现在以最小形式存在, 如果想保持最新,请关注跟踪仓库和issues。

目前实现的功能是在名为 -Z build-std 的标志后。这个标志表明,Cargo应该使用与主构建本身相同的配置文件从源代码中编译标准库。 请注意,要实现这个功能,你需要有标准库的源代码,目前唯一支持的方法是添加 rust-src rust rustup组件。

$ rustup component add rust-src --toolchain nightly

现在还要求 -Z build-std 标志与 --target 标志组合。请注意,并不是强制进行交叉编译,只是要求以某种形式传递 --target

使用方法如下:

$ 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的源代码。
  • 你必须传递 --target
  • 你必须同时使用每日构建 Cargo 和 Rustc
  • -Z build-std 标志必须传递给所有 cargo 调用。

报告错误并提供帮助

-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就会被重新构建)。 主要的用例是编译器本身,它对标准库有隐含的依赖,否则就不会追踪到变化检测。

panic-abort-tests

-Z panic-abort-tests 标志将启用每日构建支持,以 -Cpanic=abort 编译测试连接crate。如果没有这个标志,Cargo会用 -Cpanic=unwind 来编译测试, 以及所有依赖,因为这是 test-the-rate 知道如何操作的唯一方式。然而,从rust-lang/rust#64158开始,test-crate 支持 -C panic=abort ,并支持每个进程的测试,可以帮助避免多次编译crate图。

目前还不清楚如何在Cargo中稳定这一特性,但我们希望能以某种方式稳定下来。

keep-going

cargo build --keep-going (以及类似的 checktest 等)将尽可能多地构建依赖图中的crate,而不是在第一个失败的crate中止构建。

例如,如果当前包依赖于 failsworks 两个依赖项,其中一个构建失败,cargo check -j1 可能也可能不会构建成功(取决于Cargo选择先运行哪一个构建),而 cargo check -j1 --keep-going 肯定会同时运行两个构建,即使先运行的那个构建失败。

必须使用 -Z unstable-options 命令行选项,以便在尚未稳定时使用 --keep-going

cargo check --keep-going -Z unstable-options

config-include

配置文件中的 include 键可以用来加载另一个配置文件。它需要相对于配置文件的另一个文件路径的字符串,或者字符串列表。需要 -Zconfig-include 命令行选项。

# .cargo/config
include = '../../some-common-config.toml'

配置文件的值首先从包含路径中加载,然后在其上合并配置文件本身的值。

这可以与config-cli搭配使用,以指定从命令行加载的文件。传递一个配置文件的路径作为 --config 的参数:

cargo +nightly -Zunstable-options -Zconfig-include --config somefile.toml build

CLI路径是相对于当前工作目录的。

target-applies-to-host

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

曾经,Cargo对环境变量中的 linkerrustflags 配置选项以及 [target] 是否遵从构建脚本、插件和其他始终为主机平台构建的制品的行为有些不一致。当 --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- appliesto -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 arch表优先于通用的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-configtarget-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等), 以向标准输出发送JSON对象,表示Cargo的内部单元图。实际上没有任何内容被构建, 命令在打印后立即返回。每个 "单元" 对应于编译器的一次执行。这些对象还包含每个单元所依赖的单元。

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

这种结构提供了Cargo所看到的更完整的依赖的视图。特别是,"features" 字段支持新的特性解析器, 依赖可以用不同的特性构建多次。 cargo metadata 从根本上不能表示不同依赖种类之间的特性关系, 当前特性取决于运行哪个命令,选择哪个包和目标。此外,它还可以提供包内依赖的细节,如构建脚本或测试。

下面是对JSON结构的描述:

{
  /* 是JSON输出结构的版本。如果有向后不兼容的变化,这个值将增加。 */
  "version": 1,
  /* 所有构建单位的数组。 */
  "units": [
    {
      /* 一个不透明的字符串,表示该包。关于包的信息可以从 `cargo metadata` 中获得。 */
      "pkg_id": "my-package 0.1.0 (path+file:///path/to/my-package)",
      /* Cargo目标。关于这些字段的更多信息,请参见 `cargo metadata` 文档。 https://doc.rust-lang.org/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
      },
      /* 本单元的配置文件设置。这些值可能与配置清单中定义的配置文件不一致。
         单位可以使用修改的配置文件设置。例如,"panic" 设置可以被覆盖,用于测试,以迫使它 "unwind" 。 */
      "profile": {
        /* 这些设置是由配置文件名称衍生而来。 */
        "name": "dev",
        /* 字符串表示的优化级别。 */
        "opt_level": "0",
        /* 字符串表示的LTO设置。 */
        "lto": "false",
        /* 编码单位是一个整数。 `null` 表示它应该使用编译器的默认值。 */
        "codegen_units": null,
        /* 整数表示的调试信息等级。 `null` 表示它应该使用编译器的默认值 (0) 。 */
        "debuginfo": 2,
        /* 是否启用了调试断言。 */
        "debug_assertions": true,
        /* 是否启用了溢出检查。 */
        "overflow_checks": true,
        /* 是否启用了rpath。 */
        "rpath": false,
        /* 是否启用了增量编译。 */
        "incremental": true,
        /* 恐慌的策略,"unwind" 或 "abort" 。 */
        "panic": "unwind"
      },
      /* 为哪个平台建立的目标。如果值为 `null` ,则表明它是为主机建立的。
         否则,它是目标三元组的字符串(如 "x86_64-unknown-linux-gnu" )。 */
      "platform": null,
      /* 该单元的 "mode" 。有效值:

         * "test" — 使用 `rustc` 作为测试来构建。
         * "build" — 使用 `rustc` 构建。
         * "check" — 在 "check" 模式下使用 `rustc` 构建。
         * "doc" — 使用 `rustdoc` 构建。
         * "doctest" — 使用 `rustdoc` 进行测试。
         * "run-custom-build" — 表示构建脚本的执行。
      */
      "mode": "build",
      /* 在这个单元上启用的特性数组字符串。 */
      "features": ["somefeat"],
      /* 这是否是一个标准库单元,是不稳定的 build-std 功能的一部分。如果没有设置,视为 `false` 。 */
      "is_std": false,
      /* 该单元的依赖数组。 */
      "dependencies": [
        {
          /* 依赖的 "单位" 数组中的索引。 */
          "index": 1,
          /* 此依赖项将被称为的名称。 */
          "extern_crate_name": "unicode_xid",
          /* 这个依赖是否是 "public" 的,是不稳定的公共依赖特性的一部分。如果没有设置,则不启用公共依赖特性。*/
          "public": false,
          /* 该依赖是否被注入到 prelude 中,目前由 build-std 功能使用。如果没有设置,视为 `false` 。 */
          "noprelude": false
        }
      ]
    },
    // ...
  ],
  /* "单位" 数组中作为依赖图 "根" 的索引数组。 */
  "roots": [0],
}

Profile rustflags option

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

cargo-features = ["profile-rustflags"]

[package]
# ...

[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.org/nightly/ 。 要改变这种行为,请使用 doc.extern-map.std 设置。

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

值为 "local" 意味着链接到在 rustc 系统根中找到的文档。如果你使用的是rustup,这个文档可以用 rustup component add rust-docs 来安装。

默认值是 "remote"

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

per-package-target

per-package-target 特性在配置清单中增加了两个键:package.default-targetpackage.forced-target 。 第一个键使包在默认情况下 (即没有传递 --target 参数时)为某个目标进行编译。第二种是使包总是为该目标编译。

Example:

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

在这个例子中,crate总是为 wasm32-unknown-unknown 构建的,例如,因为它将被用作运行在主机(或在命令行上提供)目标上的主程序的插件。

artifact-dependencies

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

允许 Cargo 包依赖 bincdylibstaticlib crate,并在编译时使用这些crate构建的制品。

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

示例: 在构建脚本中使用 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"));
}

sparse-registry

sparse-registry 特性允许cargo与通过普通HTTP而不是git提供的远程注册中心进行交互。这些注册中心可以通过以 sparse+http://sparse+https:// 开头的URL识别。

当通过HTTP获取索引元数据时,Cargo 只下载相关crate的元数据,这可以节省大量时间和带宽。

sparse索引格式与基于git的索引的签出是一样的。

registries.crates-io.protocol 配置选项可以用来设置 crates.io 的默认协议。这个选项需要启用 -Z sparse-registry

  • sparse — 使用 sparse 索引。
  • git — 使用 git 索引。
  • 如果选项没有设置,若启用 -Z sparse-registry ,它将是sparse索引,否则它将是git索引。

Cargo在本地缓存crate元数据文件,并从服务器上捕获每个条目的 ETagLast-Modified HTTP头。 当刷新crate元数据时,Cargo会发送 If-None-MatchIf-Modified-Since 头,如果本地缓存有效,则允许服务器以HTTP 304响应,以节省时间和带宽。

publish-timeout

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

如果超时为 0 就不会发生任何检查。

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

# config.toml
[publish]
timeout = 300  # 按秒

registry-auth

通过在注册中心索引的config.json中添加配置选项,使Cargo在API请求、crate下载和sparse索引更新中包含授权令牌。

要使用这个特性,注册中心服务器必须在 config.json 中包含 "auth-required": true ,并且必须在Cargo命令行中传递 -Z registry-auth 标志。

当使用sparse协议时,Cargo会在获取任何其他文件之前尝试获取 config.json 文件。 如果服务器的回应是HTTP 401,那么Cargo将认为注册中心需要认证,并重新尝试请求 config.json ,其中包含认证令牌。

在认证失败 (或缺少认证令牌) 时,服务器可能包括 WWW-Authenticate 头和 Cargo login_url 信息,以表明用户可以去哪里获得令牌。

WWW-Authenticate: Cargo login_url="https://test-registry-login/me

This same flag is also used to enable asymmetric authentication tokens.

增加对Cargo的支持,以便在不通过网络发送私密信息的情况下对用户进行认证。

config.tomlcredentials.toml 文件中,有名为 private-key 的字段,它是以秘密的 subset of PASERK格式的私钥,用于签署非对称令牌。

可以用 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-keytokencredential-process 之一。

所有PASETO将包含 iat ,即ISO 8601格式的当前时间。Cargo将酌情包含以下内容:

  • sub一个可选的、非秘密的字符串,由注册中心选择,预期在每次请求时都会被取得。该值将是 config.toml 文件中的 private-key-subject
  • mutation 如果存在, 表示该请求是一个改变操作(如果不存在,则是一个只读操作),必须是字符串 publishyankunyank 之一。
    • name 与此请求有关的crate的名称。
    • vers 与此请求相关的包的版本字符串。
    • cksum 箱子内容的SHA256哈希值,是由64个小写的十六进制数字组成的字符串,只有当 mutation 等于 publish 时才必须出现。
  • challenge 从该服务器的session 401/403中收到的质询字符串。发出质询的注册中心必须跟踪哪些质询已经 issued/used ,并且在同一有效期内不接受特定的质询超过一次(避免跟踪每一个曾经发出的质询)。

"footer" (这是签名的一部分)将是一个UTF-8格式的JSON字符串,包括:

  • url 符合RFC 3986标准的URL,cargo从那里得到config.json文件。
    • 如果这是有HTTP索引的注册中心,那么这就是所有索引查询相对的基本URL。
    • 如果这是有GIT索引的注册中心,它是Cargo用来克隆索引的URL。
  • kid 用于签署请求的私钥的标识,使用PASERK IDs 标准。

PASETO包括被签名的信息,因而服务器不必为了检查签名而从请求中重构确切字符串。 服务器需要检查签名比对PASETO中的字符串是否有效,以及该字符串的内容是否与请求相符。 如果该请求应该有一个声明,但在PASETO中没有,那么该请求必须被拒绝。

credential-process

credential-process 特性增加了一个配置设置,通过调用一个外部进程来获取注册中心认证令牌。

Token认证被 cargo logincargo publishcargo ownercargo yank 命令所使用。此外,该特性增加新的 cargo logout 命令。

要使用这个特性,你必须在命令行中传递 -Z credential-process 标志。 此外,你必须删除当前保存在 credentials file 中的任何当前令牌(这可以通过新的 logout 命令来完成)。

credential-process 配置

要配置运行哪个进程来获取令牌,在 config fileregistry 表中指定进程:

[registry]
credential-process = "/usr/bin/cargo-creds"

如果你想对一个特定的注册中心使用不同的进程,可以在 registries 表中指定。

[registries.my-registry]
credential-process = "/usr/bin/cargo-creds"

该值可以是用空格分隔参数的字符串,也可以是TOML字符串数组。

命令行参数允许特殊的占位符,这些占位符将被替换成相应的值:

  • {name} — 注册中心的名称。
  • {api_url} — 注册中心 API 端点的基本URL。
  • {action} — 认证动作(如下所述)。

带有 cargo: 前缀的进程名称会从cargo下的 libexec 目录中加载。Cargo中包含了几个实验性的证书包装器,以提供对它们的便利访问:

[registry]
credential-process = "cargo:macos-keychain"

目前的包装器是:

  • cargo:macos-keychain: 使用macOS Keychain来存储令牌。
  • cargo:wincred: 使用Windows证书管理器来存储令牌。
  • cargo:1password: 使用1password op CLI来存储令牌。你必须从 1password 网站安装 op CLI。你必须至少运行一次op signin,并加上适当的参数(如 op signin my.1password.com user@example.com ),除非你提供地址和电子邮件参数。除非设置了适当的 OP_SESSION 环境变量,否则每次请求时都需要主密码。它支持以下命令行参数。
    • --account: 使用的账户简写名称。
    • --vault: 使用的保险名称。
    • --sign-in-address: 登录地址,是一个网址,如 my.1password.com
    • --email: 用来登录的电子邮件地址。

GNOME libsecret 有包装器,可以在Linux系统上存储令牌。由于构建的限制,这个包装器不能作为预编译的二进制文件使用。 这可以手动构建和安装。首先,使用你的系统包管理器安装 libsecret (例如,sudo apt install libsecret-1-dev)。 然后用cargo install cargo-credential-gnome-secret 构建并安装包装器。在配置中,使用二进制文件的路径,如下所示:

[registry]
credential-process = "cargo-credential-gnome-secret {action}"

credential-process 接口

Cargo支持两种不同的token进程。简单的 "basic" 类型只在Cargo需要令牌时才会被调用。 这是为了与密码管理器进行简单而方便的集成,通常可以使用已有的工具。 更高级的 "Cargo" 类型支持作为命令行参数传递的不同动作。 这样做的目的是为了获得更好的集成体验,代价是需要一个Cargo特定的进程来粘合到密码管理器上。 Cargo会根据 "credential-process" 的定义来决定支持哪种类型。 如果它包含 {action} 参数,那么它就会使用高级样式,否则它就假定它只支持 "basic" 样式。

基础认证器

基础认证器是在stdout上返回一个令牌的进程。新行将被修整。该进程继承了用户的 stdin 和 stderr 。它应在成功时退出0,在错误时退出非零。

在这种形式下,不支持 cargo logincargo logout ,如果使用,会返回一个错误。

Cargo认证器

Cargo和进程之间的协议是非常基本的,目的是确保认证过程尽可能简单。 Cargo将执行进程,其 {action} 参数表明要执行的动作。

  • store — 将给定令牌可靠存储。
  • get —从存储中获取令牌。
  • erase — 从存储中移除令牌。

cargo login 命令使用 store 来保存令牌。需要认证的命令,如 cargo publish ,使用 get 检索令牌。 cargo logout 使用 erase 命令来删除令牌。

进程继承了用户的stderr,所以进程可以显示信息。 有些值是通过环境变量传递进来(见下文)。预期的交互作用是:

  • store — 令牌被发送到进程的stdin中,以换行结束。进程应该根据注册中心的名称来存储令牌。如果进程失败,它应该以非零的退出状态退出。

  • get — 进程应将令牌发送到其stdout(尾部的换行将被修整)。进程继承用户的stdin,如果它需要接收输入的话。

    如果进程无法完成请求,它应该以非零退出代码退出。

  • erase — 该进程应该删除与注册中心名称相关联的令牌。如果没有找到令牌,进程应该以0状态退出。

环境

以下环境变量提供给被执行的命令:

  • CARGO — 执行命令的 cargo 二进制文件的路径。
  • CARGO_REGISTRY_INDEX_URL — 注册中心索引的URL。
  • CARGO_REGISTRY_NAME_OPT — 注册中心的可选名称。不应作为存储键使用。并不总是可用的。

cargo logout

增加新的 cargo logout 命令,使其更容易从存储中删除令牌。这同时支持 credentials file 令牌和 credential-process 令牌。

当与 credentials 文件令牌一起使用时,它需要 -Z unstable-options 命令行选项:

cargo logout -Z unstable-options

当与 credential-process 配置一起使用时,使用 -Z credential-process 命令行选项:

cargo logout -Z credential-process

cargo config

cargo config 子命令提供了一种显示cargo加载的配置文件的方法。 它目前包括 get 子命令,可以接受可选的配置文件来显示。

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

如果不包含配置值,它将显示所有的配置值。参见 --help 输出,了解更多可用的选项。

doctest-in-workspace

-Z doctest-in-workspace 标志改变了运行文档测试时使用的当前工作目录的行为。 曾经,Cargo运行 rustdoc --test 时是相对于包的根目录,路径相对于根目录。 然而,这与 rustcrustdoc 在工作空间的正常运行方式不一致,它们是相对于工作空间根目录运行。 这种不一致会导致各种问题,比如在传递 RUSTDOCFLAGS 时,使用相对路径,或者处理诊断输出。

-Z doctest-in-workspace 标志使cargo切换到从工作空间的根运行 rustdoc 。 它还将 --test-run-directory 传递给 rustdoc ,以便在运行测试时,从包的根目录运行。 这保留了向后的兼容性,并且与正常的单元测试的运行方式一致。

rustc --print

cargo rustc --print=VAL--print 标志转发给 rustc ,以便从 rustc 中提取信息。 在运行 rustc 时,会有相应的 --print 标志, 然后立即退出,不进行编译。将其作为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"

scrape-examples

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

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

默认情况下,Cargo会从记录的包的例子目标中抓取实例。 你可以用 doc-scrape-examples 标志单独启用或禁用目标,例如:

# 启用从库中抓取实例
[lib]
doc-scrape-examples = true

# 禁用从实例目标中抓取实例
[[example]]
name = "my-example"
doc-scrape-examples = false

关于测试的说明: 在测试目标上启用 doc-scrape-examples 目前没有任何效果。从测试中抓取例子是一项正在进行的工作。

关于dev-依赖的说明: 记录库通常不需要crate的dev-依赖。然而,示例目标需要dev-依赖。 为了向后兼容, -Z rustdoc-scrape-examplescargo doc 引入dev-依赖要求。 因此,在以下情况下,将 不会 从示例目标中抓取示例:

  1. 没有被记录的目标需要dev-依赖, AND
  2. 至少有一个目标被记录的crate有dev-依赖, AND
  3. 对于所有 [[example]] 目标,doc-scrape-examples 参数未设置或为假。

如果你想让实例从实例目标中被抓取,那么你必须不满足上述条件之一。 例如,你可以为一个例子目标设置 doc-scrape-examples 为 true,这就向Cargo发出信号,你可以为 cargo doc 建立dev-依赖。

check-cfg

-Z check-cfg 命令行可以在编译时检查 #[cfg]cfg! 中的名称和值。 #[link]#[cfg_attr] 中的名称和值,使用 rustcrustdoc 不稳定的 --check-cfg 命令行。

它的值是:

  • features: 通过 --check-cfg=values(feature, ...) 启用特性检查。 注意这个命令行选项可能会成为稳定时的默认选项。
  • names: 通过 --check-cfg=names() 实现众所周知的名称检查。
  • values: 通过 --check-cfg=values() 实现众所周知的值检查。
  • output: 启用构建脚本中的 rustc-check-cfg

例如:

cargo check -Z unstable-options -Z check-cfg=features
cargo check -Z unstable-options -Z check-cfg=names
cargo check -Z unstable-options -Z check-cfg=values
cargo check -Z unstable-options -Z check-cfg=features,names,values

Or for output:

#![allow(unused)]
fn main() {
// build.rs
println!("cargo:rustc-check-cfg=names(foo, bar)");
}
cargo check -Z unstable-options -Z check-cfg=output

cargo:rustc-check-cfg=CHECK_CFG

rustc-check-cfg 指令告诉Cargo将给定的值传递给编译器 --check-cfg 标志。 这可用于编译时检测意外的条件编译名称或值。

这只能与 -Zcheck-cfg=output 结合使用,否则会被忽略并发出警告。

如果你想集成Cargo的特性,请使用 -Zcheck-cfg=features ,而不是试图用这个选项手动完成。

稳定和删除特性

编译进度

编译进度功能在1.30版本中得到了稳定。进度条现在是默认启用的。 参见 term.progress 了解更多关于控制该特性的信息。

版次

Cargo.toml 中指定 edition 已在1.31版本中得到稳定。 请参阅 the edition field 以了解有关指定该字段的更多信息。

重命名依赖

Cargo.toml 中指定重命名依赖,在1.31版本中已经稳定。 参见 renaming dependencies 了解更多关于重命名依赖的信息。

备用注册中心

在1.34版本中,对备用注册中心的支持已经稳定下来了。 请参阅 Registries chapter 了解更多关于备用注册中心的信息。

脱机模式

脱机功能在1.36版本中已经稳定下来了。 参见 --offline flag,了解更多关于使用脱机模式的信息。

发表锁定文件

1.37版本中删除了 publish-lockfile 功能。如果包包含二进制目标,则在发布包时总是包括 Cargo.lock 文件。 cargo install 需要 --locked 标志来使用 Cargo.lock 文件。 更多信息见 cargo packagecargo install

默认运行

default-run 功能在1.37版本中已经稳定下来。参见 the `default-run'field 以了解更多关于指定默认运行目标的信息。

缓存信息

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

安装升级

install-upgrade 特性在1.41版本中得到了稳定。cargo install现在会在包出现过期时自动升级。更多信息请参见 cargo install 文档。

Profile覆盖

Profile 覆盖已经在1.41版本中得到稳定。请参阅Profile Overrides以了解更多关于使用覆盖的信息。

Config Profiles

在Cargo 配置文件和环境变量中指定配置文件的做法在1.43版本中已经稳定下来。 参见 config [profile] table 以了解更多关于在配置文件中指定 profile 的信息。

crate版本

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

特性

在1.51版本中,-Z features 标志已经稳定下来。参见 feature resolver version 2 以了解更多关于使用新特性解析器的信息。

包特性

-Z package-features 标志在1.51版本中已经稳定了。 参见 resolver version 2 command-line flags 以了解更多关于使用特性 CLI 选项的信息。

解析器

Cargo.toml 中的 Cargo.toml 特性在1.51版本中已经稳定。 请参阅 resolver versions 以了解有关指定解析器的更多信息。

在1.56版本中,用于在构建脚本中指定额外链接器参数的 extra-link-arg 功能已经稳定了。 请参阅 build script documentation 以了解更多关于指定额外链接器参数的信息。

configurable-env

在Cargo配置中指定环境变量的 configurable-env 功能在1.56版本中已经稳定下来。 关于配置环境变量的更多信息,请参见 config documentation

rust-version

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

codegen-backend

codegen-backend 特性使我们有可能使用配置文件来选择rustc使用的codegen后端。

Example:

[package]
name = "foo"

[dependencies]
serde = "1.0.117"

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

patch-in-config

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

edition 2021

2021 版次在1.56版本中已经稳定下来了。 参见edition field,了解更多关于设置版次的信息。 参见cargo fix --editionThe Edition Guide了解更多关于迁移现有项目的信息。

自定义命名的配置文件

自定义命名的配置文件已经在1.57版本中得到稳定。请参阅 profiles chapter 了解更多信息。

Profile strip option

配置文件 strip 选项在1.59版本中已经稳定了。更多信息请参见 profiles chapter

未来不兼容报告

在1.59版本中,对生成未来不兼容报告的支持已经稳定下来了。 更多信息请参见 future incompat report chapter

名称空间特性

在1.60版本中,名称空间特性已经稳定下来了。 更多信息请参见Features chapter

弱依赖性特性

弱依赖性特性在1.60版本中已经稳定下来。 更多信息请参见Features chapter

timings

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

config-cli

--config CLI选项在1.63版本中已经稳定。更多信息请参见 config documentation

multitarget

-Z multitarget 选项在1.64版本中已经稳定了。参见 build.target 以了解更多关于设置默认目标平台三元组的信息。

crate-type

在1.64版本中,cargo rustc--crate-type 标志已经稳定。更多信息请参见 cargo rustc documentation

工作空间继承

工作空间继承在1.64版本中得到了稳定。 参见 workspace.package,workspace.dependencies,和 inheriting-a-dependency-from-a-workspace 获得更多信息。

terminal-width

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