Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions src/cargo/util/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ impl Config {
}

pub fn rustc(&self) -> CargoResult<&Rustc> {
self.rustc.get_or_try_init(|| Rustc::new(self.get_tool("rustc")?))
self.rustc.get_or_try_init(|| Rustc::new(self.get_tool("rustc")?,
self.maybe_get_tool("rustc_wrapper")?))
}

pub fn cargo_exe(&self) -> CargoResult<&Path> {
Expand Down Expand Up @@ -415,18 +416,27 @@ impl Config {
}
}

fn get_tool(&self, tool: &str) -> CargoResult<PathBuf> {
/// Look for a path for `tool` in an environment variable or config path, but return `None`
/// if it's not present.
fn maybe_get_tool(&self, tool: &str) -> CargoResult<Option<PathBuf>> {
let var = tool.chars().flat_map(|c| c.to_uppercase()).collect::<String>();
if let Some(tool_path) = env::var_os(&var) {
return Ok(PathBuf::from(tool_path));
return Ok(Some(PathBuf::from(tool_path)));
}

let var = format!("build.{}", tool);
if let Some(tool_path) = self.get_path(&var)? {
return Ok(tool_path.val);
return Ok(Some(tool_path.val));
}

Ok(PathBuf::from(tool))
Ok(None)
}

/// Look for a path for `tool` in an environment variable or config path, defaulting to `tool`
/// as a path.
fn get_tool(&self, tool: &str) -> CargoResult<PathBuf> {
self.maybe_get_tool(tool)
.map(|t| t.unwrap_or(PathBuf::from(tool)))
}
}

Expand Down
18 changes: 14 additions & 4 deletions src/cargo/util/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use util::{self, CargoResult, internal, ChainError, ProcessBuilder};

pub struct Rustc {
pub path: PathBuf,
pub wrapper: Option<PathBuf>,
pub verbose_version: String,
pub host: String,
}
Expand All @@ -14,12 +15,12 @@ impl Rustc {
///
/// If successful this function returns a description of the compiler along
/// with a list of its capabilities.
pub fn new(path: PathBuf) -> CargoResult<Rustc> {
pub fn new(path: PathBuf, wrapper: Option<PathBuf>) -> CargoResult<Rustc> {
let mut cmd = util::process(&path);
cmd.arg("-vV");

let output = cmd.exec_with_output()?;

let verbose_version = String::from_utf8(output.stdout).map_err(|_| {
internal("rustc -v didn't return utf8 output")
})?;
Expand All @@ -36,12 +37,21 @@ impl Rustc {

Ok(Rustc {
path: path,
wrapper: wrapper,
verbose_version: verbose_version,
host: host,
})
}

pub fn process(&self) -> ProcessBuilder {
util::process(&self.path)
if let Some(ref wrapper) = self.wrapper {
let mut cmd = util::process(wrapper);
{
cmd.arg(&self.path);
}
cmd
} else {
util::process(&self.path)
}
}
}
3 changes: 3 additions & 0 deletions src/doc/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ system:
relative to the current working directory.
* `RUSTC` - Instead of running `rustc`, Cargo will execute this specified
compiler instead.
* `RUSTC_WRAPPER` - Instead of simply running `rustc`, Cargo will execute this
specified wrapper instead, passing as its commandline arguments the rustc
invocation, with the first argument being rustc.
* `RUSTDOC` - Instead of running `rustdoc`, Cargo will execute this specified
`rustdoc` instance instead.
* `RUSTFLAGS` - A space-separated list of custom flags to pass to all compiler
Expand Down
15 changes: 15 additions & 0 deletions tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2899,3 +2899,18 @@ fn run_proper_binary_main_rs_as_foo() {
assert_that(p.cargo_process("run").arg("--bin").arg("foo"),
execs().with_status(0));
}

#[test]
fn rustc_wrapper() {
// We don't have /usr/bin/env on Windows.
if cfg!(windows) { return }

let p = project("foo")
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]));

assert_that(p.cargo_process("build").arg("-v").env("RUSTC_WRAPPER", "/usr/bin/env"),
execs().with_stderr_contains(
"[RUNNING] `/usr/bin/env rustc --crate-name foo [..]")
.with_status(0));
}
3 changes: 2 additions & 1 deletion tests/cargotest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::env;
pub mod support;
pub mod install;

thread_local!(pub static RUSTC: Rustc = Rustc::new(PathBuf::from("rustc")).unwrap());
thread_local!(pub static RUSTC: Rustc = Rustc::new(PathBuf::from("rustc"), None).unwrap());

pub fn rustc_host() -> String {
RUSTC.with(|r| r.host.clone())
Expand All @@ -54,6 +54,7 @@ fn _process(t: &OsStr) -> cargo::util::ProcessBuilder {
.env_remove("__CARGO_DEFAULT_LIB_METADATA")
.env_remove("RUSTC")
.env_remove("RUSTDOC")
.env_remove("RUSTC_WRAPPER")
.env_remove("RUSTFLAGS")
.env_remove("CARGO_INCREMENTAL")
.env_remove("XDG_CONFIG_HOME") // see #2345
Expand Down