diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 71d90470fa6..b2f8ed687d8 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -63,7 +63,7 @@ pub fn run(ws: &Workspace, Some(path) => path.to_path_buf(), None => exe.to_path_buf(), }; - let mut process = compile.target_process(exe, pkg)?; + let mut process = compile.target_process(exe, pkg, ws)?; process.args(args).cwd(config.cwd()); config.shell().status("Running", process.to_string())?; diff --git a/src/cargo/ops/cargo_rustc/compilation.rs b/src/cargo/ops/cargo_rustc/compilation.rs index a40c310a12f..0ddd6d7df5f 100644 --- a/src/cargo/ops/cargo_rustc/compilation.rs +++ b/src/cargo/ops/cargo_rustc/compilation.rs @@ -3,7 +3,7 @@ use std::ffi::OsStr; use std::path::PathBuf; use semver::Version; -use core::{PackageId, Package, Target, TargetKind}; +use core::{PackageId, Package, Target, TargetKind, Workspace}; use util::{self, CargoResult, Config, LazyCell, ProcessBuilder, process, join_paths}; /// A structure returning the result of a compilation. @@ -83,19 +83,19 @@ impl<'cfg> Compilation<'cfg> { } /// See `process`. - pub fn rustc_process(&self, pkg: &Package) -> CargoResult { - self.fill_env(self.config.rustc()?.process(), pkg, true) + pub fn rustc_process(&self, pkg: &Package, ws: &Workspace) -> CargoResult { + self.fill_env(self.config.rustc()?.process(), pkg, ws, true) } /// See `process`. - pub fn rustdoc_process(&self, pkg: &Package) -> CargoResult { - self.fill_env(process(&*self.config.rustdoc()?), pkg, false) + pub fn rustdoc_process(&self, pkg: &Package, ws: &Workspace) -> CargoResult { + self.fill_env(process(&*self.config.rustdoc()?), pkg, ws, false) } /// See `process`. - pub fn host_process>(&self, cmd: T, pkg: &Package) + pub fn host_process>(&self, cmd: T, pkg: &Package, ws: &Workspace) -> CargoResult { - self.fill_env(process(cmd), pkg, true) + self.fill_env(process(cmd), pkg, ws, true) } fn target_runner(&self) -> CargoResult<&Option<(PathBuf, Vec)>> { @@ -106,7 +106,7 @@ impl<'cfg> Compilation<'cfg> { } /// See `process`. - pub fn target_process>(&self, cmd: T, pkg: &Package) + pub fn target_process>(&self, cmd: T, pkg: &Package, ws: &Workspace) -> CargoResult { let builder = if let Some((ref runner, ref args)) = *self.target_runner()? { let mut builder = process(runner); @@ -116,7 +116,7 @@ impl<'cfg> Compilation<'cfg> { } else { process(cmd) }; - self.fill_env(builder, pkg, false) + self.fill_env(builder, pkg, ws, false) } /// Prepares a new process with an appropriate environment to run against @@ -124,7 +124,7 @@ impl<'cfg> Compilation<'cfg> { /// /// The package argument is also used to configure environment variables as /// well as the working directory of the child process. - fn fill_env(&self, mut cmd: ProcessBuilder, pkg: &Package, is_host: bool) + fn fill_env(&self, mut cmd: ProcessBuilder, pkg: &Package, ws: &Workspace, is_host: bool) -> CargoResult { let mut search_path = if is_host { @@ -161,6 +161,7 @@ impl<'cfg> Compilation<'cfg> { // consider adding the corresponding properties to the hash // in Context::target_metadata() cmd.env("CARGO_MANIFEST_DIR", pkg.root()) + .env("CARGO_WORKSPACE_DIR", ws.root()) .env("CARGO_PKG_VERSION_MAJOR", &pkg.version().major.to_string()) .env("CARGO_PKG_VERSION_MINOR", &pkg.version().minor.to_string()) .env("CARGO_PKG_VERSION_PATCH", &pkg.version().patch.to_string()) @@ -171,6 +172,7 @@ impl<'cfg> Compilation<'cfg> { .env("CARGO_PKG_HOMEPAGE", metadata.homepage.as_ref().unwrap_or(&String::new())) .env("CARGO_PKG_AUTHORS", &pkg.authors().join(":")) .cwd(pkg.root()); + Ok(cmd) } } diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index ee51b9b3bd0..6a6ae5fb1c7 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -114,9 +114,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) // package's library profile. let profile = cx.lib_profile(); let to_exec = to_exec.into_os_string(); - let mut cmd = cx.compilation.host_process(to_exec, unit.pkg)?; + let mut cmd = cx.compilation.host_process(to_exec, unit.pkg, &cx.ws)?; cmd.env("OUT_DIR", &build_output) - .env("CARGO_MANIFEST_DIR", unit.pkg.root()) .env("NUM_JOBS", &cx.jobs().to_string()) .env("TARGET", &match unit.kind { Kind::Host => cx.host_triple(), diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index bc0c812ca20..9ac47e9c6d9 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -641,7 +641,7 @@ fn filter_dynamic_search_path<'a, I>(paths :I, root_output: &PathBuf) -> Vec(cx: &mut Context<'a, 'cfg>, crate_types: &[&str], unit: &Unit<'a>) -> CargoResult { - let mut base = cx.compilation.rustc_process(unit.pkg)?; + let mut base = cx.compilation.rustc_process(unit.pkg, &cx.ws)?; base.inherit_jobserver(&cx.jobserver); build_base_args(cx, &mut base, unit, crate_types); build_deps_args(&mut base, cx, unit)?; @@ -651,7 +651,7 @@ fn prepare_rustc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, fn rustdoc<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult { - let mut rustdoc = cx.compilation.rustdoc_process(unit.pkg)?; + let mut rustdoc = cx.compilation.rustdoc_process(unit.pkg, &cx.ws)?; rustdoc.inherit_jobserver(&cx.jobserver); rustdoc.arg("--crate-name").arg(&unit.target.crate_name()) .cwd(cx.config.cwd()) diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index ad9ea32e327..171f2c39a95 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -22,9 +22,9 @@ pub fn run_tests(ws: &Workspace, } let (test, mut errors) = if options.only_doc { assert!(options.compile_opts.filter.is_specific()); - run_doc_tests(options, test_args, &compilation)? + run_doc_tests(options, test_args, &compilation, ws)? } else { - run_unit_tests(options, test_args, &compilation)? + run_unit_tests(options, test_args, &compilation, ws)? }; // If we have an error and want to fail fast, return @@ -41,7 +41,7 @@ pub fn run_tests(ws: &Workspace, } } - let (doctest, docerrors) = run_doc_tests(options, test_args, &compilation)?; + let (doctest, docerrors) = run_doc_tests(options, test_args, &compilation, ws)?; let test = if docerrors.is_empty() { test } else { doctest }; errors.extend(docerrors); if errors.is_empty() { @@ -61,7 +61,7 @@ pub fn run_benches(ws: &Workspace, if options.no_run { return Ok(None) } - let (test, errors) = run_unit_tests(options, &args, &compilation)?; + let (test, errors) = run_unit_tests(options, &args, &compilation, ws)?; match errors.len() { 0 => Ok(None), _ => Ok(Some(CargoTestError::new(test, errors))), @@ -81,7 +81,8 @@ fn compile_tests<'a>(ws: &Workspace<'a>, /// Run the unit and integration tests of a project. fn run_unit_tests(options: &TestOptions, test_args: &[String], - compilation: &Compilation) + compilation: &Compilation, + ws: &Workspace) -> CargoResult<(Test, Vec)> { let config = options.compile_opts.config; let cwd = options.compile_opts.config.cwd(); @@ -93,7 +94,7 @@ fn run_unit_tests(options: &TestOptions, Some(path) => path, None => &**exe, }; - let mut cmd = compilation.target_process(exe, pkg)?; + let mut cmd = compilation.target_process(exe, pkg, ws)?; cmd.args(test_args); config.shell().concise(|shell| { shell.status("Running", to_display.display().to_string()) @@ -129,7 +130,8 @@ fn run_unit_tests(options: &TestOptions, fn run_doc_tests(options: &TestOptions, test_args: &[String], - compilation: &Compilation) + compilation: &Compilation, + ws: &Workspace) -> CargoResult<(Test, Vec)> { let mut errors = Vec::new(); let config = options.compile_opts.config; @@ -147,7 +149,7 @@ fn run_doc_tests(options: &TestOptions, for (package, tests) in libs { for (lib, name, crate_name) in tests { config.shell().status("Doc-tests", name)?; - let mut p = compilation.rustdoc_process(package)?; + let mut p = compilation.rustdoc_process(package, ws)?; p.arg("--test").arg(lib) .arg("--crate-name").arg(&crate_name); diff --git a/tests/build-script.rs b/tests/build-script.rs index 3644235a3e6..8f520c9d927 100644 --- a/tests/build-script.rs +++ b/tests/build-script.rs @@ -85,6 +85,7 @@ fn custom_build_env_vars() { let _target = env::var("TARGET").unwrap(); let _ncpus = env::var("NUM_JOBS").unwrap(); let _dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let _ws_dir = env::var("CARGO_WORKSPACE_DIR").unwrap(); let opt = env::var("OPT_LEVEL").unwrap(); assert_eq!(opt, "0"); diff --git a/tests/build.rs b/tests/build.rs index 523e42d9130..fdc6cdf15ef 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -925,14 +925,15 @@ fn crate_env_vars() { static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE"); static VERSION: &'static str = env!("CARGO_PKG_VERSION"); static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR"); + static CARGO_WORKSPACE_DIR: &'static str = env!("CARGO_WORKSPACE_DIR"); static PKG_NAME: &'static str = env!("CARGO_PKG_NAME"); static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE"); static DESCRIPTION: &'static str = env!("CARGO_PKG_DESCRIPTION"); fn main() { - let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR, + let s = format!("{}-{}-{} @ {} in {} ({})", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_PRE, - CARGO_MANIFEST_DIR); + CARGO_MANIFEST_DIR, CARGO_WORKSPACE_DIR); assert_eq!(s, foo::version()); println!("{}", s); assert_eq!("foo", PKG_NAME); @@ -945,12 +946,13 @@ fn crate_env_vars() { "#) .file("src/lib.rs", r#" pub fn version() -> String { - format!("{}-{}-{} @ {} in {}", + format!("{}-{}-{} @ {} in {} ({})", env!("CARGO_PKG_VERSION_MAJOR"), env!("CARGO_PKG_VERSION_MINOR"), env!("CARGO_PKG_VERSION_PATCH"), env!("CARGO_PKG_VERSION_PRE"), - env!("CARGO_MANIFEST_DIR")) + env!("CARGO_MANIFEST_DIR"), + env!("CARGO_WORKSPACE_DIR")) } "#) .build(); @@ -960,8 +962,8 @@ fn crate_env_vars() { println!("bin"); assert_that(process(&p.bin("foo")), - execs().with_status(0).with_stdout(&format!("0-5-1 @ alpha.1 in {}\n", - p.root().display()))); + execs().with_status(0).with_stdout(&format!("0-5-1 @ alpha.1 in {} ({})\n", + p.root().display(), p.root().display()))); println!("test"); assert_that(p.cargo("test").arg("-v"),