Skip to content

Commit 9dc6761

Browse files
committed
Add article 'Cargo changes how arrays in config are merged'
1 parent b14b6f1 commit 9dc6761

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
layout: post
3+
title: "Cargo changes how arrays in config are merged"
4+
author: Arlo Siemsen
5+
team: the Cargo team <https://www.rust-lang.org/governance/teams/dev-tools#cargo>
6+
---
7+
8+
Cargo will be changing the order of merged configuration arrays, and we are looking for people to help test this change and provide feedback.
9+
10+
When an array in Cargo's configuration is defined in multiple places, the elements are merged together. The order that the elements were merged was inconsistent with how other configuration types were merged together, and was not working as expected.
11+
12+
The new merging order will match the precedence order of non-array [configuration], with higher-precedence configuration being placed later in the array.
13+
14+
In the case of `build.rustflags`, this resolves the confusing situation where higher precedence flags (in a project's `config.toml`) are overridden with lower precedence flags (in the global `$CARGO_HOME`, for example).
15+
16+
This may result in behavior changes if a project depends on the existing merging order. If you have an environment that involves merging configuration arrays, please consider testing your project with nightly to ensure it will continue to work once this change stabilizes. If you encounter a problem, please file an [issue].
17+
18+
The change is included in Cargo starting with `nightly-2023-08-24` toolchain.
19+
20+
## Merging Order
21+
22+
The previous merging order was unspecified, but in practice it was the following, with earlier entries appearing first in the array:
23+
* `config.toml` in the current directory
24+
* `config.toml` in a parent directory
25+
* `config.toml` in `$CARGO_HOME`
26+
* command-line (`--config`)
27+
* environment variable (`CARGO_*`)
28+
29+
The new merging order is:
30+
* `config.toml` in `$CARGO_HOME`
31+
* `config.toml` in a parent directory
32+
* `config.toml` in the current directory
33+
* environment variable (`CARGO_*`)
34+
* command-line (`--config`)
35+
36+
The implementation is in [cargo#12515].
37+
38+
## Impacted configuration settings
39+
40+
The following configuration settings have arrays of strings that will be impacted by this change:
41+
42+
* [`alias`] entries
43+
* [`build.rustflags`]
44+
* [`build.rustdocflags`]
45+
* [`target.<triple>.rustflags`]
46+
* [`net.ssh.known-hosts`]
47+
48+
[`alias`]: https://doc.rust-lang.org/nightly/cargo/reference/config.html#alias
49+
[`build.rustflags`]: https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildrustflags
50+
[`build.rustdocflags`]: https://doc.rust-lang.org/nightly/cargo/reference/config.html#buildrustdocflags
51+
[`target.<triple>.rustflags`]: https://doc.rust-lang.org/nightly/cargo/reference/config.html#targettriplerustflags
52+
[`net.ssh.known-hosts`]: https://doc.rust-lang.org/nightly/cargo/reference/config.html#netsshknown-hosts
53+
54+
## Example
55+
56+
The following example shows how this change may impact you and why we are making this change.
57+
58+
With the following in your Cargo home directory (usually `~/.cargo/config.toml`):
59+
60+
```toml
61+
[build]
62+
rustflags = ["-C", "target-cpu=x86-64-v2"]
63+
```
64+
65+
and then inside a project directory there is a `.cargo/config.toml` configuration file with:
66+
67+
```toml
68+
[build]
69+
rustflags = ["-C", "target-cpu=x86-64-v3"]
70+
```
71+
72+
when you run `cargo build` within that project, cargo would previously merge these so that it passes `-C target-cpu=x86-64-v3 -C target-cpu=x86-64-v2` to `rustc`. Because `rustc` ignores options earlier on the command-line and only honors the last one, the result would end up using `x86-64-v2`. This would effectively cause the merged config settings in the current directory to be ignored.
73+
74+
This was not the intended behavior, since config merging should always start with the lowest precedence (things in the Cargo home directory) and have more-specific config locations override those.
75+
76+
[cargo#12515]: https://github.com/rust-lang/cargo/pull/12515
77+
[configuration]: https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure
78+
[issue]: https://github.com/rust-lang/cargo/issues/new/choose

0 commit comments

Comments
 (0)