Browse Source

env_tool returning additional param for ccache case

cl-test
fedor 7 years ago
parent
commit
6da479d6d8
  1. 55
      src/lib.rs
  2. 20
      tests/cc_env.rs

55
src/lib.rs

@ -148,7 +148,8 @@ impl From<io::Error> for Error {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Tool { pub struct Tool {
path: PathBuf, path: PathBuf,
path_args: Vec<OsString>, cc_path: Option<PathBuf>,
cc_args: Vec<OsString>,
args: Vec<OsString>, args: Vec<OsString>,
env: Vec<(OsString, OsString)>, env: Vec<(OsString, OsString)>,
family: ToolFamily family: ToolFamily
@ -1283,10 +1284,13 @@ impl Build {
}; };
let tool_opt: Option<Tool> = self.env_tool(env) let tool_opt: Option<Tool> = self.env_tool(env)
.map(|(tool, args)| { .map(|(tool, cc, args)| {
let mut t = Tool::new(PathBuf::from(tool)); let mut t = Tool::new(PathBuf::from(tool));
if let Some(cc) = cc {
t.cc_path = Some(PathBuf::from(cc));
}
for arg in args { for arg in args {
t.path_args.push(arg.into()); t.cc_args.push(arg.into());
} }
t t
}) })
@ -1403,15 +1407,19 @@ impl Build {
} }
fn env_tool(&self, name: &str) -> Option<(String, Vec<String>)> { /// 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| { self.get_var(name).ok().map(|tool| {
let whitelist = ["ccache", "distcc", "sccache"]; let whitelist = ["ccache", "distcc", "sccache"];
for t in whitelist.iter() { for t in whitelist.iter() {
if tool.starts_with(t) && tool[t.len()..].starts_with(' ') { if tool.starts_with(t) && tool[t.len()..].starts_with(' ') {
return (t.to_string(), vec![tool[t.len()..].trim_left().to_string()]); let args = tool.split_whitespace().collect::<Vec<_>>();
return (args[1].to_string(), Some(t.to_string()), args[2..].iter().map(|s| s.to_string()).collect());
} }
} }
(tool, Vec::new()) (tool, None, Vec::new())
}) })
} }
@ -1541,7 +1549,8 @@ impl Tool {
}; };
Tool { Tool {
path: path, path: path,
path_args: Vec::new(), cc_path: None,
cc_args: Vec::new(),
args: Vec::new(), args: Vec::new(),
env: Vec::new(), env: Vec::new(),
family: family family: family
@ -1555,7 +1564,7 @@ impl Tool {
/// variables configured. /// variables configured.
pub fn to_command(&self) -> Command { pub fn to_command(&self) -> Command {
let mut cmd = Command::new(&self.path); let mut cmd = Command::new(&self.path);
cmd.args(&self.path_args); cmd.args(&self.cc_args);
cmd.args(&self.args); cmd.args(&self.args);
for &(ref k, ref v) in self.env.iter() { for &(ref k, ref v) in self.env.iter() {
cmd.env(k, v); cmd.env(k, v);
@ -1586,20 +1595,30 @@ impl Tool {
} }
/// Returns the compiler command in format of CC environment variable. /// Returns the compiler command in format of CC environment variable.
/// /// Or empty string if CC env was not present
/// This is typically used by configure script ///
/// This is typically used by configure script
pub fn cc_env(&self) -> OsString { pub fn cc_env(&self) -> OsString {
let mut cc = self.path.as_os_str().to_owned(); match self.cc_path {
for arg in self.path_args.iter() { Some(ref cc_path) => {
cc.push(" "); let mut cc_env = cc_path.as_os_str().to_owned();
cc.push(arg); cc_env.push(" ");
cc_env.push(self.path.to_path_buf().into_os_string());
for arg in self.cc_args.iter() {
cc_env.push(" ");
cc_env.push(arg);
}
cc_env
},
None => {
OsString::from("")
}
} }
cc
} }
/// Returns the compiler flags in format of CFLAGS environment variable. /// Returns the compiler flags in format of CFLAGS environment variable.
/// /// Important here - this will not be CFLAGS from env, its internal gcc's flags to use as CFLAGS
/// This is typically used by configure script /// This is typically used by configure script
pub fn cflags_env(&self) -> OsString { pub fn cflags_env(&self) -> OsString {
let mut flags = OsString::new(); let mut flags = OsString::new();
for (i, arg) in self.args.iter().enumerate() { for (i, arg) in self.args.iter().enumerate() {

20
tests/cc_env.rs

@ -16,37 +16,37 @@ fn main() {
fn ccache() { fn ccache() {
let test = Test::gnu(); let test = Test::gnu();
test.shim("ccache");
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo"); env::set_var("CC", "ccache cc");
test.gcc().file("foo.c").compile("libfoo.a"); test.gcc().file("foo.c").compile("foo");
test.cmd(0) test.cmd(0)
.must_have("lol-this-is-not-a-compiler foo")
.must_have("foo.c") .must_have("foo.c")
.must_not_have("ccache"); .must_not_have("ccache");
test.cmd(1).must_have(test.td.path().join("foo.o"));
} }
fn ccache_spaces() { fn ccache_spaces() {
let test = Test::gnu(); let test = Test::gnu();
test.shim("ccache"); test.shim("ccache");
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo"); env::set_var("CC", "ccache cc");
test.gcc().file("foo.c").compile("libfoo.a"); test.gcc().file("foo.c").compile("libfoo.a");
test.cmd(0).must_have("lol-this-is-not-a-compiler foo"); test.cmd(0).must_have("foo.c");
test.cmd(1).must_have(test.td.path().join("foo.o"));
} }
fn distcc() { fn distcc() {
let test = Test::gnu(); let test = Test::gnu();
test.shim("distcc"); test.shim("distcc");
env::set_var("CC", "distcc lol-this-is-not-a-compiler foo"); env::set_var("CC", "distcc cc");
test.gcc().file("foo.c").compile("libfoo.a"); test.gcc().file("foo.c").compile("foo");
test.cmd(0) test.cmd(0)
.must_have("lol-this-is-not-a-compiler foo")
.must_have("foo.c") .must_have("foo.c")
.must_not_have("distcc"); .must_not_have("distcc");
test.cmd(1).must_have(test.td.path().join("foo.o"));
} }
fn ccache_env_flags() { fn ccache_env_flags() {
@ -58,7 +58,7 @@ fn ccache_env_flags() {
env::set_var("CC", "ccache lol-this-is-not-a-compiler"); env::set_var("CC", "ccache lol-this-is-not-a-compiler");
let compiler = test.gcc().file("foo.c").get_compiler(); let compiler = test.gcc().file("foo.c").get_compiler();
assert_eq!(compiler.path(), Path::new("ccache")); assert_eq!(compiler.path(), Path::new("lol-this-is-not-a-compiler"));
assert_eq!(compiler.cc_env(), OsString::from("ccache lol-this-is-not-a-compiler")); assert_eq!(compiler.cc_env(), OsString::from("ccache lol-this-is-not-a-compiler"));
assert!(compiler.cflags_env().into_string().unwrap().contains("ccache") == false); assert!(compiler.cflags_env().into_string().unwrap().contains("ccache") == false);
assert!(compiler.cflags_env().into_string().unwrap().contains(" lol-this-is-not-a-compiler") == false); assert!(compiler.cflags_env().into_string().unwrap().contains(" lol-this-is-not-a-compiler") == false);

Loading…
Cancel
Save