Skip to content

Commit cbe6895

Browse files
committed
Fix CARGO_CFG_ vars for configs defined both with and without value
When a rustc cfg is defined both with and without value, the environment variable should provide all the values. Before this change, it ended up being empty. Fixes: #11789
1 parent c61b0f0 commit cbe6895

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

src/cargo/core/compiler/custom_build.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,11 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
231231
for cfg in bcx.target_data.cfg(unit.kind) {
232232
match *cfg {
233233
Cfg::Name(ref n) => {
234-
cfg_map.insert(n.clone(), None);
234+
cfg_map.insert(n.clone(), Vec::new());
235235
}
236236
Cfg::KeyPair(ref k, ref v) => {
237-
if let Some(ref mut values) =
238-
*cfg_map.entry(k.clone()).or_insert_with(|| Some(Vec::new()))
239-
{
240-
values.push(v.clone())
241-
}
237+
let values = cfg_map.entry(k.clone()).or_insert_with(|| Vec::new());
238+
values.push(v.clone());
242239
}
243240
}
244241
}
@@ -249,14 +246,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
249246
continue;
250247
}
251248
let k = format!("CARGO_CFG_{}", super::envify(&k));
252-
match v {
253-
Some(list) => {
254-
cmd.env(&k, list.join(","));
255-
}
256-
None => {
257-
cmd.env(&k, "");
258-
}
259-
}
249+
cmd.env(&k, v.join(","));
260250
}
261251

262252
// Also inform the build script of the rustc compiler context.

tests/testsuite/build_script_env.rs

+60
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,63 @@ fn cfg_paradox() {
239239
.with_stderr_contains("[..]--cfg=bertrand[..]")
240240
.run();
241241
}
242+
243+
/// This test checks how Cargo handles rustc cfgs which are defined both with
244+
/// and without a value. The expected behavior is that the environment variable
245+
/// is going to contain all the values.
246+
///
247+
/// For example, this configuration:
248+
/// ```
249+
/// target_has_atomic
250+
/// target_has_atomic="16"
251+
/// target_has_atomic="32"
252+
/// target_has_atomic="64"
253+
/// target_has_atomic="8"
254+
/// target_has_atomic="ptr"
255+
/// ```
256+
///
257+
/// Should result in the following environment variable:
258+
///
259+
/// ```
260+
/// CARGO_CFG_TARGET_HAS_ATOMIC=16,32,64,8,ptr
261+
/// ```
262+
///
263+
/// On the other hand, configuration symbols without any value should result in
264+
/// an empty string.
265+
///
266+
/// For example, this configuration:
267+
///
268+
/// ```
269+
/// target_thread_local
270+
/// ```
271+
///
272+
/// Should result in the following environment variable:
273+
///
274+
/// ```
275+
/// CARGO_CFG_TARGET_THREAD_LOCAL=
276+
/// ```
277+
#[cargo_test(nightly, reason = "affected rustc cfg is unstable")]
278+
#[cfg(target_arch = "x86_64")]
279+
fn rustc_cfg_with_and_without_value() {
280+
let build_rs = r#"
281+
fn main() {
282+
let cfg = std::env::var("CARGO_CFG_TARGET_THREAD_LOCAL").unwrap();
283+
eprintln!("CARGO_CFG_TARGET_THREAD_LOCAL={cfg}");
284+
let cfg = std::env::var("CARGO_CFG_TARGET_HAS_ATOMIC").unwrap();
285+
eprintln!("CARGO_CFG_TARGET_HAS_ATOMIC={cfg}");
286+
let cfg = std::env::var("CARGO_CFG_TARGET_HAS_ATOMIC_LOAD_STORE").unwrap();
287+
eprintln!("CARGO_CFG_TARGET_HAS_ATOMIC_LOAD_STORE={cfg}");
288+
}
289+
"#;
290+
291+
let p = project()
292+
.file("src/lib.rs", r#""#)
293+
.file("build.rs", build_rs)
294+
.build();
295+
296+
p.cargo("check -vv")
297+
.with_stderr_contains("[foo 0.0.1] CARGO_CFG_TARGET_THREAD_LOCAL=")
298+
.with_stderr_contains("[foo 0.0.1] CARGO_CFG_TARGET_HAS_ATOMIC=16,32,64,8,ptr")
299+
.with_stderr_contains("[foo 0.0.1] CARGO_CFG_TARGET_HAS_ATOMIC_LOAD_STORE=16,32,64,8,ptr")
300+
.run();
301+
}

0 commit comments

Comments
 (0)