不稳定特性
实验性的 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 版本。
不稳定特性列表
- 仅在不稳定版本中提供的特性
- -Z allow-features — 提供一种限制使用哪些不稳定特性的方法。
- 构建脚本和链接
- Metabuild — 提供声明式构建脚本。
- 解析器和特性
- no-index-update — 阻止 cargo 更新索引缓存。
- avoid-dev-deps — 阻止解析器在解析过程中包含开发依赖。
- minimal-versions — 强制解析器使用最低兼容版本而非最高版本。
- direct-minimal-versions — 强制解析器仅对直接依赖使用最低兼容版本而非最高版本。
- public-dependency — 允许将依赖项分类为公共或私有。
- msrv-policy — MSRV 感知的解析器和版本选择。
- precise-pre-release — 允许通过
update --precise
选择预发布版本。 - sbom — 为编译产物生成 SBOM 前置文件。
- update-breaking — 允许使用
update --breaking
升级到不兼容 SemVer 的版本。 - feature-unification — 在工作空间中启用新的特性统一模式。
- 输出行为
- 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
- rustdoc-map — 提供文档映射,使其可以链接到 docs.rs 等外部站点。
- scrape-examples — 在文档中显示示例。
- output-format — 允许文档也以实验性的 JSON 格式 输出。
Cargo.toml
扩展- Profile
rustflags
选项 — 直接传递给 rustc。 - codegen-backend — 选择 rustc 使用的代码生成后端。
- per-package-target — 为每个单独的包设置使用的
--target
。 - artifact dependencies — 允许将构建产物包含到其他构建产物中,并为不同的目标构建它们。
- Profile
trim-paths
选项 — 控制构建输出中文件路径的清理(sanitization)。 [lints.cargo]
— 允许配置 Cargo 的 lint 警告。- path bases — 路径依赖项的命名基础目录。
- Profile
- 信息和元数据
- 构建计划 — 输出 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
的消息格式。
- gitoxide — 对于一组操作,使用
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 工具(如 rustc
或 rustdoc
)。因此,如果您运行 cargo -Zallow-features=
,则无法使用任何不稳定的 Cargo 或 Rust 特性。
no-index-update
-Z no-index-update
标志确保 Cargo 不尝试更新注册表索引。这适用于 Crater 等会发出许多 Cargo 命令的工具,您希望避免每次更新索引的网络延迟。
mtime-on-use
-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 install
或 cargo 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/release
或 target/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
构建计划
- Tracking Issue: #5579
构建计划特性已弃用,并可能在未来版本中移除。参见 https://github.com/rust-lang/cargo/issues/7614。
build
命令的 --build-plan
参数将输出 JSON 格式的信息,说明会运行哪些命令,而不实际执行任何操作。这在与另一个构建工具集成时很有用。示例:
cargo +nightly build --build-plan -Z unstable-options
Metabuild
- Tracking Issue: rust-lang/rust#49803
- RFC: #2196
Metabuild 是一种实现声明式构建脚本的特性。您无需编写 build.rs
脚本,而是在 Cargo.toml
的 metabuild
键中指定构建依赖项列表。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
- Tracking Issue: #44663
‘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: MSRV 感知的解析器
- #9930 (MSRV 感知的解析器)
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.0
将 my-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
- Tracking Issue: #12425
允许使用 --breaking
标志在 Cargo.toml
中升级跨越 SemVer 不兼容版本的依赖项版本要求。
这仅适用于符合以下条件的依赖项:
- 该包是工作空间成员的依赖项
- 该依赖项未被重命名
- 存在 SemVer 不兼容的版本
- 使用了“SemVer 运算符”(默认为
^
)
用户可以通过在命令行上指定包来进一步限制哪些包被升级。
示例:
$ cargo +nightly -Zunstable-options update --breaking
$ cargo +nightly -Zunstable-options update --breaking clap
这旨在扮演与 cargo-upgrade 类似的角色
build-std
- Tracking Repository: https://github.com/rust-lang/wg-cargo-std-aware
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,包括 core
、std
、alloc
和 proc_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,请将其报告到:
- Cargo — https://github.com/rust-lang/cargo/issues/new — 报告实现方面的 bug
- 跟踪仓库 — https://github.com/rust-lang/wg-cargo-std-aware/issues/new — 提问大型设计问题。
此外,如果您想看到尚未实现的特性,或者有什么地方不完全符合您的期望,请随时查看跟踪仓库的问题跟踪器,如果其中没有您的问题,请提交一个新问题!
build-std-features
- Tracking Repository: https://github.com/rust-lang/wg-cargo-std-aware
此标志是 -Zbuild-std
特性标志的同级标志。这将配置构建标准库时为标准库本身启用的特性。目前默认启用的特性是 backtrace
和 panic-unwind
。此标志需要一个逗号分隔的列表,如果提供了该列表,它将覆盖默认启用的特性列表。
binary-dep-depinfo
- Tracking rustc issue: #63012
-Z binary-dep-depinfo
标志使 Cargo 将相同的标志转发给 rustc
,从而使 rustc
将所有二进制依赖项的路径包含在“dep info”文件(扩展名为 .d
)中。Cargo 随后使用这些信息进行变更检测(如果任何二进制依赖项发生变化,则 crate 将被重新构建)。主要用例是构建编译器本身,编译器对标准库有隐式依赖,否则这些依赖将不会被跟踪以进行变更检测。
checksum-freshness
- Tracking issue: #14136
-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#64158,test
crate 支持使用 test-per-process 的 -C panic=abort
,这有助于避免多次编译 crate 图。
目前尚不清楚此特性将如何在 Cargo 中稳定化,但我们希望以某种方式将其稳定化!
config-include
- Tracking Issue: #7723
此特性需要 -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
键时:
- 首先从
include
路径加载配置值。- 如果
include
键的值是路径数组,则按从左到右的顺序加载并合并每个路径中的配置值。 - 如果从
include
路径加载的配置值也包含include
键,则递归执行此步骤。
- 如果
- 然后,将当前配置文件的值合并到从
include
路径加载的配置之上。
target-applies-to-host
历史上,Cargo 对于来自环境变量和 [target]
的 linker
和 rustflags
配置选项是否应用于构建脚本、插件以及始终为 host 平台构建的其他产物的行为一直有些不一致。当不传递 --target
时,Cargo 对构建脚本和其他所有编译产物应用相同的 linker
和 rustflags
。然而,当传递 --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
配置文件中的 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
- Tracking Issue: #8002
可以将 --unit-graph
标志传递给任何构建命令(build
、check
、run
、test
、bench
、doc
等),以向标准输出(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
选项
- Original Issue: rust-lang/cargo#7878
- Tracking Issue: rust-lang/cargo#10271
此特性在 [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
- Tracking Issue: #8296
此特性添加了传递给 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-target
和 package.forced-target
。第一个键使包在默认情况下(即未传递 --target
参数时)为某个目标编译。第二个键使包始终为该目标编译。
示例:
[package]
forced-target = "wasm32-unknown-unknown"
在此示例中,该 crate 始终为 wasm32-unknown-unknown
目标构建,例如因为它可以作为插件用于在 host 目标(或命令行指定目标)上运行的主程序。
artifact dependencies
Artifact 依赖项允许 Cargo 包依赖于 bin
、cdylib
和 staticlib
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
— 这是一个布尔值,指示是否也将依赖项的库构建为正常的 Rustlib
依赖项。此字段只能在指定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
类型(大写,如CDYLIB
、STATICLIB
或BIN
),而<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_CMAKE
和CARGO_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
- Tracking Issue: 11222
配置文件中的 publish.timeout
键可用于控制 cargo publish
从发布包到注册表到其在本地索引中可用之间等待的时间。
超时时间设置为 0
将阻止任何检查发生。当前默认值为 60
秒。
它需要设置 -Zpublish-timeout
命令行选项。
# config.toml
[publish]
timeout = 300 # in seconds
asymmetric-token
-Z asymmetric-token
标志启用 cargo:paseto
凭证提供者,它允许 Cargo 向注册表进行身份验证,而无需在网络上传输秘密信息。
在 config.toml
和 credentials.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-key
或 token
中的一个。
所有 PASETO 都将包含 iat
,即当前时间的 ISO 8601 格式表示。Cargo 将在适当的情况下包含以下信息:
sub
一个可选的非秘密字符串,由注册表选择,预计在每个请求中声明。其值将是config.toml
文件中的private-key-subject
。mutation
如果存在,表示此请求是一个修改操作(如果不存在则是只读操作),必须是字符串publish
、yank
或unyank
之一。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
- Tracking Issue: #9357
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
引入开发依赖的要求。因此,在以下情况下,不会从示例目标中抓取示例:
- 没有需要文档化的目标需要开发依赖,并且
- 至少一个包含需要文档化的目标的 crate 具有开发依赖,并且
- 所有
[[example]]
目标的doc-scrape-examples
参数未设置或为 false。
如果您希望从示例目标中抓取示例,则必须不满足上述条件之一。例如,您可以将某个示例目标的 doc-scrape-examples
设置为 true,这将向 Cargo 发出信号,表明您允许为 cargo doc
构建开发依赖。
rustdoc 的 output-format
- Tracking Issue: #13283
此标志决定 cargo rustdoc
的输出格式,接受 html
或 json
,为工具提供了一种依赖 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
- Tracking Issue: #11813
启用‘gitoxide’不稳定特性后,所有或指定的 git 操作将由 gitoxide
crate 执行,而不是 git2
。
虽然 -Zgitoxide
启用了所有当前已实现的特性,但可以使用 -Zgitoxide=operation[,operationN]
语法单独选择使用 gitoxide
运行哪些 git 操作。
有效的操作如下:
fetch
- 所有 fetch 操作都使用gitoxide
完成,包括 git 依赖以及 crate 索引。checkout
(计划中) - checkout 工作树,支持过滤器和子模块。
git
- Tracking Issue: #13285
启用‘git’不稳定特性后,gitoxide
和 git2
都会对 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
- Tracking Issue: #12207
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 <子命令>
的优先级如下:
- 内置子命令或单文件包(二者择一)
- 别名
- 外部子命令
如果参数具有以下特征之一,则将其识别为 manifest-command:
- 路径分隔符
.rs
扩展名- 文件名为
Cargo.toml
cargo run --manifest-path <路径>
与 cargo <路径>
之间的区别
cargo <路径>
使用<路径>
的配置运行,而不是当前目录的配置,更类似于cargo install --path <路径>
cargo <路径>
的详细级别低于常规默认值。传递-v
以获得正常输出。
文档更新
Profile trim-paths
选项
- Tracking Issue: rust-lang/cargo#12137
- Tracking Rustc Issue: rust-lang/rust#111540
这添加了一个新的 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
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
不是 none
或 false
,则如果以下路径出现在选定范围内,它们将被清理:
- 标准库和核心库(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
- 当前包的路径将被剥离,相对于当前工作空间根目录,例如:
/home/username/crate/src/lib.rs
->src/lib.rs
。 - 依赖包的路径将被替换为
[包名]-[版本]
。例如:/home/username/deps/foo/src/lib.rs
->foo-0.1.0/src/lib.rs
当标准库和核心库的源代码文件路径不在清理范围内时,输出的路径将取决于是否存在 rust-src
组件。如果存在,则某些路径将指向您文件系统上的源代码文件副本;如果不存在,则它们将显示为 /rustc/[rustc commit hash]/library/...
(就像选择清理时一样)。所有其他源代码文件的路径将不受影响。
这不会影响源代码中任何硬编码的路径,例如字符串中的路径。
环境变量
作为“Cargo 为构建脚本设置的环境变量”的新条目
CARGO_TRIM_PATHS
—trim-paths
profile 选项的值。false
、"none"
和空数组将被转换为none
。true
和"all"
将变为all
。非空数组中的值将连接成一个逗号分隔的列表。如果构建脚本引入了构建产物的绝对路径(例如通过调用编译器),用户可以请求在不同类型的产物中清理这些路径。常见的需要清理的路径包括OUT_DIR
、CARGO_MANIFEST_DIR
和CARGO_MANIFEST_PATH
,以及构建脚本引入的任何其他路径,例如 include 目录。
gc
- Tracking Issue: #12633
-Zgc
标志启用 Cargo 主目录中 Cargo 全局缓存的垃圾回收(garbage-collection)。这包括下载的依赖项,例如压缩的 .crate
文件、解压的 src
目录、注册表索引缓存和 git 依赖项。存在 -Zgc
时,Cargo 会跟踪任何索引和依赖项上次使用的时间,然后使用这些时间戳手动或自动删除一段时间未使用的缓存条目。
cargo build -Zgc
自动垃圾回收
自动删除发生在已经执行大量工作的命令上,例如所有构建命令(cargo build
、cargo test
、cargo 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
— 删除自给定时长以来未使用的注册表索引(包括其.crate
和src
文件)。--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]
- Tracking Issue: #12235
用于 cargo
的新的 lints
工具表,当使用 -Zcargo-lints
时,可用于配置 cargo
本身发出的 lint 警告。
[lints.cargo]
implicit-features = "warn"
这将与 RFC 2906 workspace-deduplicate
一起工作
[workspace.lints.cargo]
implicit-features = "warn"
[lints]
workspace = true
路径基础
- Tracking Issue: #14355
一个 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]
表格中指定即可使用。
workspace
- 如果项目是工作空间或工作空间成员,则此路径基被定义为工作空间根目录Cargo.toml
的父目录。
如果内置路径基名称也在配置中声明,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(打包工作空间)
- 跟踪问题:#10948
这允许 cargo 在工作空间中打包(或发布)多个 crate,即使它们之间存在相互依赖。例如,考虑一个包含包 foo
和 dep
的工作空间,其中 foo
依赖于 dep
。那么
cargo +nightly -Zpackage-workspace package -p foo -p dep
将打包 foo
和 dep
,而
cargo +nightly -Zpackage-workspace publish -p foo -p dep
将发布 foo
和 dep
。如果 foo
和 dep
是工作空间中唯一的 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
选项。
特别需要反馈的方面
- 需要转义或引用的参数但未正确处理
- 信息不准确
- 命令行解析中的错误
- 未报告其补全信息的参数
- 如果已知问题正在引起麻烦
反馈可以分为
- 报告了哪些补全候选项
- 已知问题:#14520,
A-completions
- 报告问题 或 讨论行为
- 已知问题:#14520,
- Shell 集成、命令行解析和补全过滤
- 已知问题:clap#3166,clap 的
A-completions
- 报告问题 或 讨论行为
- 已知问题:clap#3166,clap 的
如何使用 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 package
和 cargo 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(额外链接器参数)
用于在构建脚本中指定额外链接器参数的 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.package、workspace.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
和 版本指南。