Skip to content

Commit

Permalink
Detect and use sccache by introspecting RUSTC_WRAPPER (#475)
Browse files Browse the repository at this point in the history
* Detect and use `sccache` via `RUSTC_WRAPPER`

If no other C/C++ caching tool is found by inspecting `CC` and `CXX`,
`RUSTC_WRAPPER` is tested to see if an output-caching wrapper for
`rustc` is in use. If that is the case and it is a wrapper known to also
support C/C++ caching, use it.

(Also correct/clarify a misnamed variable that caused me some confusion
looking over the code.)

* Support RUSTC_WRAPPER on Windows and with absolute paths

When checking for possible `RUSTC_WRAPPER`s that we can use to cache
C/C++ output, allow for filename extensions (e.g. `sccache.exe`) and
absolute paths (e.g. `/usr/local/bin/sccache`).

Closes #473
  • Loading branch information
mqudsi authored Feb 4, 2020
1 parent aebeadd commit 4b72474
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
35 changes: 29 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1867,7 +1867,7 @@ impl Build {
cmd.args.push(sdk_path.trim().into());
cmd.args.push("-fembed-bitcode".into());
/*
* TODO we probably ultimatedly want the -fembed-bitcode-marker flag
* TODO we probably ultimately want the -fembed-bitcode-marker flag
* but can't have it now because of an issue in LLVM:
* https://github.com/alexcrichton/cc-rs/issues/301
* https://github.com/rust-lang/rust/pull/48896#comment-372192660
Expand Down Expand Up @@ -1919,13 +1919,13 @@ impl Build {
.iter()
.find(|a| a.starts_with(DRIVER_MODE))
.map(|a| &a[DRIVER_MODE.len()..]);
// chop off leading/trailing whitespace to work around
// Chop off leading/trailing whitespace to work around
// semi-buggy build scripts which are shared in
// makefiles/configure scripts (where spaces are far more
// lenient)
let mut t = Tool::with_clang_driver(PathBuf::from(tool.trim()), driver_mode);
if let Some(cc) = wrapper {
t.cc_wrapper_path = Some(PathBuf::from(cc));
if let Some(cc_wrapper) = wrapper {
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
}
for arg in args {
t.cc_wrapper_args.push(arg.into());
Expand Down Expand Up @@ -2065,7 +2065,12 @@ impl Build {
} else {
default.to_string()
};
Tool::new(PathBuf::from(compiler))

let mut t = Tool::new(PathBuf::from(compiler));
if let Some(cc_wrapper) = Self::rustc_wrapper_fallback() {
t.cc_wrapper_path = Some(PathBuf::from(cc_wrapper));
}
t
}
};

Expand Down Expand Up @@ -2141,6 +2146,24 @@ impl Build {
.collect()
}

/// Returns a fallback `cc_compiler_wrapper` by introspecting `RUSTC_WRAPPER`
fn rustc_wrapper_fallback() -> Option<String> {
// No explicit CC wrapper was detected, but check if RUSTC_WRAPPER
// is defined and is a build accelerator that is compatible with
// C/C++ compilers (e.g. sccache)
let valid_wrappers = ["sccache"];

let rustc_wrapper = std::env::var_os("RUSTC_WRAPPER")?;
let wrapper_path = Path::new(&rustc_wrapper);
let wrapper_stem = wrapper_path.file_stem()?;

if valid_wrappers.contains(&wrapper_stem.to_str()?) {
Some(rustc_wrapper.to_str()?.to_owned())
} else {
None
}
}

/// Returns compiler path, optional modifier name from whitelist, and arguments vec
fn env_tool(&self, name: &str) -> Option<(String, Option<String>, Vec<String>)> {
let tool = match self.get_var(name) {
Expand Down Expand Up @@ -2200,7 +2223,7 @@ impl Build {

Some((
maybe_wrapper.to_string(),
None,
Self::rustc_wrapper_fallback(),
parts.map(|s| s.to_string()).collect(),
))
}
Expand Down
12 changes: 12 additions & 0 deletions tests/support/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ pub struct Execution {

impl Test {
pub fn new() -> Test {
// This is ugly: `sccache` needs to introspect the compiler it is
// executing, as it adjusts its behavior depending on the
// language/compiler. This crate's test driver uses mock compilers that
// are obviously not supported by sccache, so the tests fail if
// RUSTC_WRAPPER is set. rust doesn't build test dependencies with
// the `test` feature enabled, so we can't conditionally disable the
// usage of `sccache` if running in a test environment, at least not
// without setting an environment variable here and testing for it
// there. Explicitly deasserting RUSTC_WRAPPER here seems to be the
// lesser of the two evils.
env::remove_var("RUSTC_WRAPPER");

let mut gcc = PathBuf::from(env::current_exe().unwrap());
gcc.pop();
if gcc.ends_with("deps") {
Expand Down

0 comments on commit 4b72474

Please sign in to comment.