Browse Source

Handle paths to ccache-like wrappers

Closes #298
cl-test
Alex Crichton 7 years ago
parent
commit
02a09e2411
  1. 41
      src/lib.rs
  2. 24
      tests/cc_env.rs

41
src/lib.rs

@ -1651,18 +1651,41 @@ impl Build {
/// Returns compiler path, optional modifier name from whitelist, and arguments vec
fn env_tool(&self, name: &str) -> Option<(String, Option<String>, Vec<String>)> {
self.get_var(name).ok().map(|tool| {
let whitelist = ["ccache", "distcc", "sccache", "icecc"];
let tool = match self.get_var(name) {
Ok(tool) => tool,
Err(_) => return None,
};
for t in whitelist.iter() {
if tool.starts_with(t) && tool[t.len()..].starts_with(' ') {
let args = tool.split_whitespace().collect::<Vec<_>>();
// If our env var looks like `CC='ccache gcc'` then we want to handle
// that by default and use `ccache` as a wrapper and `gcc` as the actual
// compiler itself. This is quite common in a lot of build systems and
// it's in general best to just handle it.
//
// Note that we're careful here though because we don't want to
// misinterpret `CC='C:\path to\bin\gcc.exe'` as a wrapper by default.
// In other words we want to support spaces in paths to compilers as it
// happens from time to time. As a result we maintain a whitelist here
// of ccache-like wrappers and only split on spaces if we see them.
let whitelist = ["ccache", "distcc", "sccache", "icecc"];
let mut parts = tool.split_whitespace();
let maybe_wrapper = match parts.next() {
Some(s) => s,
None => return None,
};
return (args[1].to_string(), Some(t.to_string()), args[2..].iter().map(|s| s.to_string()).collect());
}
let file_stem = Path::new(maybe_wrapper).file_stem().unwrap().to_str().unwrap();
if whitelist.contains(&file_stem) {
if let Some(compiler) = parts.next() {
return Some((
compiler.to_string(),
Some(maybe_wrapper.to_string()),
parts.map(|s| s.to_string()).collect(),
))
}
(tool, None, Vec::new())
})
}
Some((tool.clone(), None, Vec::new()))
}
/// Returns the default C++ standard library for the current target: `libc++`

24
tests/cc_env.rs

@ -15,6 +15,8 @@ fn main() {
ccache_spaces();
ccache_env_flags();
leading_spaces();
extra_flags();
path_to_ccache();
}
fn ccache() {
@ -83,3 +85,25 @@ fn leading_spaces() {
env::set_var("CC", "");
}
fn extra_flags() {
let test = Test::gnu();
test.shim("ccache");
env::set_var("CC", "ccache cc -m32");
let compiler = test.gcc().file("foo.c").get_compiler();
assert_eq!(compiler.path(), Path::new("cc"));
}
fn path_to_ccache() {
let test = Test::gnu();
test.shim("ccache");
env::set_var("CC", "/path/to/ccache.exe cc -m32");
let compiler = test.gcc().file("foo.c").get_compiler();
assert_eq!(compiler.path(), Path::new("cc"));
assert_eq!(
compiler.cc_env(),
OsString::from("/path/to/ccache.exe cc -m32"),
);
}

Loading…
Cancel
Save