about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAfonso Bordado <afonsobordado@az8.co>2022-08-06 13:34:55 +0100
committerAfonso Bordado <afonsobordado@az8.co>2022-08-06 15:56:37 +0100
commit3bd9821342d57081aea18cbb53271a20769eaf03 (patch)
tree70827a58bfa6570e86f558ce03affcc964b60656
parent3c97227a433c244f34fb8bb23afe41f259431d9b (diff)
downloadrust-3bd9821342d57081aea18cbb53271a20769eaf03.tar.gz
rust-3bd9821342d57081aea18cbb53271a20769eaf03.zip
Initial ABI Checker support
-rw-r--r--.gitignore1
-rw-r--r--build_system/abi_checker.rs67
-rw-r--r--build_system/mod.rs16
-rw-r--r--build_system/prepare.rs7
4 files changed, 91 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 38dd5b26063..6fd3e4443de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ perf.data.old
 /regex
 /simple-raytracer
 /portable-simd
+/abi-checker
diff --git a/build_system/abi_checker.rs b/build_system/abi_checker.rs
new file mode 100644
index 00000000000..1aff4acc21b
--- /dev/null
+++ b/build_system/abi_checker.rs
@@ -0,0 +1,67 @@
+use super::build_sysroot;
+use super::utils::spawn_and_wait_with_input;
+use build_system::SysrootKind;
+use std::env;
+use std::path::Path;
+use std::process::Command;
+
+pub(crate) fn run(
+    channel: &str,
+    sysroot_kind: SysrootKind,
+    target_dir: &Path,
+    cg_clif_build_dir: &Path,
+    host_triple: &str,
+    target_triple: &str,
+) {
+    assert_eq!(
+        host_triple, target_triple,
+        "abi-checker not supported on cross-compilation scenarios"
+    );
+
+    eprintln!("Building sysroot for abi-checker");
+    build_sysroot::build_sysroot(
+        channel,
+        sysroot_kind,
+        target_dir,
+        cg_clif_build_dir,
+        host_triple,
+        target_triple,
+    );
+
+    eprintln!("Running abi-checker");
+    let mut abi_checker_path = env::current_dir().unwrap();
+    abi_checker_path.push("abi-checker");
+    env::set_current_dir(abi_checker_path.clone()).unwrap();
+
+    let build_dir = abi_checker_path.parent().unwrap().join("build");
+    let cg_clif_dylib_path = build_dir.join(if cfg!(windows) { "bin" } else { "lib" }).join(
+        env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
+    );
+    println!("cg_clif_dylib_path: {}", cg_clif_dylib_path.display());
+
+    let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
+
+    for pair in pairs {
+        eprintln!("[ABI-CHECKER] Running pair {pair}");
+
+        let mut cmd = Command::new("cargo");
+        cmd.arg("run");
+        cmd.arg("--target");
+        cmd.arg(target_triple);
+        cmd.arg("--");
+        cmd.arg("--pairs");
+        cmd.arg(pair);
+        cmd.arg("--add-rustc-codegen-backend");
+        cmd.arg(format!("cgclif:{}", cg_clif_dylib_path.display()));
+
+        let output = spawn_and_wait_with_input(cmd, "".to_string());
+
+        // TODO: The correct thing to do here is to check the exit code, but abi-checker
+        // currently doesn't return 0 on success, so check for the test fail count.
+        // See: https://github.com/Gankra/abi-checker/issues/10
+        let failed = !(output.contains("0 failed") && output.contains("0 completely failed"));
+        if failed {
+            panic!("abi-checker for pair {} failed!", pair);
+        }
+    }
+}
diff --git a/build_system/mod.rs b/build_system/mod.rs
index 88c4150dbba..c5b3e6619b7 100644
--- a/build_system/mod.rs
+++ b/build_system/mod.rs
@@ -4,6 +4,7 @@ use std::process;
 
 use self::utils::is_ci;
 
+mod abi_checker;
 mod build_backend;
 mod build_sysroot;
 mod config;
@@ -21,6 +22,9 @@ fn usage() {
     eprintln!(
         "  ./y.rs test [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
     );
+    eprintln!(
+        "  ./y.rs abi-checker [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
+    );
 }
 
 macro_rules! arg_error {
@@ -35,6 +39,7 @@ macro_rules! arg_error {
 enum Command {
     Build,
     Test,
+    AbiChecker,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -66,6 +71,7 @@ pub fn main() {
         }
         Some("build") => Command::Build,
         Some("test") => Command::Test,
+        Some("abi-checker") => Command::AbiChecker,
         Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
         Some(command) => arg_error!("Unknown command {}", command),
         None => {
@@ -152,5 +158,15 @@ pub fn main() {
                 &target_triple,
             );
         }
+        Command::AbiChecker => {
+            abi_checker::run(
+                channel,
+                sysroot_kind,
+                &target_dir,
+                &cg_clif_build_dir,
+                &host_triple,
+                &target_triple,
+            );
+        }
     }
 }
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index 7e0fd182d98..12aafdc1fb3 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -15,6 +15,13 @@ pub(crate) fn prepare() {
     Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
 
     clone_repo_shallow_github(
+        "abi-checker",
+        "Gankra",
+        "abi-checker",
+        "7c1571da6e43f9a37347623e7d5c7d51be664a7b",
+    );
+
+    clone_repo_shallow_github(
         "rand",
         "rust-random",
         "rand",