Cargo 更改了配置中数组的合并方式

2023 年 8 月 24 日 · Arlo Siemsen 代表 Cargo 团队 发布

Cargo 将会改变已合并配置数组的顺序,我们正在寻找人员帮助测试这一变化并提供反馈。

当 Cargo 配置中的一个数组在多个地方定义时,其元素会被合并。之前元素的合并顺序与其他配置类型的合并方式不一致,也未按预期工作。

新的合并顺序将与非数组配置的优先级顺序一致,优先级更高的配置会放在数组中靠后的位置。

对于 build.rustflags,这解决了令人困惑的情况:项目中 config.toml 中优先级更高的标志会被全局 $CARGO_HOME 中优先级较低的标志覆盖。

如果项目依赖现有的合并顺序,这可能会导致行为改变。如果您使用的环境涉及合并配置数组,请考虑使用 nightly 版本测试您的项目,以确保此更改稳定后仍能正常工作。如果您遇到问题,请提交一个议题

此更改已包含在从 nightly-2023-08-24 工具链开始的 Cargo 版本中。

合并顺序

之前的合并顺序未指定,但在实践中是以下顺序,较早的条目出现在数组中靠前的位置

  • 当前目录中的 config.toml
  • 父目录中的 config.toml
  • $CARGO_HOME 中的 config.toml
  • 命令行 (--config)
  • 环境变量 (CARGO_*)

新的合并顺序是

  • $CARGO_HOME 中的 config.toml
  • 父目录中的 config.toml
  • 当前目录中的 config.toml
  • 环境变量 (CARGO_*)
  • 命令行 (--config)

实现位于 cargo#12515

受影响的配置设置

以下配置设置的字符串数组将受到此更改的影响

示例

以下示例展示了此更改可能如何影响您以及我们进行此更改的原因。

在您的 Cargo 主目录(通常是 ~/.cargo/config.toml)中包含以下内容

[build]
rustflags = ["-C", "target-cpu=x86-64-v2"]

然后在项目目录内有一个 .cargo/config.toml 配置文件,内容为

[build]
rustflags = ["-C", "target-cpu=x86-64-v3"]

当您在该项目中运行 cargo build 时,Cargo 之前会将这些合并,从而向 rustc 传递 -C target-cpu=x86-64-v3 -C target-cpu=x86-64-v2。由于 rustc 会忽略命令行中较早的选项,只采用最后一个,结果最终会使用 x86-64-v2。这实际上导致当前目录中的合并配置设置被忽略。

这并不是预期的行为,因为配置合并应始终从最低优先级(Cargo 主目录中的内容)开始,并由更具体的配置位置覆盖它们。