1 //! Runs `rustc --print cfg` to get built-in cfg flags.
3 use std::process::Command;
7 use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath};
9 pub(crate) fn get(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Vec<CfgFlag> {
10 let _p = profile::span("rustc_cfg::get");
11 let mut res = Vec::with_capacity(6 * 2 + 1);
13 // Some nightly-only cfgs, which are required for stdlib
14 res.push(CfgFlag::Atom("target_thread_local".into()));
15 for ty in ["8", "16", "32", "64", "cas", "ptr"] {
16 for key in ["target_has_atomic", "target_has_atomic_load_store"] {
17 res.push(CfgFlag::KeyValue { key: key.to_string(), value: ty.into() });
21 match get_rust_cfgs(cargo_toml, target) {
24 "rustc cfgs found: {:?}",
27 .map(|it| it.parse::<CfgFlag>().map(|it| it.to_string()))
30 res.extend(rustc_cfgs.lines().filter_map(|it| it.parse().ok()));
32 Err(e) => tracing::error!("failed to get rustc cfgs: {e:?}"),
38 fn get_rust_cfgs(cargo_toml: Option<&ManifestPath>, target: Option<&str>) -> Result<String> {
39 if let Some(cargo_toml) = cargo_toml {
40 let mut cargo_config = Command::new(toolchain::cargo());
42 .current_dir(cargo_toml.parent())
43 .args(&["-Z", "unstable-options", "rustc", "--print", "cfg"])
44 .env("RUSTC_BOOTSTRAP", "1");
45 if let Some(target) = target {
46 cargo_config.args(&["--target", target]);
48 match utf8_stdout(cargo_config) {
49 Ok(it) => return Ok(it),
50 Err(e) => tracing::debug!("{e:?}: falling back to querying rustc for cfgs"),
53 // using unstable cargo features failed, fall back to using plain rustc
54 let mut cmd = Command::new(toolchain::rustc());
55 cmd.args(&["--print", "cfg", "-O"]);
56 if let Some(target) = target {
57 cmd.args(&["--target", target]);