Skip to content

Commit

Permalink
Merge pull request #56 from cuviper/wrappers
Browse files Browse the repository at this point in the history
Support `RUSTC_WRAPPER` and `RUSTC_WORKSPACE_WRAPPER`
  • Loading branch information
cuviper authored Mar 25, 2024
2 parents cf17815 + 1ca2af8 commit 7f3e58b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
41 changes: 40 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ mod tests;
pub struct AutoCfg {
out_dir: PathBuf,
rustc: PathBuf,
rustc_wrapper: Option<PathBuf>,
rustc_workspace_wrapper: Option<PathBuf>,
rustc_version: Version,
target: Option<OsString>,
no_std: bool,
Expand Down Expand Up @@ -168,6 +170,8 @@ impl AutoCfg {

let mut ac = AutoCfg {
rustflags: rustflags(&target, &dir),
rustc_wrapper: get_rustc_wrapper(false),
rustc_workspace_wrapper: get_rustc_wrapper(true),
out_dir: dir,
rustc: rustc,
rustc_version: rustc_version,
Expand Down Expand Up @@ -234,7 +238,18 @@ impl AutoCfg {
static ID: AtomicUsize = ATOMIC_USIZE_INIT;

let id = ID.fetch_add(1, Ordering::Relaxed);
let mut command = Command::new(&self.rustc);

// Build the command with possible wrappers.
let mut rustc = self
.rustc_wrapper
.iter()
.chain(self.rustc_workspace_wrapper.iter())
.chain(Some(&self.rustc));
let mut command = Command::new(rustc.next().unwrap());
for arg in rustc {
command.arg(arg);
}

command
.arg("--crate-name")
.arg(format!("probe{}", id))
Expand Down Expand Up @@ -478,3 +493,27 @@ fn rustflags(target: &Option<OsString>, dir: &Path) -> Vec<String> {

Vec::new()
}

fn get_rustc_wrapper(workspace: bool) -> Option<PathBuf> {
// We didn't really know whether the workspace wrapper is applicable until Cargo started
// deliberately setting or unsetting it in rust-lang/cargo#9601. We'll use the encoded
// rustflags as a proxy for that change for now, but we could instead check version 1.55.
if workspace && env::var_os("CARGO_ENCODED_RUSTFLAGS").is_none() {
return None;
}

let name = if workspace {
"RUSTC_WORKSPACE_WRAPPER"
} else {
"RUSTC_WRAPPER"
};

if let Some(wrapper) = env::var_os(name) {
// NB: `OsStr` didn't get `len` or `is_empty` until 1.9.
if wrapper != OsString::new() {
return Some(wrapper.into());
}
}

None
}
51 changes: 51 additions & 0 deletions tests/wrappers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
extern crate autocfg;

use std::env;

/// Tests that autocfg uses the RUSTC_WRAPPER and/or RUSTC_WORKSPACE_WRAPPER
/// environment variables when running rustc.
#[test]
#[cfg(unix)] // we're using system binaries as wrappers
fn test_wrappers() {
fn set(name: &str, value: Option<bool>) {
match value {
Some(true) => env::set_var(name, "/usr/bin/env"),
Some(false) => env::set_var(name, "/bin/false"),
None => env::remove_var(name),
}
}

// Use the same path as this test binary.
let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf();
env::set_var("OUT_DIR", &format!("{}", dir.display()));

// This is used as a heuristic to detect rust-lang/cargo#9601.
env::set_var("CARGO_ENCODED_RUSTFLAGS", "");

// No wrapper, a good pass-through wrapper, and a bad wrapper.
let variants = [None, Some(true), Some(false)];

for &workspace in &variants {
for &rustc in &variants {
set("RUSTC_WRAPPER", rustc);
set("RUSTC_WORKSPACE_WRAPPER", workspace);

let ac = autocfg::AutoCfg::new().unwrap();
if rustc == Some(false) || workspace == Some(false) {
// Everything should fail with bad wrappers.
assert!(!ac.probe_type("usize"));
} else {
// Try known good and bad types for the wrapped rustc.
assert!(ac.probe_type("usize"));
assert!(!ac.probe_type("mesize"));
}
}
}

// Finally, make sure that `RUSTC_WRAPPER` is applied outermost
// by using something that doesn't pass through at all.
env::set_var("RUSTC_WRAPPER", "/bin/true");
env::set_var("RUSTC_WORKSPACE_WRAPPER", "/bin/false");
let ac = autocfg::AutoCfg::new().unwrap();
assert!(ac.probe_type("mesize")); // anything goes!
}

0 comments on commit 7f3e58b

Please sign in to comment.