第30章 Cargo 不稳定功能(Unstable Features)
实验性的 Cargo 功能只能在 nightly 通道上使用。欢迎你试用这些功能,看看能否满足需求、是否存在问题。想了解更多细节,可以查看下面对应的跟踪 issue,如果希望持续跟进更新,点击 GitHub 上的 subscribe 按钮即可。
经过一段时间后,如果某个功能没有重大问题,就可以被稳定化(stabilize)。等当前的 nightly 版本进入 stable 通道后(通常需要 6 到 12 周),该功能便会在 stable 版本中可用。
根据功能的工作方式,启用不稳定功能有以下三种方式:
-
Cargo.toml中的新语法需要在文件顶部、所有 table 之前添加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。例如,新的--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)的unstabletable 中设置。例如:[unstable] mtime-on-use = true build-std = ["core", "alloc"]
下面介绍每个新功能时都会说明其使用方法。
最新 nightly 版本的本页内容,请参见nightly 版本。
不稳定特性列表
- 不稳定特性专属功能
- -Z allow-features — 限制可使用的不稳定特性。
- 构建脚本与链接
- Metabuild — 提供声明式构建脚本。
- Multiple Build Scripts — 允许使用多个构建脚本。
- Any Build Script Metadata — 允许任意构建脚本通过
cargo::metadata=key=value指定环境变量
- 解析器与特性
- no-index-update — 阻止 cargo 更新索引缓存。
- avoid-dev-deps — 阻止解析器在依赖解析时包含 dev-dependencies。
- minimal-versions — 强制解析器使用最低兼容版本而非最高版本。
- direct-minimal-versions — 强制解析器使用最低兼容版本而非最高版本。
- public-dependency — 允许将依赖项标记为 public 或 private。
- msrv-policy — 感知 MSRV 的解析器与版本选择策略
- precise-pre-release — 允许使用
update --precise选择预发布版本 - sbom — 为编译产物生成 SBOM 前置文件
- update-breaking — 允许使用
update --breaking升级到破坏性版本 - feature-unification — 在 workspace 中启用新的特性统一模式
- lockfile-publish-time — 限制解析器仅选择发布于指定时间之前的包
- min-publish-age — 过滤掉发布时间晚于配置的最小发布时间的依赖版本。
- 输出行为
- artifact-dir — 指定一个目录,将产物复制到该目录中。
- build-dir-new-layout — 启用新的 build-dir 文件系统布局
- Different binary name — 为构建出的二进制文件指定一个与 crate 名不同的名称。
- root-dir — 控制打印路径时所参照的根目录
- 编译行为
- mtime-on-use — 每次使用依赖时都更新其最后修改时间戳,从而提供一种删除未使用产物的机制。
- build-std — 从源码构建标准库,而不是使用预编译的二进制文件。
- build-std-features — 设置构建标准库时使用的 features。
- binary-dep-depinfo — 让 dep-info 文件跟踪二进制依赖。
- checksum-freshness — 启用后,判断 crate 是否需要重新编译时使用文件校验和而非文件 mtime。
- panic-abort-tests — 允许使用 “abort” panic 策略运行测试。
- host-config — 允许为主机构建目标设置类似
[target]的配置项。 - no-embed-metadata — 向编译器传递
-Zembed-metadata=no,避免将元数据嵌入 rlib 和 dylib 产物,以节省磁盘空间。 - target-applies-to-host — 改变某些 flags 是否会传递给主机构建目标。
- gc — 全局缓存的垃圾回收。
- open-namespaces — 允许多个包共用同一个 API 命名空间
- panic-immediate-abort — 向编译器传递
-Cpanic=immediate-abort。 - compile-time-deps — 为 rust-analyzer 提供的永久不稳定特性
- fine-grain-locking — 使用细粒度锁,而不是锁定整个构建缓存
- json-target-spec — 允许使用
.json自定义目标规范。 - hint-msrv — 允许 Cargo 设置
-Zhint-msrv
- rustdoc
- rustdoc-map — 提供文档到 docs.rs 等外部网站的链接映射。
- scrape-examples — 在文档中展示示例代码。
- output-format — 允许以实验性的 JSON 格式输出文档。
- rustdoc-depinfo — 在 rustdoc 的重新构建检测中使用 dep-info 文件。
- rustdoc-mergeable-info — 使用 rustdoc 可合并的跨 crate 信息文件。
Cargo.toml扩展- Profile 的
rustflags选项 — 直接传给 rustc。 - Profile 的
hint-mostly-unused选项 — 提示某个依赖基本未被使用,以优化编译时间。 - codegen-backend — 选择 rustc 使用的代码生成后端。
- per-package-target — 为每个包单独设置
--target。 - artifact dependencies — 允许将构建产物包含到其他构建产物中,并为不同 target 分别构建。
- Profile 的
trim-paths选项 — 控制构建输出中文件路径的清理方式。 [lints.cargo]— 允许为 Cargo 配置 lint。- path bases — 为路径依赖提供命名的基准目录。
unstable-editions— 允许使用尚未稳定的 edition。
- Profile 的
- 信息与元数据
- unit-graph — 以 JSON 输出 Cargo 的内部图结构。
cargo rustc --print— 以--print调用 rustc 来显示相关信息。- 构建分析 — 记录并持久化每次运行的详细构建指标,并提供查询历史构建的新命令。
rustc-unicode— 在 Cargo 的报错信息中启用rustc的 Unicode 错误格式
- 配置
cargo config— 新增一个用于查看配置文件的子命令。
- 注册表
- publish-timeout — 控制上传 crate 与在索引中可用之间的超时时间
- asymmetric-token — 支持使用非对称加密的认证令牌(
cargo:paseto提供商)。
- 其他
- gitoxide — 对于一组操作,使用
gitoxide替代git2。 - script — 启用对单文件
.rs包的支持。 - native-completions — 将 cargo shell 补全迁移到原生补全。
- 包消息格式 —
cargo package的消息格式。 fix-edition— 一个永久不稳定的版本迁移助手。- 管道子命令 — 作为 Cargo API 的底层命令,例如
cargo metadata
- 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 不去更新 registry 索引。这是为 Crater 这类会执行大量 Cargo 命令的工具设计的,可以避免每次更新索引带来的网络延迟。
mtime-on-use
-Z mtime-on-use 标志是一个实验性功能,让 Cargo 更新被使用文件的 mtime,方便 cargo-sweep 这类工具检测哪些文件已过期。很多工作流需要在所有 cargo 调用中都设置这个选项。为了让它更实用,可以在 .cargo/config.toml 中设置 unstable.mtime_on_use 标志(或设置对应的环境变量),这样所有 nightly cargo 的调用都会自动启用 -Z mtime-on-use。(stable 版本会忽略该配置项)
avoid-dev-deps
在运行 cargo install 或 cargo 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/release 或 target/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!() 宏输出的路径。
Metabuild
- 跟踪议题: rust-lang/rust#49803
- RFC: #2196
Metabuild 是一种声明式构建脚本功能。它不需要你编写 build.rs 脚本,而是让你在 Cargo.toml 的 metabuild 字段中列出一组构建依赖。系统会自动生成一个构建脚本,并按顺序执行这些构建依赖。Metabuild 包随后可以从 Cargo.toml 中读取元数据,以决定其具体行为。
要在 Cargo.toml 中使用 Metabuild,需要在文件顶部添加 cargo-features,在 package 部分添加 metabuild 字段,在 build-dependencies 中列出依赖,并将 Metabuild 包所需的元数据放在 package.metadata 下。示例:
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 构建脚本相同。
Multiple Build Scripts(多个构建脚本)
Multiple Build Scripts 特性允许在一个包中包含多个构建脚本。
在 Cargo.toml 顶部添加 cargo-features,并加入 multiple-build-scripts 来启用该特性。然后在 package.build 中以数组形式指定各构建脚本的路径,例如:
cargo-features = ["multiple-build-scripts"]
[package]
name = "mypackage"
version = "0.0.1"
build = ["foo.rs", "bar.rs"]
访问输出目录:每个构建脚本的输出目录可以通过 <script-name>_OUT_DIR 访问,其中 <script-name> 是构建脚本的文件名主干(不含扩展名),保持原样。例如 foo/bar.rs 对应的环境变量是 bar_OUT_DIR。(仅在编译期间设置,可通过 env! 宏访问)
Any Build Script Metadata(任意构建脚本的 metadata)
- Tracking Issue: #14903
允许任意构建脚本通过 cargo::metadata=key=value 指定环境变量。
依赖它的构建脚本可以在运行时读取 CARGO_DEP_<dep>_<key> 环境变量来获取这些键值对。对于声明了 links 的 crate 构建脚本,DEP_<links>_<key> 和 CARGO_DEP_<dep>_<key> 都会被设置。
注意,CARGO_DEP_<dep>_<key> 中的 dep 和 key 都会转为大写,连字符(-)会被替换为下划线(_)。
public-dependency
- Tracking Issue: #44663
‘public-dependency’ 特性允许把依赖标记为 ‘public’(公开)或 ‘private’(私有)。启用该特性后,cargo 会向 rustc 传递额外信息,使 exported_private_dependencies lint 能正常工作。
启用方式有两种,一是使用 -Zpublic-dependency:
cargo +nightly run -Zpublic-dependency
二是使用 [unstable] 配置表,例如:
# .cargo/config.toml
[unstable]
public-dependency = true
也可以在 cargo-features 中启用 public-dependency,但这种方式已废弃,很快将被移除。
cargo-features = ["public-dependency"]
[dependencies]
my_dep = { version = "1.2.3", public = true }
private_dep = "2.0.0" # 默认为 'private'
文档更新:
- 工作空间文档的 “The
dependenciestable” 一节中,需注明public在workspace.dependencies中是不支持的字段 - 使用
public要求的最低 MSRV 为 1.83(参见 #14507)
msrv-policy
- RFC:感知 MSRV 的依赖解析器
- #9930(感知 MSRV 的 resolver)
这是 RFC 2495 下所有感知 MSRV 的 cargo 特性的统称不稳定特性。
感知 MSRV 的 cargo add
已于 1.79 稳定,见 #13608。
感知 MSRV 的 resolver
已于 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
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.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 格式,遵循命名规则
<artifact>.cargo-sbom.json。JSON 文件包含依赖项、目标、特性以及使用的 rustc 编译器的信息。
所有被提升到 target 或 artifact 目录中的可执行和可链接输出,都会生成 SBOM 前置文件。
Cargo 为 crate 设置的环境变量
CARGO_SBOM_PATH—— 生成的 SBOM 前置文件列表,以平台 PATH 分隔符分隔。可以用std::env::split_paths拆分该列表。
SBOM 前置文件格式
{
// Schema 版本。
"version": 1,
// 根 crate 在 crates 数组中的索引。
"root": 0,
// 所有 crate 的数组。如果同一个 crate 以不同方式编译(不同的 opt-level、features 等),可能出现重复。
"crates": [
{
// 完整的 package ID 规格
"id": "path+file:///sample-package#0.1.0",
// target 类型列表:bin、lib、rlib、dylib、cdylib、staticlib、proc-macro、example、test、bench、custom-build
"kind": ["bin"],
// 已启用的 feature 标志。
"features": [],
// 此 crate 的依赖。
"dependencies": [
{
// 在 crates 数组中的索引。
"index": 1,
// 依赖类型:
// Normal:链接到此 crate 产出物的依赖。
// Build:构建此 crate 时使用的编译期依赖(build-script 或 proc-macro)。
"kind": "normal"
},
{
// 一个 crate 可以同时以 normal 和 build 两种方式依赖另一个 crate。
"index": 1,
"kind": "build"
}
]
},
{
"id": "registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.16",
"kind": ["bin"],
"features": [],
"dependencies": []
}
],
// 用于执行编译的 rustc 相关信息。
"rustc": {
// 编译器版本
"version": "1.86.0-nightly",
// 编译器 wrapper
"wrapper": null,
// 编译器 workspace wrapper
"workspace_wrapper": null,
// rustc 的 commit hash
"commit_hash": "bef3c3b01f690de16738b1c9f36470fbfc6ac623",
// 宿主平台的 target triple
"host": "x86_64-pc-windows-msvc",
// 详细版本信息:`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 不兼容版本升级依赖的版本要求。
该功能只对满足以下条件的依赖生效:
- 该 package 是某个 workspace 成员的依赖
- 该依赖没有被重命名
- 存在一个 SemVer 不兼容的版本
- 使用了“SemVer 操作符”(
^,这是默认值)
用户可以通过在命令行中指定特定包来进一步限制哪些包会被升级。
示例:
$ cargo +nightly -Zunstable-options update --breaking
$ cargo +nightly -Zunstable-options update --breaking clap
此功能旨在发挥类似 cargo-upgrade 的作用
build-std
build-std 功能允许 Cargo 在编译 crate 依赖图时,将标准库本身也作为其中的一部分进行编译。该功能在历史上也被称为“std-aware Cargo”。目前该功能仍处于早期开发阶段,且是一个极具潜力的重大功能扩展。即便以目前最小的形态来看,这一功能也有巨大的文档工作量,如果你希望保持关注其最新进展,建议跟踪该 跟踪仓库 及其相关 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。
使用要求
简单总结,目前使用 -Z build-std 需要满足以下条件:
- 必须通过
rustup component add rust-src安装 libstd 源码 - 必须同时使用 nightly 版本的 Cargo 和 rustc
- 所有
cargo调用都必须带上-Z build-std标志
报告 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 — 用于更宏观的设计问题
另外,如果你想看到某个尚未实现的功能,或者某些地方的表现不如预期,欢迎查看跟踪仓库的 issue tracker,如果没找到相关问题,欢迎提一个新 issue!
build-std-features
该 flag 与 -Zbuild-std 功能 flag 是配套的,用于在构建标准库时配置标准库自身启用的 features。目前默认启用的 features 是 backtrace 和 panic-unwind。该 flag 接受一个逗号分隔的列表,如果指定了它,就会覆盖默认的 features 列表。
binary-dep-depinfo
- 跟踪 rustc issue:#63012
-Z binary-dep-depinfo flag 会让 Cargo 把同样的 flag 转发给 rustc,从而使 rustc 在 "dep info" 文件(扩展名为 .d)中记录所有二进制依赖的路径。Cargo 随后利用这些信息进行变更检测——只要任何一个二进制依赖发生变化,对应的 crate 就会被重新构建。这个功能最主要的用例是构建编译器本身:编译器对标准库存在隐式依赖,如果不启用该功能,这些依赖不会纳入变更检测。
checksum-freshness
- 跟踪 issue:#14136
-Z checksum-freshness flag 会用文件校验和取代 Cargo fingerprint 中对文件 mtime 的使用。这在 mtime 实现不可靠的系统上,或者在 CI/CD 环境中最为有用。不同 Cargo 版本之间的校验和算法可能会在不另行通知的情况下发生变化。Cargo 通过 fingerprint 来判断一个 crate 是否需要重新构建。
目前,即使启用了 checksum-freshness,build script 摄取的文件仍会继续使用 mtime。这只是临时做法,并非长期方案。
panic-abort-tests
-Z panic-abort-tests 标志允许 Nightly 版本以 -Cpanic=abort 模式编译测试框架 crate。若未设置此标志,Cargo 将以 -Cpanic=unwind 模式编译测试及其所有依赖项,因为这是 test crate 目前唯一支持的操作方式。不过,自 rust-lang/rust#64158 起,test crate 已支持基于“每进程一测试”的 -C panic=abort 模式,这有助于避免多次编译相同的依赖图。
该功能在 Cargo 中如何标准化(stabilize)目前尚不明确,但我们希望将其以某种形式稳定下来!
target-applies-to-host
历史上,Cargo 在处理构建脚本、插件及其他始终针对宿主机平台构建的产物时,对来自环境变量及[target]配置段中的 linker 和 rustflags 选项是否生效,其行为曾有过不一致之处。
当未传入 --target 参数时,Cargo 会对构建脚本应用与其他编译产物相同的 linker 和 rustflags 设置。
然而,当传入 --target 参数时,Cargo 仅从[target.<host triple>]中读取 linker 设置,而不会应用任何 rustflags 配置。
这种双重行为容易令人困惑,同时也使得难以正确配置那些宿主机三元组(host triple)与目标三元组(target triple)恰好相同、但旨在宿主机上运行的产物仍需区别配置的场景。
-Ztarget-applies-to-host 会启用 Cargo 配置文件中的顶层 target-applies-to-host 设置,让用户可以选择启用不同(也更一致)的行为。当配置文件中未设置 target-applies-to-host 或设为 true 时,Cargo 保持现有行为不变(不过要注意 -Zhost-config 会改变这个默认值)。当设为 false 时,无论是否给 Cargo 传入 --target,主机构建产物都不会应用 [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 键可用于为主机构建目标传递参数,例如交叉编译时必须在主机系统(而非目标系统)上运行的 build script。它同时支持通用表和主机架构专属表,且匹配到的主机架构专属表优先于通用主机表。
使用该功能需要同时设置 -Zhost-config 和 -Ztarget-applies-to-host 命令行选项,并在 Cargo 配置文件中设置 target-applies-to-host = false。
# config.toml
[host]
linker = "/path/to/host/linker"
runner = "host-runner"
[host.x86_64-unknown-linux-gnu]
linker = "/path/to/host/arch/linker"
runner = "host-arch-runner"
rustflags = ["-Clink-arg=--verbose"]
[target.x86_64-unknown-linux-gnu]
linker = "/path/to/target/linker"
host.runner 配置用于包装宿主构建目标(如 build script)的执行过程,作用类似于 target.<triple>.runner 包装 cargo run/test/bench。
在 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
- Tracking Issue: #8002
--unit-graph 标志可以传给任何构建命令(build、check、run、test、bench、doc 等),它会在 stdout 输出一个 JSON 对象,表示 Cargo 内部的 unit 图。实际上不会构建任何东西,命令在打印后立即返回。每个 "unit" 对应一次编译器执行,对象中还包含各 unit 之间的依赖关系。
cargo +nightly build --unit-graph -Z unstable-options
这种结构能更完整地展现 Cargo 所理解的依赖关系。特别是 "features" 字段支持新的 feature 解析器,即同一个依赖可以用不同的 feature 构建多次。cargo metadata 从根本上无法表示不同依赖类别之间的 feature 关系,而且 feature 现在取决于运行的命令以及选中的包和目标。此外,它还能提供包内依赖的细节,比如 build script 或测试。
以下是 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
},
/* 此单元的 profile 设置。
这些值可能与 manifest 中定义的 profile 不一致。
单元可以使用修改后的 profile 设置。例如,测试可覆写 "panic"
设置,强制设为 "unwind"。
*/
"profile": {
/* 这些设置所派生的 profile 名称。 */
"name": "dev",
/* 以字符串形式表示的优化级别。 */
"opt_level": "0",
/* 以字符串形式表示的 LTO 设置。 */
"lto": "false",
/* 以整数形式表示的 codegen units。
若应使用编译器默认值,则为 `null`。
*/
"codegen_units": null,
/* 以整数形式表示的调试信息级别。
若应使用编译器默认值 (0),则为 `null`。
*/
"debuginfo": 2,
/* 是否启用 debug-assertions。 */
"debug_assertions": true,
/* 是否启用 overflow-checks。 */
"overflow_checks": true,
/* 是否启用 rpath。 */
"rpath": false,
/* 是否启用 incremental。 */
"incremental": true,
/* panic 策略,"unwind" 或 "abort"。 */
"panic": "unwind"
},
/* 此目标正在构建的平台。
`null` 表示为目标主机。
否则为目标三元组字符串(如 "x86_64-unknown-linux-gnu")。
*/
"platform": null,
/* 此单元的 "mode"。合法值:
* "test" --- 使用 `rustc` 作为测试构建。
* "build" --- 使用 `rustc` 构建。
* "check" --- 使用 `rustc` 的 "check" 模式构建。
* "doc" --- 使用 `rustdoc` 构建。
* "doctest" --- 使用 `rustdoc` 测试。
* "run-custom-build" --- 代表执行构建脚本。
*/
"mode": "build",
/* 此单元启用的 features 字符串数组。 */
"features": ["somefeat"],
/* 是否属于标准库单元,
是未稳定的 build-std 功能的一部分。
若未设置,视为 `false`。
*/
"is_std": false,
/* 此单元的依赖项数组。 */
"dependencies": [
{
/* 在 "units" 数组中依赖项的索引。 */
"index": 1,
/* 此依赖项的引用名称。 */
"extern_crate_name": "unicode_xid",
/* 此依赖项是否为 "public",
是未稳定的 public-dependency 功能的一部分。
若未设置,未启用 public-dependency 功能。
*/
"public": false,
/* 此依赖项是否注入到 prelude,
当前由 build-std 功能使用。
若未设置,视为 `false`。
*/
"noprelude": false
}
]
},
// ...
],
/* "units" 数组中 "roots" 的索引数组,
即依赖图的根。
*/
"roots": [0],
}
Profile 的 rustflags 选项
- 原始 Issue:rust-lang/cargo#7878
- 跟踪 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", "..." ]
Profile 的 hint-mostly-unused 选项
- 跟踪 Issue:#15644
该特性在 [profile] 配置段中新增了一个选项,用于启用 rustc 的 hint-mostly-unused 选项。它主要针对特定依赖启用,例如:
[profile.dev.package.huge-mostly-unused-dependency]
hint-mostly-unused = true
要启用该特性,需传入 -Zprofile-hint-mostly-unused。不过由于这个选项只是一个提示,如果没有传 -Zprofile-hint-mostly-unused,Cargo 只会发出警告并忽略该 profile 选项。引入该特性之前的 Cargo 版本会给出 "unused manifest key" 警告,但不会报错。这样即使在 crate 的 Cargo.toml 中使用了该提示,构建它时也不强制要求使用更新版本的 Cargo。
crate 也可以通过 [hints] 配置段为依赖它的 crate 自动提供该提示(旧版本 Cargo 同样会忽略它):
[hints]
mostly-unused = true
这会让该 crate 默认启用 hint-mostly-unused,除非通过 profile 覆盖——profile 的优先级更高,且只能在顶层被构建的 crate 中指定。
rustdoc-map
- 跟踪 Issue:#8296
该特性增加了一些传递给 rustdoc 的配置项:当某个依赖没有附带文档时,rustdoc 可以为它生成指向其他托管地址的链接。首先,在 .cargo/config 中加入:
[doc.extern-map.registries]
crates-io = "https://docs.rs/"
然后在构建文档时使用以下 flag,依赖的链接就会指向 docs.rs:
cargo +nightly doc --no-deps -Zrustdoc-map
registries 表用于把 registry 名称映射到要链接的 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 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 目标构建,例如它是作为运行在宿主(或由命令行指定目标)的主程序的插件使用。
artifact-dependencies
Artifact dependencies 允许 Cargo 包依赖 bin、cdylib 和 staticlib crate,并在编译时使用这些 crate 构建出的工件。
运行 cargo 并附加 -Z bindeps 参数以启用此功能。
artifact-dependencies: 依赖声明
Artifact-dependencies 在 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 依赖会针对 host 目标构建;其他类型的依赖则针对声明它的包所构建的目标平台构建。
对于 build 依赖,还可以使用特殊值
"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 环境变量一样,依赖名会转换为大写,横线替换为下划线。如果在 manifest 中重命名了依赖,
<DEP>对应的是你指定的名称,而不是原始的包名。 -
CARGO_<ARTIFACT-TYPE>_FILE_<DEP>_<NAME>—— 该 artifact 的完整路径。<ARTIFACT-TYPE>是为该依赖指定的artifact(按上述规则转为大写),<DEP>是依赖的名称(按上述规则转换),<NAME>是该依赖提供的 artifact 名称。注意,
<NAME>会原样使用提供 artifact 的 crate 中指定的name,未指定时则使用 crate 名称,不做任何修改;比如它可能是小写,或者包含连字符。为方便起见,如果 artifact 名称与原始包名一致,Cargo 还会额外提供一个省略了
_<NAME>后缀的同名变量。 例如,如果cmakecrate 提供了一个名为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 产物
消费方包中的 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
- 跟踪 Issue:11222
配置文件中的 publish.timeout 键可用于控制 cargo publish 在将包发布到 registry 后,等待其在本地索引中可用时的超时时长。
超时设置为 0 可阻止任何检查执行。当前默认值为 60 秒。
需设置 -Zpublish-timeout 命令行选项。
# config.toml
[publish]
timeout = 300 # 单位:秒
asymmetric-token
-Z asymmetric-token 标志会启用 cargo:paseto 凭证提供程序,让 Cargo 在向 registry 认证时无需在网络上传输密钥。
在 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,其值由 registry 指定。该字符串会包含在非对称令牌中,不需要保密。它只用于极少数场景,比如“用加密方式证明中央 CA 服务器授权了这次操作”。Cargo 要求它的值是除空白字符外的可打印 ASCII,需要非 ASCII 数据的 registry 应将其做 base64 编码。
这两个字段都可以通过 cargo login --registry=name --private-key --private-key-subject="subject" 设置,命令会提示你输入密钥值。
每个 registry 最多只能设置 private-key 和 token 中的一个。
所有 PASETO 都会包含 iat 字段,即 ISO 8601 格式的当前时间。在适用的情况下,Cargo 还会包含以下字段:
sub:一个可选的非机密字符串,由 registry 指定,预期会随每个请求一起声明。其值取自config.toml文件中的private-key-subject。mutation(如果存在)表示该请求是一个修改操作(不存在则为只读操作),必须是publish、yank或unyank之一。name该请求相关的 crate 名称。vers该请求相关的 crate 版本字符串。cksumcrate 内容的 SHA256 哈希,为 64 位小写十六进制字符串,仅当mutation为publish时必须提供。
challenge本次会话中从服务器 401/403 响应收到的 challenge 字符串。颁发 challenge 的 registry 必须记录哪些 challenge 已颁发/已使用,并且在同一有效期内绝不能接受同一个 challenge 多次(这样就不必记录所有颁发过的 challenge)。
"footer"(属于签名的一部分)是一个 UTF-8 编码的 JSON 字符串,包含:
urlcargo 获取 config.json 文件时使用的符合 RFC 3986 的 URL,- 如果是 HTTP 索引的 registry,则为所有索引查询的基准 URL。
- 如果是 GIT 索引的 registry,则为 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
- 跟踪 Issue: #9357
cargo rustc --print=VAL 将 --print 标志转发给 rustc,以提取 rustc 的相关信息。此命令会以对应的 --print 标志运行 rustc,然后立即退出而不执行编译。将其暴露为 cargo 标志,使得 cargo 可以根据当前配置注入正确的 target 和 RUSTFLAGS。
主要使用场景是运行 cargo rustc --print=cfg,以获取适用于相应 target 的配置值,并考虑其他 RUSTFLAGS 的影响。
不同的二进制名称
different-binary-name 功能允许设置二进制的文件名,而无需遵守 crate 名称的限制。例如,crate 名称只能使用 alphanumeric 字符、- 或 _,且不能为空。
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 在当前 workspace 的 crate 中搜索函数调用,并将这些调用点作为文档示例收录。用法如下:
cargo doc -Z unstable-options -Z rustdoc-scrape-examples
默认情况下,Cargo 会从被文档化的包的 example 目标中抓取示例。你可以通过 doc-scrape-examples 选项单独开启或关闭某个目标的抓取,例如:
# 从库中开启示例抓取
[lib]
doc-scrape-examples = true
# 从某个 example 目标关闭示例抓取
[[example]]
name = "my-example"
doc-scrape-examples = false
关于测试: 目前在 test 目标上开启 doc-scrape-examples 不会产生任何效果,从测试中抓取示例的功能仍在开发中。
关于 dev-dependencies: 生成库文档通常不需要 crate 的 dev-dependencies,但 example 目标是需要它们的。为了向后兼容,-Z rustdoc-scrape-examples 不会让 cargo doc 额外引入 dev-deps 依赖。因此在满足以下全部条件时,example 目标不会被抓取示例:
- 所有被文档化的目标都不需要 dev-deps,且
- 至少有一个被文档化的 crate 存在 dev-deps,且
- 所有
[[example]]目标的doc-scrape-examples均未设置或为 false。
如果你想从 example 目标中抓取示例,就需要避免满足上述条件之一。例如,你可以为某个 example 目标设置 doc-scrape-examples = true,这等于告诉 Cargo:你可以接受 cargo doc 时构建 dev-deps。
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 所使用的 codegen 后端。
示例:
[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
- 跟踪 Issue:#11813
启用 'gitoxide' 不稳定特性后,所有或指定的 git 操作将由 gitoxide crate 而非 git2 来执行。
-Zgitoxide 会启用当前已实现的全部功能,也可以通过 -Zgitoxide=operation[,operationN] 语法单独选择用 gitoxide 执行哪些 git 操作。
可用操作如下:
fetch- 所有拉取操作都由gitoxide完成,包括 git 依赖和 crates 索引。checkout(计划中) - 检出工作区,支持过滤器和子模块。
git
- 跟踪 Issue:#13285
启用 'git' 不稳定特性后,gitoxide 和 git2 都会对 crates 索引和 git 依赖执行浅拉取(shallow fetch)。
-Zgit 会启用当前已实现的全部功能,也可以通过 -Zgit=operation[,operationN] 语法单独选择何时执行浅拉取。
可用操作如下:
shallow-index- 对索引执行浅克隆。shallow-deps- 对 git 依赖执行浅克隆。
关于浅克隆的细节
- 要启用浅克隆,拉取 git 依赖时添加
-Zgit=shallow-deps,拉取 registry 索引时添加-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 仍然足够智能,能够在不解除浅获取限制的情况下完成浅获取。
script
- 追踪议题:#12207
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);
}
Single-file packages
除了现有的多文件包(由 Cargo.toml 文件和其他 .rs
文件组成)外,我们正在引入单文件包的概念,这种包可以包含嵌入式清单。
单文件 .rs 包与其他普通 .rs 文件之间没有强制性的区别要求。
单文件包可以通过 --manifest-path 进行指定,例如
cargo test --manifest-path foo.rs。与 Cargo.toml 不同,这类文件无法被自动发现。
单文件包可以包含嵌入式清单。嵌入式清单以 TOML 格式存储在 Rust 的“前言”中,这是一种位于文件顶部的 Markdown 代码栅栏,其信息字符串以 cargo 开头。
自动推断/设置默认值的 manifest 字段:
package.name = <slugified file stem>package.edition = <current>,这样就不必总是添加内嵌 manifest,代价是 rust 升级可能导致脚本失效edition未指定时会发出警告,提醒用户注意
不允许使用的 manifest 字段:
[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 中。将来支持 workspace 后,用户就能拥有持久的 lockfile。
Manifest 命令
你可以把 manifest 直接传给 cargo 命令而不用子命令,比如 foo/Cargo.toml,或单文件包如 foo.rs。这主要是为写入 #! 行而设计的。
cargo <subcommand> 的解析优先级为:
- 内置命令,或单文件包
- 别名
- 外部子命令
如果参数满足以下任一条件,就会被识别为 manifest 命令:
- 包含路径分隔符
- 扩展名为
.rs - 文件名为
Cargo.toml
cargo run --manifest-path <path> 与 cargo <path> 的区别:
cargo <path>使用<path>处的配置而非当前目录的配置,行为更接近cargo install --path <path>cargo <path>的输出详细程度低于默认水平,传-v可获得正常输出。
运行带有嵌入式 manifest 的包时,arg0 会是脚本的路径。要获取可执行文件的路径,请参见 current_exe。
文档更新
Profile 的 trim-paths 选项
- Tracking Issue: rust-lang/cargo#12137
- Tracking Rustc Issue: rust-lang/rust#111540
这个功能新增了一个 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 配置使用 none,release 配置使用 object。
你可以在 Cargo.toml 中手动指定该选项来覆盖默认值:
[profile.dev]
trim-paths = "all"
[profile.release]
trim-paths = ["object", "diagnostics"]
release 配置的默认设置(object)只清理输出可执行文件或库文件中的路径。
它总是会影响宏产生的路径(例如 panic 消息);对于调试信息,仅当这些信息与二进制文件一同嵌入时才会被清理(这是 Linux 和 windows-gnu 等 ELF 二进制平台的行为),如果它们位于单独的文件中则不会修改(这是 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。 - 依赖包的路径将替换为
[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 为 build script 设置的环境变量」的新增条目
CARGO_TRIM_PATHS_SCOPE— profile 中trim-paths选项的值。false、"none"和空数组会被转换为none;true和"all"变为all; 非空数组中的值会合并为逗号分隔的列表。 如果 build script 引入了指向构建产物的绝对路径(比如调用编译器时), 用户可以要求在不同类型的产物中清理这些路径。 常见的需要清理的路径包括OUT_DIR、CARGO_MANIFEST_DIR和CARGO_MANIFEST_PATH, 以及 build script 引入的其他路径,比如 include 目录。CARGO_TRIM_PATHS_REMAP— Cargo 传给编译器的<from>=<to>路径重映射对, 以平台的路径分隔符连接。 仅在trim-pathsprofile 激活时才会设置。 Build script 可以把这些映射转发给 C/C++ 编译器和其他工具, 例如通过cc的-ffile-prefix-map选项, 使路径清理与构建的其他部分保持一致。
gc
- Tracking Issue: #12633
-Zgc 标志用于启用与清理 Cargo 主目录下全局缓存相关的部分功能。
自动 gc 配置
-Zgc 标志会让 Cargo 读取与垃圾回收相关的额外配置选项。
可用设置如下:
# config.toml 示例文件。
# 用于定义全局缓存清理具体设置的子表。
[cache.global-clean]
# 超过该时长的源码缓存文件将被删除。
max-src-age = "1 month"
# 超过该时长的压缩 crate 缓存文件将被删除。
max-crate-age = "3 months"
# 超过该时长的索引缓存将被删除。
max-index-age = "3 months"
# 超过该时长的 git checkout 将从 checkout 缓存中删除。
max-git-co-age = "1 month"
# 超过该时长的 git clone 将从 git 缓存中删除。
max-git-db-age = "3 months"
注意,cache.auto-clean-frequency 选项已在 Rust 1.88 中稳定。
使用 cargo clean 手动垃圾回收
可以通过 cargo clean gc -Zgc 命令手动删除缓存。传入以下任一缓存选项即可执行删除:
--max-src-age=DURATION— 删除超过指定时长未使用的源码缓存文件。--max-crate-age=DURATION— 删除超过指定时长未使用的 crate 缓存文件。--max-index-age=DURATION— 删除超过指定时长未使用的 registry 索引(包括对应的.crate和src文件)。--max-git-co-age=DURATION— 删除超过指定时长未使用的 git 依赖 checkout。--max-git-db-age=DURATION— 删除超过指定时长未使用的 git 依赖 clone。--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 suffix”,其中 suffix 可以是 B、kB、MB、GB、kiB、MiB 或 GiB,N 为整数或浮点数。若未指定后缀,则数值表示字节数。
cargo clean gc -Zgc
cargo clean gc -Zgc --max-download-age=1week
cargo clean gc -Zgc --max-git-size=0 --max-download-size=100MB
open-namespaces
- 跟踪 Issue:#13576
允许多个包共享同一个 API 命名空间
启用方式如下:
cargo-features = ["open-namespaces"]
[package]
# ...
panic-immediate-abort
- 跟踪 Issue:#16042
- 上游跟踪 Issue:rust-lang/rust#147286
扩展 panic 配置项,以支持 immediate-abort panic 策略。启用方式如下:
# Cargo.toml
cargo-features = ["panic-immediate-abort"]
[package]
# ...
[profile.release]
panic = "immediate-abort"
若要在 Cargo 配置文件的 profile 中设置此项,需使用 -Z panic-immediate-abort 命令行标志,或通过 [unstable] 表启用。示例如下:
# .cargo/config.toml
[unstable]
panic-immediate-abort = true
[profile.release]
panic = "immediate-abort"
fine-grain-locking
- 跟踪 Issue:#4282
使用细粒度锁替代对整个构建缓存加锁。
注意:细粒度锁基于目录重组,因此隐式启用 build-dir-new-layout。
[lints.cargo]
- 跟踪 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
路径基准(Path Bases)
- Tracking Issue: #14355
path 依赖可以通过 base 键指定一个基准,其值为 配置 中 [path-bases] 表里的某个路径基准名称,或某个 内置路径基准 的名称。Cargo 会把该路径基准的值拼接到 path 值前面(必要时加上路径分隔符),得到依赖的实际查找位置。
例如,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/foo 的 path 依赖 foo。
路径基准可以是绝对路径,也可以是相对路径。相对路径相对于声明该基准的配置文件所在的父目录。
路径基准的名称只能包含字母数字字符、- 或 _,必须以字母开头,且不能为空。
如果依赖中使用的路径基准名称既不在配置中,也不是内置基准,Cargo 会报错。
内置路径基准
Cargo 提供了一些隐式的 path base,无需在 [path-bases] 表中显式声明即可使用。
workspace- 如果项目本身是一个 workspace 或其成员,则该 path base 被定义为 workspace 根目录下Cargo.toml的父目录。
如果配置中也声明了与内置 path base 同名的名称,Cargo 会优先使用配置中的值。这样 Cargo 在新增内置 path base 时就不会产生兼容性问题(现有的同名定义会覆盖内置名称)。
native-completions
该特性将手写的补全脚本迁移到 Rust 原生实现,让我们能更方便地添加、扩展和测试新的补全功能。在 nightly 通道上该特性默认启用,无需额外的 -Z 选项。
特别欢迎以下方面的反馈:
- 本应转义或加引号但处理不正确的参数
- 信息不准确之处
- 命令行解析中的 bug
- 未报告补全候选的参数
- 已知问题造成困扰的情况
反馈可以分为以下几类:
- 补全候选的报告内容
- 已知问题:#14520、
A-completions - 提交 issue 或讨论相关行为
- 已知问题:#14520、
- Shell 集成、命令行解析和补全过滤
- 已知问题:clap#3166、clap 的
A-completions - 提交 issue 或讨论相关行为
- 已知问题:clap#3166、clap 的
如何使用 native-completions 功能:
-
bash: 在
~/.local/share/bash-completion/completions/cargo文件中添加source <(CARGO_COMPLETE=bash cargo +nightly)。 -
zsh: 在你的
.zshrc文件中添加source <(CARGO_COMPLETE=zsh cargo +nightly)。 -
fish: 在
$XDG_CONFIG_HOME/fish/completions/cargo.fish文件中添加source (CARGO_COMPLETE=fish cargo +nightly | psub)。 -
elvish: 在
$XDG_CONFIG_HOME/elvish/rc.elv文件中添加eval (E:CARGO_COMPLETE=elvish cargo +nightly | slurp)。 -
powershell: 在
$PROFILE文件中添加CARGO_COMPLETE=powershell cargo +nightly | Invoke-Expression。
feature 统一
启用 -Z feature-unification 后,可以通过 resolver.feature-unification
配置项来控制工作区内 feature 的统一方式。
若未启用 -Z feature-unification 不稳定标志,
则 resolver.feature-unification 配置将被忽略。
resolver.feature-unification
- 类型:字符串
- 默认值:
"selected" - 环境变量:
CARGO_RESOLVER_FEATURE_UNIFICATION
指定哪些包参与feature 统一。
selected:合并当前构建中指定所有包的依赖 feature。workspace:合并所有工作区成员的依赖 feature, 无论当前构建指定了哪些包。package:按包独立处理依赖 feature, 当不同包激活了不同的 feature 集合时,允许依赖存在重复构建。
lockfile-publish-time
使用 cargo generate-lockfile -Zunstable-options --publish-time <time> 时,包解析将不再考虑发布时间晚于指定时间的任何包。
Package message format
cargo package 中的 --message-format 标志用于控制输出消息的格式。目前它只能与 --list 标志配合使用,影响文件列表的输出格式。需要 -Zunstable-options。详见 cargo package --message-format。
rustdoc depinfo
-Z rustdoc-depinfo 标志利用 rustdoc 的 dep-info 文件来判断是否需要重新生成文档。它还可以与 -Z checksum-freshness 结合使用,通过检测校验和变化而非文件 mtime 来判断。
no-embed-metadata
Rust 的默认行为是把 crate 元数据嵌入到 rlib 和 dylib 产物中。由于 Cargo 还会为这些中间产物传递 --emit=metadata 以启用流水线编译,这导致大量元数据在磁盘上重复存储,浪费 target 目录的磁盘空间。
该特性会让 Cargo 向编译器传递 -Zembed-metadata=no 标志,指示其不要在 rlib 和 dylib 产物中嵌入元数据。这种情况下,元数据只会存储在 .rmeta 文件中。
cargo +nightly -Zno-embed-metadata build
unstable-editions
cargo-features 列表中的 unstable-editions 值允许 Cargo.toml 清单指定尚未稳定的 edition。
cargo-features = ["unstable-editions"]
[package]
name = "my-package"
edition = "future"
当新的 edition 发布时,在该 edition 稳定之前都需要启用 unstable-editions 这个 feature。
特殊的 “future” edition 用于收纳仍在开发中的新特性,它永远是unstable的。“future” edition 本身不会带来任何新行为,其中的每项改动都需要显式开启,比如添加 #![feature(...)] 属性。
fix-edition
-Zfix-edition 是一个永远unstable的标志,用于辅助测试 edition 迁移,尤其是在 crater 中使用。它只对 cargo fix 子命令有效,有两种形式:
-Zfix-edition=start=$INITIAL—— 检查当前 edition 是否等于给定数字。如果不等,则以成功状态退出(因为我们想忽略更旧的 edition);如果相等,则执行相当于cargo check的操作。它用于 crater 的 “start” 工具链,为 “before” 工具链建立基线。-Zfix-edition=end=$INITIAL,$NEXT—— 检查当前 edition 是否等于给定的$INITIAL值。如果不等,则以成功状态退出;如果相等,则执行向$NEXT`所指定 edition 的迁移。之后它会修改Cargo.toml,添加相应的cargo-features = ["unstable-edition"],更新edition字段,并执行相当于cargo check的操作来验证迁移在新 edition 上能正常工作。
例如:
cargo +nightly fix -Zfix-edition=end=2024,future
section-timings
该特性用于扩展 cargo build --timings 的输出。它指示 rustc 生成各编译阶段的耗时数据,这些数据随后会显示在耗时的 HTML 或 JSON 输出中。
cargo +nightly -Zsection-timings build --timings
构建分析
- 原始 Issue:rust-lang/rust-project-goals#332
- 跟踪 Issue:#15844
-Zbuild-analysis 特性会将详细的构建指标记录并持久化到磁盘上,并提供用于查询历史构建的新命令。
启用后,Cargo 会以 JSONL 格式将构建日志写入 $CARGO_HOME/log/ 目录。每次调用 cargo 都会生成一个以唯一会话 ID 命名的日志文件。这些日志包含耗时信息、重新构建原因及其他构建元数据,可通过 cargo report 子命令进行分析。
要启用构建分析,请在 Cargo 配置中添加以下内容:
# 示例 config.toml 文件。
[unstable]
build-analysis = true
# 启用构建指标收集
[build.analysis]
enabled = true
在稳定版工具链上设置此项仅会发出未知配置警告,因此在 Cargo 配置中保持启用是安全的。
cargo report 命令
在 -Zbuild-analysis 下可用以下命令:
cargo report sessions— 列出之前的构建会话。使用此命令查找会话 ID 以供其他报告命令使用。cargo report timings— 从之前的会话生成 HTML 耗时报告,类似于cargo build --timings但无需重新构建。cargo report rebuilds— 报告 Crate 被重新构建的原因,有助于诊断意外的重新编译。
build-dir-new-layout
- 跟踪 Issue:#15010
启用新的 build-dir 文件系统布局。此项布局变更为改进缓存和锁定机制扫清了障碍。
compile-time-deps
这是一个永久不稳定的标志,只构建 proc-macro 和构建脚本(及其必需的依赖),并运行构建脚本。
它供 rust-analyzer 等工具使用,永远不会被稳定化。
示例:
cargo +nightly build --compile-time-deps -Z unstable-options
cargo +nightly check --compile-time-deps --all-targets -Z unstable-options
rustc-unicode
- Tracking Issue: rust#148607
让 Cargo 的错误信息启用 rustc 的 unicode 错误格式。
rustdoc mergeable info
- Original Pull Request: #16309
- Tracking issue: #16306
- Tracking rustc issue: rust-lang/rust#130676
-Z rustdoc-mergeable-info 利用 rustdoc 的 mergeable crate 信息,让 cargo doc 能够合并来自不同输出目录的跨 crate 信息(如搜索索引、源码文件索引等),并并行运行 rustdoc。
json-target-spec
- Tracking Issue: rust-lang/rust#151528
-Z json-target-spec 命令行标志允许使用自定义 target spec JSON 文件作为构建目标。
cargo +nightly build --target my-target.json -Z json-target-spec
通常需要与 build-std 配合使用。
hint-msrv
- Tracking Issue: rust-lang/rust#157574
-Z hint-msrv 命令行标志让 Cargo 把 package.rust-version 传给 rustc,从而影响 rustc 发出哪些 lint。
你可以在全局 ~/.cargo/config.toml 中设置该选项,nightly 版 Cargo 会自动启用它,而 stable 版 Cargo 则会静默忽略这个不稳定选项:
[unstable]
hint-msrv = true
min-publish-age
-Zmin-publish-age 特性允许用户为依赖版本指定一个最短发布时长。设置后,Cargo 不会使用发布时间距当前不足该时长的 registry crate 版本,同时提供覆盖机制,以应对紧急安全修复等特殊情况。
例如,在 <repo>/.cargo/config.toml 中:
[registry]
global-min-publish-age = "14 days"
新增的配置项
Cargo 的配置格式将新增以下内容:
[resolver]
incompatible-publish-age = "deny" # 指定 resolver 对此类情况的处理方式
[registries.<name>]
min-publish-age = "..." # 针对该 registry 覆盖 `registry.global-min-publish-age`
[registry]
min-publish-age = "..." # 针对 crates.io 覆盖 `registry.global-min-publish-age`
global-min-publish-age = "0" # 该 registry 来源的包所允许的最短发布时长
resolver.incompatible-publish-age
- 类型:字符串
- 默认值:
"deny" - 环境变量:
CARGO_RESOLVER_INCOMPATIBLE_PUBLISH_AGE
在解析依赖版本时,指定对 pubtime(如存在)不满足 registry.min-publish-age 要求的版本的处理方式。可选值包括:
allow:将不满足发布时长要求的版本与其他版本同等对待deny:忽略不满足要求的版本,除非它们已存在于 lock file 中
registries.<name>.min-publish-age
- 类型:字符串
- 默认值:无
- 环境变量:
CARGO_REGISTRIES_<name>_MIN_PUBLISH_AGE
指定该 registry 来源的包,其版本自 pubtime 起需经过的最短时长,用于配合 resolver.incompatible-publish-age 进行判断。未设置时将使用 registry.global-min-publish-age。
如果该 registry 不支持此功能,则该配置会被忽略。
支持以下取值:
- 一个整数后跟“seconds”、“minutes”、“hours”、“days”、“weeks”或“months”
"0"允许所有包
registry.min-publish-age
- 类型:String
- 默认值:无
- 环境变量:
CARGO_REGISTRY_MIN_PUBLISH_AGE
指定自某个版本的 pubtime 以来,来自 crates.io 的包可以被 resolver.incompatible-publish-age 考虑的最小时间间隔。若未设置,则将使用 registry.global-min-publish-age。
支持以下值:
- 一个整数后跟“seconds”、“minutes”、“hours”、“days”、“weeks”或“months”
"0"允许所有包
通常使用 "0"、"N days" 或 "N weeks"。
registry.global-min-publish-age
- 类型:String
- 默认值:
"0" - 环境变量:
CARGO_REGISTRY_GLOBAL_MIN_PUBLISH_AGE
指定自某个版本的 pubtime 以来,包可以被 resolver.incompatible-publish-age 考虑的全局最小时间间隔。如果未通过 registries.<name>.min-publish-age 为特定注册表设置 min-publish-age,Cargo 将使用此全局最小发布时间。
支持以下值:
- 一个整数后跟“seconds”、“minutes”、“hours”、“days”、“weeks”或“months”
"0"允许所有包
添加到 Resolver
以下内容将作为“Yanked versions”的兄弟章节,添加到解析器章节中:
“Pubtime 不兼容的版本”
发布时间比配置的
min-publish-age更新的版本被视为 pubtime 不兼容。当resolver.incompatible-publish-age设置为deny时,解析器将忽略这些版本,除非它们已存在于Cargo.lock文件中。将配置设置为allow会禁用此检查;若与cargo update --precise结合使用,Cargo 将拉取特定版本及其传递依赖。
已稳定并移除的特性
Compile progress
compile-progress 特性已在 1.30 版本中稳定,进度条现在默认开启。关于如何控制该特性,请参阅 term.progress。
Edition
在 Cargo.toml 中指定 edition 的功能已在 1.31 版本中稳定。详情请参阅edition 字段。
rename-dependency
在 Cargo.toml 中重命名依赖的功能已在 1.31 版本中稳定。详情请参阅重命名依赖。
Alternate Registries
对备用 registry 的支持已在 1.34 版本中稳定。详情请参阅Registries 章节。
Offline Mode
offline 特性已在 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
Profile overrides 已在 1.41 版本中稳定。有关使用 override 的更多信息,请参阅 Profile Overrides。
Config Profiles
在 Cargo 配置文件和环境变量中指定 profile 的功能已在 1.43 版本中稳定。有关在配置文件中指定 profile 的更多信息,请参阅配置中的 [profile] 表。
crate-versions
-Z crate-versions 标志已在 1.47 版本中稳定。crate 版本现在会自动显示在 cargo doc 生成的文档侧边栏中。
Features
-Z features 标志已在 1.51 版本中稳定。有关使用新 feature 解析器的更多信息,请参阅 feature resolver version 2。
package-features
-Z package-features 标志已在 1.51 版本中稳定。有关使用 features 命令行选项的更多信息,请参阅 resolver version 2 命令行标志。
Resolver
Cargo.toml 中的 resolver 特性已在 1.51 版本中稳定。有关指定 resolver 的更多信息,请参阅 resolver versions。
extra-link-arg
在 build script 中指定额外链接器参数的 extra-link-arg 特性已在 1.56 版本中稳定。有关指定额外链接器参数的更多信息,请参阅 build script 文档。
configurable-env
configurable-env 功能用于在 Cargo 配置中指定环境变量,已在 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 edition 已在 1.56 版本中稳定化。关于设置 edition 的更多信息,请参阅edition 字段。关于迁移现有项目,请参阅cargo fix --edition 和Edition Guide。
自定义命名 profile
自定义命名 profile 已在 1.57 版本中稳定化。更多信息请参阅profile 章节。
Profile 的 strip 选项
Profile 的 strip 选项已在 1.59 版本中稳定化。更多信息请参阅profile 章节。
未来不兼容报告
生成未来不兼容报告的支持已在 1.59 版本中稳定化。更多信息请参阅未来不兼容报告章节。
命名空间特性
命名空间特性已在 1.60 版本中稳定化。更多信息请参阅特性章节。
弱依赖特性
弱依赖特性已在 1.60 版本中稳定化。更多信息请参阅特性章节。
timings
-Ztimings 选项已在 1.60 版本中稳定为 --timings。
timings 输出格式选项
(例如 --timings=html 以及机器可读的 --timings=json 输出)
已在 1.94.0-nightly 中移除。
config-cli
--config 命令行选项已在 1.63 版本中稳定。
详见 config 文档。
multitarget
-Z multitarget 选项已在 1.64 版本中稳定。
关于如何设置默认的 target 平台三元组,
请参阅 build.target。
crate-type
cargo rustc 的 --crate-type 标志已在 1.64 版本中稳定。
详见 cargo rustc 文档。
Workspace Inheritance
Workspace Inheritance 已在 1.64 版本中稳定。 详见 workspace.package、 workspace.dependencies 和 inheriting-a-dependency-from-a-workspace。
terminal-width
-Z terminal-width 选项已在 1.68 版本中稳定。
只要 Cargo 能够自动检测终端宽度,就会在从终端运行时把宽度传给编译器。
sparse-registry
Sparse registry 支持已在 1.68 版本中稳定。 详见 Registry Protocols。
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]
[lints](通过 -Zlints 启用)已在 1.74 版本中稳定。
credential-process
-Z credential-process 特性已在 1.74 版本中稳定。
详情请参阅 Registry Authentication 文档。
registry-auth
-Z registry-auth 特性已在 1.74 版本中稳定,但需要额外配置 credential-provider。
详情请参阅 Registry Authentication 文档。
check-cfg
-Z check-cfg 特性已在 1.80 版本中稳定,并成为默认行为。
关于如何指定自定义 cfg,请参阅 build script 文档。
Edition 2024
2024 edition 已在 1.85 版本中稳定。关于如何设置 edition,请参阅 edition 字段。关于如何迁移现有项目,请参阅 cargo fix --edition 和 The Edition Guide。
自动垃圾回收
自动删除旧文件的支持已在 Rust 1.88 中稳定。更多信息请参阅 配置章节。
doctest-xcompile
从 Rust 1.89 开始,doctest 交叉编译已被无条件启用。cargo test 运行 doctest 时现在会遵循 --target 标志。
package-workspace
多 package 发布功能已在 Rust 1.90.0 中稳定。
build-dir
build.build-dir 的支持已在 1.91 版本中稳定。关于如何更改 build-dir,请参阅 配置文档。
Build-plan
build 命令的 --build-plan 参数已在 1.93.0-nightly 中移除。移除原因见 https://github.com/rust-lang/cargo/issues/7614。
config-include
通过 include 配置项包含额外配置文件的功能已在 1.93.0 中稳定化。详见 include 配置文档。
pubtime
pubtime 索引字段已在 Rust 1.94.0 中稳定化。
lockfile-path
resolver.lockfile-path 配置字段的支持已在 Rust 1.97.0 中稳定化。
warnings
build.warnings 配置字段已在 Rust 1.97 中稳定化。