about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro.albini@ferrous-systems.com>2023-03-09 17:04:11 +0100
committerPietro Albini <pietro.albini@ferrous-systems.com>2023-04-03 09:24:15 +0200
commit0e6d2053b460a130ad798a5037708bb01352b3ea (patch)
treeb2b748b506fc897fab312bcf7bae2beb469de377
parentef2bf6d5053f55057aecd0f0cb35c13ef332d72a (diff)
downloadrust-0e6d2053b460a130ad798a5037708bb01352b3ea.tar.gz
rust-0e6d2053b460a130ad798a5037708bb01352b3ea.zip
use target specs rather than --print=cfg to discover targets
-rw-r--r--src/tools/compiletest/src/common.rs78
1 files changed, 29 insertions, 49 deletions
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 86810179ff8..03c0f2982fa 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -11,6 +11,7 @@ use crate::util::{add_dylib_path, PathBufExt};
 use lazycell::LazyCell;
 use std::collections::HashSet;
 use test::{ColorConfig, OutputFormat};
+use serde::de::{Deserialize, Deserializer, Error as _};
 
 macro_rules! string_enum {
     ($(#[$meta:meta])* $vis:vis enum $name:ident { $($variant:ident => $repr:expr,)* }) => {
@@ -114,8 +115,10 @@ string_enum! {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Clone, Copy, Debug, PartialEq, Default, serde::Deserialize)]
+#[serde(rename_all = "kebab-case")]
 pub enum PanicStrategy {
+    #[default]
     Unwind,
     Abort,
 }
@@ -450,72 +453,43 @@ impl TargetCfgs {
     }
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, serde::Deserialize)]
+#[serde(rename_all = "kebab-case")]
 pub struct TargetCfg {
     pub(crate) arch: String,
+    #[serde(default)]
     pub(crate) os: String,
+    #[serde(default)]
     pub(crate) env: String,
+    #[serde(default)]
     pub(crate) abi: String,
+    #[serde(rename = "target-family", default)]
     pub(crate) families: Vec<String>,
+    #[serde(rename = "target-pointer-width", deserialize_with = "serde_parse_u32")]
     pub(crate) pointer_width: u32,
+    #[serde(rename = "target-endian", default)]
     endian: Endian,
+    #[serde(rename = "panic-strategy", default)]
     panic: PanicStrategy,
 }
 
-#[derive(Eq, PartialEq, Clone, Debug)]
+#[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
+#[serde(rename_all = "kebab-case")]
 pub enum Endian {
+    #[default]
     Little,
     Big,
 }
 
 impl TargetCfg {
     fn new(config: &Config, target: &str) -> TargetCfg {
-        let print_cfg = rustc_output(config, &["--print=cfg", "--target", target]);
-        let mut arch = None;
-        let mut os = None;
-        let mut env = None;
-        let mut abi = None;
-        let mut families = Vec::new();
-        let mut pointer_width = None;
-        let mut endian = None;
-        let mut panic = None;
-        for line in print_cfg.lines() {
-            if let Some((name, value)) = line.split_once('=') {
-                let value = value.trim_matches('"');
-                match name {
-                    "target_arch" => arch = Some(value),
-                    "target_os" => os = Some(value),
-                    "target_env" => env = Some(value),
-                    "target_abi" => abi = Some(value),
-                    "target_family" => families.push(value.to_string()),
-                    "target_pointer_width" => pointer_width = Some(value.parse().unwrap()),
-                    "target_endian" => {
-                        endian = Some(match value {
-                            "little" => Endian::Little,
-                            "big" => Endian::Big,
-                            s => panic!("unexpected {s}"),
-                        })
-                    }
-                    "panic" => {
-                        panic = match value {
-                            "abort" => Some(PanicStrategy::Abort),
-                            "unwind" => Some(PanicStrategy::Unwind),
-                            s => panic!("unexpected {s}"),
-                        }
-                    }
-                    _ => {}
-                }
-            }
-        }
-        TargetCfg {
-            arch: arch.unwrap().to_string(),
-            os: os.unwrap().to_string(),
-            env: env.unwrap().to_string(),
-            abi: abi.unwrap().to_string(),
-            families,
-            pointer_width: pointer_width.unwrap(),
-            endian: endian.unwrap(),
-            panic: panic.unwrap(),
+        let json = rustc_output(
+            config,
+            &["--print=target-spec-json", "-Zunstable-options", "--target", target],
+        );
+        match serde_json::from_str(&json) {
+            Ok(res) => res,
+            Err(err) => panic!("failed to parse target spec for {target}: {err}"),
         }
     }
 }
@@ -524,6 +498,7 @@ fn rustc_output(config: &Config, args: &[&str]) -> String {
     let mut command = Command::new(&config.rustc_path);
     add_dylib_path(&mut command, iter::once(&config.compile_lib_path));
     command.args(&config.target_rustcflags).args(args);
+    command.env("RUSTC_BOOTSTRAP", "1");
 
     let output = match command.output() {
         Ok(output) => output,
@@ -539,6 +514,11 @@ fn rustc_output(config: &Config, args: &[&str]) -> String {
     String::from_utf8(output.stdout).unwrap()
 }
 
+fn serde_parse_u32<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
+    let string = String::deserialize(deserializer)?;
+    string.parse().map_err(D::Error::custom)
+}
+
 #[derive(Debug, Clone)]
 pub struct TestPaths {
     pub file: PathBuf,         // e.g., compile-test/foo/bar/baz.rs