diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 1b4843f9031..41dca8dbd72 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -1,5 +1,6 @@ -use std::collections::hash_map::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; +use std::collections::hash_map::HashMap; +use std::os; use std::str; use std::sync::Arc; @@ -29,6 +30,7 @@ pub struct Context<'a, 'b: 'a> { pub compilation: Compilation, pub build_state: Arc, pub exec_engine: Arc>, + pub cwd: Path, env: &'a str, host: Layout, @@ -60,6 +62,9 @@ impl<'a, 'b: 'a> Context<'a, 'b> { }; let target_triple = config.target().map(|s| s.to_string()); let target_triple = target_triple.unwrap_or(config.rustc_host().to_string()); + let cwd = try!(os::getcwd().chain_error(|| { + human("failed to get the current directory") + })); Ok(Context { target_triple: target_triple, env: env, @@ -78,6 +83,7 @@ impl<'a, 'b: 'a> Context<'a, 'b> { build_state: Arc::new(BuildState::new(build_config.clone(), deps)), build_config: build_config, exec_engine: Arc::new(Box::new(ProcessEngine) as Box), + cwd: cwd, }) } diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index d93b2540e4a..a707679658f 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -63,7 +63,7 @@ pub fn prepare_target(cx: &mut Context, pkg: &Package, target: &Target, // indicates that the target is fresh. let dep_info = dep_info_loc(cx, pkg, target, kind); let mut are_files_fresh = use_pkg || - try!(calculate_target_fresh(pkg, &dep_info)); + try!(calculate_target_fresh(&dep_info)); // Second bit of the freshness calculation, whether rustc itself, the // target are fresh, and the enabled set of features are all fresh. @@ -226,8 +226,15 @@ fn mk_fingerprint>(cx: &Context, data: &T) -> String { util::to_hex(hasher.finish()) } -fn calculate_target_fresh(pkg: &Package, dep_info: &Path) -> CargoResult { - let line = match BufferedReader::new(File::open(dep_info)).lines().next() { +fn calculate_target_fresh(dep_info: &Path) -> CargoResult { + macro_rules! fs_try { + ($e:expr) => (match $e { Ok(e) => e, Err(..) => return Ok(false) }) + } + let mut f = BufferedReader::new(fs_try!(File::open(dep_info))); + // see comments in append_current_dir for where this cwd is manifested from. + let cwd = fs_try!(f.read_until(0)); + let cwd = Path::new(&cwd[..cwd.len()-1]); + let line = match f.lines().next() { Some(Ok(line)) => line, _ => return Ok(false), }; @@ -250,7 +257,7 @@ fn calculate_target_fresh(pkg: &Package, dep_info: &Path) -> CargoResult { file.push(' '); file.push_str(deps.next().unwrap()) } - match fs::stat(&pkg.get_root().join(file.as_slice())) { + match fs::stat(&cwd.join(file.as_slice())) { Ok(stat) if stat.modified <= mtime => {} Ok(stat) => { info!("stale: {} -- {} vs {}", file, stat.modified, mtime); @@ -289,3 +296,18 @@ fn filename(target: &Target) -> String { }; format!("{}{}-{}", flavor, kind, target.get_name()) } + +// The dep-info files emitted by the compiler all have their listed paths +// relative to whatever the current directory was at the time that the compiler +// was invoked. As the current directory may change over time, we need to record +// what that directory was at the beginning of the file so we can know about it +// next time. +pub fn append_current_dir(path: &Path, cwd: &Path) -> CargoResult<()> { + let mut f = try!(File::open_mode(path, io::Open, io::ReadWrite)); + let contents = try!(f.read_to_end()); + try!(f.seek(0, io::SeekSet)); + try!(f.write(cwd.as_vec())); + try!(f.write(&[0])); + try!(f.write(&contents[])); + Ok(()) +} diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 15b16b1d444..c18facd6893 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -489,6 +489,7 @@ fn rustc(package: &Package, target: &Target, let rustc_dep_info_loc = root.join(target.file_stem()).with_extension("d"); let dep_info_loc = fingerprint::dep_info_loc(cx, package, target, kind); + let cwd = cx.cwd.clone(); Ok((Work::new(move |desc_tx| { let mut rustc = rustc; @@ -525,6 +526,7 @@ fn rustc(package: &Package, target: &Target, })); try!(fs::rename(&rustc_dep_info_loc, &dep_info_loc)); + try!(fingerprint::append_current_dir(&dep_info_loc, &cwd)); Ok(()) @@ -559,11 +561,10 @@ fn prepare_rustc(package: &Package, target: &Target, crate_types: Vec<&str>, fn rustdoc(package: &Package, target: &Target, cx: &mut Context) -> CargoResult { let kind = Kind::Target; - let pkg_root = package.get_root(); let cx_root = cx.layout(package, kind).proxy().dest().join("doc"); - let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx)) - .cwd(pkg_root.clone()); - let mut rustdoc = rustdoc.arg(target.get_src_path()) + let rustdoc = try!(process(CommandType::Rustdoc, package, target, cx)); + let mut rustdoc = rustdoc.arg(root_path(cx, package, target)) + .cwd(cx.cwd.clone()) .arg("-o").arg(cx_root) .arg("--crate-name").arg(target.get_name()); @@ -614,6 +615,20 @@ fn rustdoc(package: &Package, target: &Target, })) } +// The path that we pass to rustc is actually fairly important because it will +// show up in error messages and the like. For this reason we take a few moments +// to ensure that something shows up pretty reasonably. +// +// The heuristic here is fairly simple, but the key idea is that the path is +// always "relative" to the current directory in order to be found easily. The +// path is only actually relative if the current directory is an ancestor if it. +// This means that non-path dependencies (git/registry) will likely be shown as +// absolute paths instead of relative paths. +fn root_path(cx: &Context, pkg: &Package, target: &Target) -> Path { + let absolute = pkg.get_root().join(target.get_src_path()); + absolute.path_relative_from(&cx.cwd).unwrap_or(absolute) +} + fn build_base_args(cx: &Context, mut cmd: CommandPrototype, pkg: &Package, @@ -621,8 +636,11 @@ fn build_base_args(cx: &Context, crate_types: &[&str]) -> CommandPrototype { let metadata = target.get_metadata(); + // Move to cwd so the root_path() passed below is actually correct + cmd = cmd.cwd(cx.cwd.clone()); + // TODO: Handle errors in converting paths into args - cmd = cmd.arg(target.get_src_path()); + cmd = cmd.arg(root_path(cx, pkg, target)); cmd = cmd.arg("--crate-name").arg(target.get_name()); diff --git a/tests/test_cargo_bench.rs b/tests/test_cargo_bench.rs index 55692edb1e1..70c75fdd198 100644 --- a/tests/test_cargo_bench.rs +++ b/tests/test_cargo_bench.rs @@ -840,8 +840,8 @@ test!(bench_with_examples { execs().with_status(0) .with_stdout(format!("\ {compiling} testbench v6.6.6 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name testbench --crate-type lib [..]` -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name testbench --crate-type lib [..]` +{running} `rustc src{sep}lib.rs --crate-name testbench --crate-type lib [..]` +{running} `rustc src{sep}lib.rs --crate-name testbench --crate-type lib [..]` {running} `rustc benches{sep}testb1.rs --crate-name testb1 --crate-type bin \ [..] --test [..]` {running} `{dir}{sep}target{sep}release{sep}testb1-[..] --bench` diff --git a/tests/test_cargo_build_lib.rs b/tests/test_cargo_build_lib.rs index 6da91566935..6b6064a3a4d 100644 --- a/tests/test_cargo_build_lib.rs +++ b/tests/test_cargo_build_lib.rs @@ -9,7 +9,7 @@ fn setup() { fn verbose_output_for_lib(p: &ProjectBuilder) -> String { format!("\ {compiling} {name} v{version} ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name {name} --crate-type lib -g \ +{running} `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \ -C metadata=[..] \ -C extra-filename=-[..] \ --out-dir {dir}{sep}target \ diff --git a/tests/test_cargo_compile.rs b/tests/test_cargo_compile.rs index 32c4d3dd2a4..4dbea701734 100644 --- a/tests/test_cargo_compile.rs +++ b/tests/test_cargo_compile.rs @@ -765,7 +765,7 @@ test!(lto_build { assert_that(p.cargo_process("build").arg("-v").arg("--release"), execs().with_status(0).with_stdout(format!("\ {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}main.rs --crate-name test --crate-type bin \ +{running} `rustc src{sep}main.rs --crate-name test --crate-type bin \ -C opt-level=3 \ -C lto \ --cfg ndebug \ @@ -794,7 +794,7 @@ test!(verbose_build { assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0).with_stdout(format!("\ {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib -g \ +{running} `rustc src{sep}lib.rs --crate-name test --crate-type lib -g \ -C metadata=[..] \ -C extra-filename=-[..] \ --out-dir {dir}{sep}target \ @@ -822,7 +822,7 @@ test!(verbose_release_build { assert_that(p.cargo_process("build").arg("-v").arg("--release"), execs().with_status(0).with_stdout(format!("\ {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib \ +{running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \ -C opt-level=3 \ --cfg ndebug \ -C metadata=[..] \ @@ -867,7 +867,7 @@ test!(verbose_release_build_deps { assert_that(p.cargo_process("build").arg("-v").arg("--release"), execs().with_status(0).with_stdout(format!("\ {compiling} foo v0.0.0 ({url}) -{running} `rustc {dir}{sep}foo{sep}src{sep}lib.rs --crate-name foo \ +{running} `rustc foo{sep}src{sep}lib.rs --crate-name foo \ --crate-type dylib --crate-type rlib -C prefer-dynamic \ -C opt-level=3 \ --cfg ndebug \ @@ -878,7 +878,7 @@ test!(verbose_release_build_deps { -L dependency={dir}{sep}target{sep}release{sep}deps \ -L dependency={dir}{sep}target{sep}release{sep}deps` {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib \ +{running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \ -C opt-level=3 \ --cfg ndebug \ -C metadata=[..] \ diff --git a/tests/test_cargo_compile_custom_build.rs b/tests/test_cargo_compile_custom_build.rs index 2d89dca6a02..32ede9525ae 100644 --- a/tests/test_cargo_compile_custom_build.rs +++ b/tests/test_cargo_compile_custom_build.rs @@ -364,9 +364,9 @@ test!(links_passes_env_vars { execs().with_status(0) .with_stdout(format!("\ {compiling} [..] v0.5.0 (file://[..]) -{running} `rustc build.rs [..]` +{running} `rustc [..]build.rs [..]` {compiling} [..] v0.5.0 (file://[..]) -{running} `rustc build.rs [..]` +{running} `rustc [..]build.rs [..]` {running} `[..]` {running} `[..]` {running} `[..]` @@ -563,7 +563,7 @@ test!(propagation_of_l_flags { execs().with_status(0) .with_stdout(format!("\ {compiling} a v0.5.0 (file://[..]) -{running} `rustc build.rs [..]` +{running} `rustc a[..]build.rs [..]` {compiling} b v0.5.0 (file://[..]) {running} `rustc [..] --crate-name b [..]-L foo[..]` {running} `[..]a-[..]build-script-build[..]` @@ -691,7 +691,7 @@ test!(build_cmd_with_a_build_cmd { {compiling} b v0.5.0 (file://[..]) {running} `rustc [..] --crate-name b [..]` {compiling} a v0.5.0 (file://[..]) -{running} `rustc build.rs [..] --extern b=[..]` +{running} `rustc a[..]build.rs [..] --extern b=[..]` {running} `[..]a-[..]build-script-build[..]` {running} `rustc [..]lib.rs --crate-name a --crate-type lib -g \ -C metadata=[..] -C extra-filename=-[..] \ diff --git a/tests/test_cargo_cross_compile.rs b/tests/test_cargo_cross_compile.rs index 73fb1b39cbf..668a81ab690 100644 --- a/tests/test_cargo_cross_compile.rs +++ b/tests/test_cargo_cross_compile.rs @@ -495,7 +495,7 @@ test!(cross_with_a_build_script { {compiling} foo v0.0.0 (file://[..]) {running} `rustc build.rs [..] --out-dir {dir}{sep}target{sep}build{sep}foo-[..]` {running} `{dir}{sep}target{sep}build{sep}foo-[..]build-script-build` -{running} `rustc {dir}{sep}src{sep}main.rs [..] --target {target} [..]` +{running} `rustc src{sep}main.rs [..] --target {target} [..]` ", compiling = COMPILING, running = RUNNING, target = target, dir = p.root().display(), sep = path::SEP).as_slice())); }); @@ -562,21 +562,21 @@ test!(build_script_needed_for_host_and_target { execs().with_status(0) .with_stdout(format!("\ {compiling} d1 v0.0.0 (file://{dir}) -{running} `rustc build.rs [..] --out-dir {dir}{sep}target{sep}build{sep}d1-[..]` +{running} `rustc d1{sep}build.rs [..] --out-dir {dir}{sep}target{sep}build{sep}d1-[..]` {running} `{dir}{sep}target{sep}build{sep}d1-[..]build-script-build` {running} `{dir}{sep}target{sep}build{sep}d1-[..]build-script-build` -{running} `rustc {dir}{sep}d1{sep}src{sep}lib.rs [..] --target {target} [..] \ +{running} `rustc d1{sep}src{sep}lib.rs [..] --target {target} [..] \ -L /path/to/{target}` -{running} `rustc {dir}{sep}d1{sep}src{sep}lib.rs [..] \ +{running} `rustc d1{sep}src{sep}lib.rs [..] \ -L /path/to/{host}` {compiling} d2 v0.0.0 (file://{dir}) -{running} `rustc {dir}{sep}d2{sep}src{sep}lib.rs [..] \ +{running} `rustc d2{sep}src{sep}lib.rs [..] \ -L /path/to/{host}` {compiling} foo v0.0.0 (file://{dir}) {running} `rustc build.rs [..] --out-dir {dir}{sep}target{sep}build{sep}foo-[..] \ -L /path/to/{host}` {running} `{dir}{sep}target{sep}build{sep}foo-[..]build-script-build` -{running} `rustc {dir}{sep}src{sep}main.rs [..] --target {target} [..] \ +{running} `rustc src{sep}main.rs [..] --target {target} [..] \ -L /path/to/{target}` ", compiling = COMPILING, running = RUNNING, target = target, host = host, dir = p.root().display(), sep = path::SEP).as_slice())); diff --git a/tests/test_cargo_doc.rs b/tests/test_cargo_doc.rs index 2e963802b63..e26f46ebfb9 100644 --- a/tests/test_cargo_doc.rs +++ b/tests/test_cargo_doc.rs @@ -180,7 +180,7 @@ test!(doc_only_bin { pub fn bar() {} "#); - assert_that(p.cargo_process("doc"), + assert_that(p.cargo_process("doc").arg("-v"), execs().with_status(0)); assert_that(&p.root().join("target/doc"), existing_dir()); diff --git a/tests/test_cargo_profiles.rs b/tests/test_cargo_profiles.rs index c4ee0edb37d..e4f0cd67c29 100644 --- a/tests/test_cargo_profiles.rs +++ b/tests/test_cargo_profiles.rs @@ -27,7 +27,7 @@ test!(profile_overrides { assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0).with_stdout(format!("\ {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib \ +{running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \ -C opt-level=1 \ --cfg ndebug \ -C metadata=[..] \ @@ -81,7 +81,7 @@ test!(top_level_overrides_deps { assert_that(p.cargo_process("build").arg("-v").arg("--release"), execs().with_status(0).with_stdout(format!("\ {compiling} foo v0.0.0 ({url}) -{running} `rustc {dir}{sep}foo{sep}src{sep}lib.rs --crate-name foo \ +{running} `rustc foo{sep}src{sep}lib.rs --crate-name foo \ --crate-type dylib --crate-type rlib -C prefer-dynamic \ -C opt-level=1 \ -g \ @@ -92,7 +92,7 @@ test!(top_level_overrides_deps { -L dependency={dir}{sep}target{sep}release{sep}deps \ -L dependency={dir}{sep}target{sep}release{sep}deps` {compiling} test v0.0.0 ({url}) -{running} `rustc {dir}{sep}src{sep}lib.rs --crate-name test --crate-type lib \ +{running} `rustc src{sep}lib.rs --crate-name test --crate-type lib \ -C opt-level=1 \ -g \ -C metadata=[..] \ diff --git a/tests/test_cargo_run.rs b/tests/test_cargo_run.rs index bc727a9e68e..f8077f39564 100644 --- a/tests/test_cargo_run.rs +++ b/tests/test_cargo_run.rs @@ -266,7 +266,7 @@ test!(example_with_release_flag { assert_that(p.cargo_process("run").arg("-v").arg("--release").arg("--example").arg("a"), execs().with_status(0).with_stdout(format!("\ {compiling} bar v0.0.1 ({url}) -{running} `rustc src{sep}bar.rs --crate-name bar --crate-type lib \ +{running} `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \ -C opt-level=3 \ --cfg ndebug \ -C metadata=[..] \ @@ -276,7 +276,7 @@ test!(example_with_release_flag { -L dependency={dir}{sep}target{sep}release{sep}deps \ -L dependency={dir}{sep}target{sep}release{sep}deps` {compiling} foo v0.0.1 ({url}) -{running} `rustc {dir}{sep}examples{sep}a.rs --crate-name a --crate-type bin \ +{running} `rustc examples{sep}a.rs --crate-name a --crate-type bin \ -C opt-level=3 \ --cfg ndebug \ --out-dir {dir}{sep}target{sep}release{sep}examples \ @@ -297,7 +297,7 @@ fast2 assert_that(p.process(cargo_dir().join("cargo")).arg("run").arg("-v").arg("--example").arg("a"), execs().with_status(0).with_stdout(format!("\ {compiling} bar v0.0.1 ({url}) -{running} `rustc src{sep}bar.rs --crate-name bar --crate-type lib \ +{running} `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \ -g \ -C metadata=[..] \ -C extra-filename=[..] \ @@ -306,7 +306,7 @@ fast2 -L dependency={dir}{sep}target{sep}deps \ -L dependency={dir}{sep}target{sep}deps` {compiling} foo v0.0.1 ({url}) -{running} `rustc {dir}{sep}examples{sep}a.rs --crate-name a --crate-type bin \ +{running} `rustc examples{sep}a.rs --crate-name a --crate-type bin \ -g \ --out-dir {dir}{sep}target{sep}examples \ --emit=dep-info,link \