Skip to content

Commit e552eeb

Browse files
committed
generator: Parse rustc --print cfg
1 parent 7a786c5 commit e552eeb

File tree

2 files changed

+83
-4
lines changed

2 files changed

+83
-4
lines changed

dev-tools/gen-target-info/src/read.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1-
use std::process;
1+
use std::{io::BufRead, process};
22

3-
use crate::{RustcTargetSpecs, TargetSpec};
3+
use crate::{Cfgs, RustcTargetSpecs, TargetSpec};
4+
5+
fn get_cfgs(version: &str, target: &str) -> Cfgs {
6+
let mut cmd = process::Command::new("rustc");
7+
cmd.args([
8+
version,
9+
"-Zunstable-options",
10+
"--print",
11+
"cfg",
12+
"--target",
13+
target,
14+
]);
15+
cmd.env("RUSTC_BOOTSTRAP", "1");
16+
cmd.stdout(process::Stdio::piped());
17+
cmd.stderr(process::Stdio::inherit());
18+
19+
let process::Output { status, stdout, .. } = cmd.output().unwrap();
20+
21+
if !status.success() {
22+
panic!("{:?} failed with non-zero exit status: {}", cmd, status)
23+
}
24+
25+
let cfgs: Vec<String> = stdout.lines().map(|line| line.unwrap()).collect();
26+
Cfgs::parse(&cfgs)
27+
}
428

529
pub fn get_targets_msrv() -> Vec<u8> {
630
let mut cmd = process::Command::new("rustc");
@@ -37,7 +61,9 @@ pub fn get_target_spec_from_msrv(target: &str) -> TargetSpec {
3761
panic!("{:?} failed with non-zero exit status: {}", cmd, status)
3862
}
3963

40-
serde_json::from_slice(&stdout).unwrap()
64+
let mut spec: TargetSpec = serde_json::from_slice(&stdout).unwrap();
65+
spec.cfgs = get_cfgs("+1.63", target);
66+
spec
4167
}
4268

4369
pub fn get_target_specs_from_json() -> RustcTargetSpecs {
@@ -57,5 +83,9 @@ pub fn get_target_specs_from_json() -> RustcTargetSpecs {
5783
panic!("{:?} failed with non-zero exit status: {}", cmd, status)
5884
}
5985

60-
serde_json::from_slice(&stdout).unwrap()
86+
let mut specs: RustcTargetSpecs = serde_json::from_slice(&stdout).unwrap();
87+
for (target, spec) in &mut specs.0 {
88+
spec.cfgs = get_cfgs("+nightly", target);
89+
}
90+
specs
6191
}

dev-tools/gen-target-info/src/target_specs.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ pub struct TargetSpec {
2323
pub vendor: Option<String>,
2424
pub env: Option<String>,
2525
pub abi: Option<String>,
26+
pub target_pointer_width: String,
2627
pub pre_link_args: Option<PreLinkArgs>,
28+
#[serde(skip)]
29+
pub cfgs: Cfgs,
2730
}
2831

2932
#[derive(Debug, Deserialize)]
@@ -32,3 +35,49 @@ pub struct RustcTargetSpecs(
3235
/// First field in the tuple is the rustc target
3336
pub BTreeMap<String, TargetSpec>,
3437
);
38+
39+
/// Potentially useful values from:
40+
/// https://doc.rust-lang.org/reference/conditional-compilation.html
41+
///
42+
/// That are not directly / easily exposed in `TargetSpec`.
43+
#[derive(Debug, Default)]
44+
pub struct Cfgs {
45+
pub target_features: Vec<String>,
46+
pub target_families: Vec<String>,
47+
pub target_endian: String,
48+
pub target_atomics: Vec<String>,
49+
pub target_thread_local: bool,
50+
}
51+
52+
impl Cfgs {
53+
pub fn parse(cfgs: &[String]) -> Self {
54+
let mut target_features = vec![];
55+
let mut target_families = vec![];
56+
let mut target_endian = None;
57+
let mut target_atomics = vec![];
58+
let mut target_thread_local = false;
59+
for cfg in cfgs {
60+
let (name, value) = cfg
61+
.split_once('=')
62+
.map(|(n, v)| (n.trim(), Some(v.trim().trim_matches('"'))))
63+
.unwrap_or((cfg.trim(), None));
64+
65+
match (name, value) {
66+
("target_feature", Some(value)) => target_features.push(value.to_string()),
67+
("target_family", Some(value)) => target_families.push(value.to_string()),
68+
("target_endian", Some(value)) => target_endian = Some(value.to_string()),
69+
("target_has_atomic", Some(value)) => target_atomics.push(value.to_string()),
70+
("target_thread_local", None) => target_thread_local = true,
71+
_ => {} // Ignore the rest
72+
}
73+
}
74+
75+
Self {
76+
target_features,
77+
target_families,
78+
target_endian: target_endian.expect("must have target_endian cfg"),
79+
target_atomics,
80+
target_thread_local,
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)