From f80bd6e0a4be2d85a684f1aa5fb9677bac9e1103 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 12 Jan 2023 16:00:46 -0800 Subject: [PATCH] Sync build.rs with rustix Sync cap-std's build.rs with the changes in rustix in https://github.com/bytecodealliance/rustix/pull/511 --- build.rs | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/build.rs b/build.rs index 912e0a9f..3481199d 100644 --- a/build.rs +++ b/build.rs @@ -36,20 +36,53 @@ fn use_feature(feature: &str) { /// Test whether the rustc at `var("RUSTC")` supports the given feature. fn has_feature(feature: &str) -> bool { + can_compile(&format!( + "#![allow(stable_features)]\n#![feature({})]", + feature + )) +} + +/// Test whether the rustc at `var("RUSTC")` can compile the given code. +fn can_compile>(test: T) -> bool { + use std::process::Stdio; + let out_dir = var("OUT_DIR").unwrap(); let rustc = var("RUSTC").unwrap(); + let target = var("TARGET").unwrap(); + + let mut cmd = if let Ok(wrapper) = var("CARGO_RUSTC_WRAPPER") { + let mut cmd = std::process::Command::new(wrapper); + // The wrapper's first argument is supposed to be the path to rustc. + cmd.arg(rustc); + cmd + } else { + std::process::Command::new(rustc) + }; - let mut child = std::process::Command::new(rustc) - .arg("--crate-type=rlib") // Don't require `main`. + cmd.arg("--crate-type=rlib") // Don't require `main`. .arg("--emit=metadata") // Do as little as possible but still parse. + .arg("--target") + .arg(target) .arg("--out-dir") - .arg(out_dir) // Put the output somewhere inconsequential. + .arg(out_dir); // Put the output somewhere inconsequential. + + // If Cargo wants to set RUSTFLAGS, use that. + if let Ok(rustflags) = var("CARGO_ENCODED_RUSTFLAGS") { + if !rustflags.is_empty() { + for arg in rustflags.split('\x1f') { + cmd.arg(arg); + } + } + } + + let mut child = cmd .arg("-") // Read from stdin. - .stdin(std::process::Stdio::piped()) // Stdin is a pipe. + .stdin(Stdio::piped()) // Stdin is a pipe. + .stderr(Stdio::null()) // Errors from feature detection aren't interesting and can be confusing. .spawn() .unwrap(); - writeln!(child.stdin.take().unwrap(), "#![feature({})]", feature).unwrap(); + writeln!(child.stdin.take().unwrap(), "{}", test.as_ref()).unwrap(); child.wait().unwrap().success() }