diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 88c8c933a..21cb053d1 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -73,7 +73,7 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> { try!(cx.probe_target_info(&units)); for unit in units.iter() { - let layout = cx.layout(&unit.pkg, unit.kind); + let layout = cx.layout(unit); try!(rm_rf(&layout.proxy().fingerprint(&unit.pkg))); try!(rm_rf(&layout.build(&unit.pkg))); diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 4df862ffd..fb9acab30 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -96,7 +96,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Prepare this context, ensuring that all filesystem directories are in /// place. - pub fn prepare(&mut self, root: &Package) -> CargoResult<()> { + pub fn prepare(&mut self) -> CargoResult<()> { let _p = profile::start("preparing layout"); try!(self.host.prepare().chain_error(|| { @@ -111,10 +111,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { None => {} } - self.compilation.root_output = - self.layout(root, Kind::Target).proxy().dest().to_path_buf(); - self.compilation.deps_output = - self.layout(root, Kind::Target).proxy().deps().to_path_buf(); + let layout = self.target.as_ref().unwrap_or(&self.host); + self.compilation.root_output = layout.dest().to_path_buf(); + self.compilation.deps_output = layout.deps().to_path_buf(); Ok(()) } @@ -237,9 +236,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } /// Returns the appropriate directory layout for either a plugin or not. - pub fn layout(&self, pkg: &Package, kind: Kind) -> LayoutProxy { - let primary = pkg.package_id() == self.resolve.root(); - match kind { + pub fn layout(&self, unit: &Unit) -> LayoutProxy { + let primary = unit.pkg.package_id() == self.resolve.root(); + match unit.kind { Kind::Host => LayoutProxy::new(&self.host, primary), Kind::Target => LayoutProxy::new(self.target.as_ref() .unwrap_or(&self.host), @@ -247,13 +246,18 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } } + /// Returns the path for plugin/dylib dependencies + pub fn host_dylib_path(&self) -> &Path { + self.host.deps() + } + /// Returns the appropriate output directory for the specified package and /// target. pub fn out_dir(&self, unit: &Unit) -> PathBuf { if unit.profile.doc { - self.layout(unit.pkg, unit.kind).doc_root() + self.layout(unit).doc_root() } else { - self.layout(unit.pkg, unit.kind).out_dir(unit.pkg, unit.target) + self.layout(unit).out_dir(unit) } } @@ -289,7 +293,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { let mut metadata = unit.pkg.generate_metadata(); metadata.mix(&format!("bin-{}", unit.target.name())); Some(metadata) - } else if unit.pkg.package_id() == self.resolve.root() && + } else if unit.pkg.package_id().source_id().is_path() && !unit.profile.test { // If we're not building a unit test then the root package never // needs any metadata as it's guaranteed to not conflict with any diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 071c7079d..e2ea45226 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -87,9 +87,10 @@ pub fn prepare<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) -> CargoResult<(Work, Work)> { + let host_unit = Unit { kind: Kind::Host, ..*unit }; let (script_output, build_output) = { - (cx.layout(unit.pkg, Kind::Host).build(unit.pkg), - cx.layout(unit.pkg, unit.kind).build_out(unit.pkg)) + (cx.layout(&host_unit).build(unit.pkg), + cx.layout(unit).build_out(unit.pkg)) }; // Building the command to execute @@ -161,8 +162,8 @@ fn build_work<'a, 'cfg>(cx: &mut Context<'a, 'cfg>, unit: &Unit<'a>) }; cx.build_explicit_deps.insert(*unit, (output_file.clone(), rerun_if_changed)); - try!(fs::create_dir_all(&cx.layout(unit.pkg, Kind::Host).build(unit.pkg))); - try!(fs::create_dir_all(&cx.layout(unit.pkg, unit.kind).build(unit.pkg))); + try!(fs::create_dir_all(&cx.layout(&host_unit).build(unit.pkg))); + try!(fs::create_dir_all(&cx.layout(unit).build(unit.pkg))); // Prepare the unit of "dirty work" which will actually run the custom build // command. diff --git a/src/cargo/ops/cargo_rustc/fingerprint.rs b/src/cargo/ops/cargo_rustc/fingerprint.rs index 60ff14c2b..e8ad1880f 100644 --- a/src/cargo/ops/cargo_rustc/fingerprint.rs +++ b/src/cargo/ops/cargo_rustc/fingerprint.rs @@ -497,7 +497,7 @@ pub fn prepare_init(cx: &mut Context, unit: &Unit) -> CargoResult<()> { /// Return the (old, new) location for fingerprints for a package pub fn dir(cx: &Context, unit: &Unit) -> PathBuf { - cx.layout(unit.pkg, unit.kind).proxy().fingerprint(unit.pkg) + cx.layout(unit).proxy().fingerprint(unit.pkg) } /// Returns the (old, new) location for the dep info file of a target. diff --git a/src/cargo/ops/cargo_rustc/layout.rs b/src/cargo/ops/cargo_rustc/layout.rs index 67c2341fa..f96ce5715 100644 --- a/src/cargo/ops/cargo_rustc/layout.rs +++ b/src/cargo/ops/cargo_rustc/layout.rs @@ -49,9 +49,10 @@ use std::fs; use std::io; use std::path::{PathBuf, Path}; -use core::{Package, Target, Workspace}; +use core::{Package, Workspace}; use util::{Config, FileLock, CargoResult, Filesystem}; use util::hex::short_hash; +use super::Unit; pub struct Layout { root: PathBuf, @@ -165,11 +166,13 @@ impl<'a> LayoutProxy<'a> { pub fn proxy(&self) -> &'a Layout { self.root } - pub fn out_dir(&self, pkg: &Package, target: &Target) -> PathBuf { - if target.is_custom_build() { - self.build(pkg) - } else if target.is_example() { + pub fn out_dir(&self, unit: &Unit) -> PathBuf { + if unit.target.is_custom_build() { + self.build(unit.pkg) + } else if unit.target.is_example() { self.examples().to_path_buf() + } else if unit.target.is_lib() { + self.deps().to_path_buf() } else { self.root().to_path_buf() } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 2342352c5..bffb0b63f 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -87,7 +87,7 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, let mut queue = JobQueue::new(&cx); - try!(cx.prepare(root)); + try!(cx.prepare()); try!(cx.probe_target_info(&units)); try!(custom_build::build_map(&mut cx, &units)); @@ -104,7 +104,7 @@ pub fn compile_targets<'a, 'cfg: 'a>(ws: &Workspace<'cfg>, try!(queue.execute(&mut cx)); for unit in units.iter() { - let out_dir = cx.layout(unit.pkg, unit.kind).build_out(unit.pkg) + let out_dir = cx.layout(unit).build_out(unit.pkg) .display().to_string(); cx.compilation.extra_env.entry(unit.pkg.package_id().clone()) .or_insert(Vec::new()) @@ -228,6 +228,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult { let do_rename = unit.target.allows_underscores() && !unit.profile.test; let real_name = unit.target.name().to_string(); let crate_name = unit.target.crate_name(); + let move_outputs_up = unit.pkg.package_id() == cx.resolve.root(); let rustc_dep_info_loc = if do_rename { root.join(&crate_name) @@ -271,7 +272,7 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult { let src = dst.with_file_name(dst.file_name().unwrap() .to_str().unwrap() .replace(&real_name, &crate_name)); - if !has_custom_args || fs::metadata(&src).is_ok() { + if !has_custom_args || src.exists() { try!(fs::rename(&src, &dst).chain_error(|| { internal(format!("could not rename crate {:?}", src)) })); @@ -286,6 +287,40 @@ fn rustc(cx: &mut Context, unit: &Unit) -> CargoResult { try!(fingerprint::append_current_dir(&dep_info_loc, &cwd)); } + // If we're a "root crate", e.g. the target of this compilation, then we + // hard link our outputs out of the `deps` directory into the directory + // above. This means that `cargo build` will produce binaries in + // `target/debug` which one probably expects. + if move_outputs_up { + for &(ref filename, _linkable) in filenames.iter() { + let src = root.join(filename); + // This may have been a `cargo rustc` command which changes the + // output, so the source may not actually exist. + if !src.exists() { + continue + } + + // We currently only lift files up from the `deps` directory. If + // it was compiled into something like `example/` or `doc/` then + // we don't want to link it up. + let src_dir = src.parent().unwrap(); + if !src_dir.ends_with("deps") { + continue + } + let dst = src_dir.parent().unwrap() + .join(src.file_name().unwrap()); + if dst.exists() { + try!(fs::remove_file(&dst).chain_error(|| { + human(format!("failed to remove: {}", dst.display())) + })); + } + try!(fs::hard_link(&src, &dst).chain_error(|| { + human(format!("failed to link `{}` to `{}`", + src.display(), dst.display())) + })); + } + } + Ok(()) })); @@ -390,8 +425,7 @@ fn rustdoc(cx: &mut Context, unit: &Unit) -> CargoResult { try!(build_deps_args(&mut rustdoc, cx, unit)); if unit.pkg.has_custom_build() { - rustdoc.env("OUT_DIR", &cx.layout(unit.pkg, unit.kind) - .build_out(unit.pkg)); + rustdoc.env("OUT_DIR", &cx.layout(unit).build_out(unit.pkg)); } rustdoc.args(&try!(cx.rustdocflags_args(unit))); @@ -552,12 +586,7 @@ fn build_plugin_args(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) { fn build_deps_args(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) -> CargoResult<()> { - let layout = cx.layout(unit.pkg, unit.kind); - cmd.arg("-L").arg(&{ - let mut root = OsString::from("dependency="); - root.push(layout.root()); - root - }); + let layout = cx.layout(unit); cmd.arg("-L").arg(&{ let mut deps = OsString::from("dependency="); deps.push(layout.deps()); @@ -569,7 +598,7 @@ fn build_deps_args(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) } for unit in try!(cx.dep_targets(unit)).iter() { - if unit.target.linkable() { + if unit.target.linkable() && !unit.profile.doc { try!(link_to(cmd, cx, unit)); } } @@ -578,8 +607,6 @@ fn build_deps_args(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) fn link_to(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) -> CargoResult<()> { - let layout = cx.layout(unit.pkg, unit.kind); - for (filename, linkable) in try!(cx.target_filenames(unit)) { if !linkable { continue @@ -587,7 +614,7 @@ fn build_deps_args(cmd: &mut CommandPrototype, cx: &Context, unit: &Unit) let mut v = OsString::new(); v.push(&unit.target.crate_name()); v.push("="); - v.push(layout.root()); + v.push(cx.out_dir(unit)); v.push(&path::MAIN_SEPARATOR.to_string()); v.push(&filename); cmd.arg("--extern").arg(&v); @@ -600,9 +627,8 @@ pub fn process(cmd: CommandType, pkg: &Package, cx: &Context) -> CargoResult { // When invoking a tool, we need the *host* deps directory in the dynamic // library search path for plugins and such which have dynamic dependencies. - let layout = cx.layout(pkg, Kind::Host); let mut search_path = util::dylib_path(); - search_path.push(layout.deps().to_path_buf()); + search_path.push(cx.host_dylib_path().to_path_buf()); // We want to use the same environment and such as normal processes, but we // want to override the dylib search path with the one we just calculated. diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 52365c6e6..44a51be30 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -134,7 +134,7 @@ fn run_doc_tests(options: &TestOptions, p.arg("--test").arg(lib) .arg("--crate-name").arg(&crate_name); - for &rust_dep in &[&compilation.deps_output, &compilation.root_output] { + for &rust_dep in &[&compilation.deps_output] { let mut arg = OsString::from("dependency="); arg.push(rust_dep); p.arg("-L").arg(arg); diff --git a/tests/build-lib.rs b/tests/build-lib.rs index f2b42aea7..3d8a44108 100644 --- a/tests/build-lib.rs +++ b/tests/build-lib.rs @@ -10,9 +10,8 @@ fn verbose_output_for_lib(p: &ProjectBuilder) -> String { format!("\ [COMPILING] {name} v{version} ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, diff --git a/tests/build-script.rs b/tests/build-script.rs index b599f452c..3cc250af3 100644 --- a/tests/build-script.rs +++ b/tests/build-script.rs @@ -766,19 +766,17 @@ fn build_cmd_with_a_build_cmd() { [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=-[..] \ --out-dir [..]target[..]deps --emit=dep-info,link \ - -L [..]target[..]deps -L [..]target[..]deps` + -L [..]target[..]deps` [COMPILING] foo v0.5.0 (file://[..]) [RUNNING] `rustc build.rs --crate-name build_script_build --crate-type bin \ - -g \ - --out-dir [..]build[..]foo-[..] --emit=dep-info,link \ - -L [..]target[..]debug -L [..]target[..]deps \ - --extern a=[..]liba-[..].rlib` + -g --out-dir [..] --emit=dep-info,link \ + -L [..]target[..]deps \ + --extern a=[..]liba[..].rlib` [RUNNING] `[..]foo-[..]build-script-build[..]` [RUNNING] `rustc [..]lib.rs --crate-name foo --crate-type lib -g \ - --out-dir [..]target[..]debug --emit=dep-info,link \ - -L [..]target[..]debug -L [..]target[..]deps` + --out-dir [..] --emit=dep-info,link \ + -L [..]target[..]deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ")); } @@ -1175,7 +1173,7 @@ fn build_script_with_dynamic_native_dependency() { fn main() { let src = PathBuf::from(env::var("SRC").unwrap()); - println!("cargo:rustc-link-search={}/target/debug", + println!("cargo:rustc-link-search={}/target/debug/deps", src.display()); } "#) diff --git a/tests/build.rs b/tests/build.rs index c45d50660..aa3ec6e66 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -1026,7 +1026,6 @@ fn lto_build() { -C lto \ --out-dir {dir}[..]target[..]release \ --emit=dep-info,link \ - -L dependency={dir}[..]target[..]release \ -L dependency={dir}[..]target[..]release[..]deps` [FINISHED] release [optimized] target(s) in [..] ", @@ -1051,9 +1050,8 @@ fn verbose_build() { execs().with_status(0).with_stderr(&format!("\ [COMPILING] test v0.0.0 ({url}) [RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib -g \ - --out-dir {dir}[..]target[..]debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}[..]target[..]debug \ -L dependency={dir}[..]target[..]debug[..]deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", @@ -1079,9 +1077,8 @@ fn verbose_release_build() { [COMPILING] test v0.0.0 ({url}) [RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \ -C opt-level=3 \ - --out-dir {dir}[..]target[..]release \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}[..]target[..]release \ -L dependency={dir}[..]target[..]release[..]deps` [FINISHED] release [optimized] target(s) in [..] ", @@ -1123,22 +1120,18 @@ fn verbose_release_build_deps() { [RUNNING] `rustc foo[..]src[..]lib.rs --crate-name foo \ --crate-type dylib --crate-type rlib -C prefer-dynamic \ -C opt-level=3 \ - -C metadata=[..] \ - -C extra-filename=-[..] \ - --out-dir {dir}[..]target[..]release[..]deps \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}[..]target[..]release[..]deps \ -L dependency={dir}[..]target[..]release[..]deps` [COMPILING] test v0.0.0 ({url}) [RUNNING] `rustc src[..]lib.rs --crate-name test --crate-type lib \ -C opt-level=3 \ - --out-dir {dir}[..]target[..]release \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}[..]target[..]release \ -L dependency={dir}[..]target[..]release[..]deps \ --extern foo={dir}[..]target[..]release[..]deps[..]\ - {prefix}foo-[..]{suffix} \ - --extern foo={dir}[..]target[..]release[..]deps[..]libfoo-[..].rlib` + {prefix}foo{suffix} \ + --extern foo={dir}[..]target[..]release[..]deps[..]libfoo.rlib` [FINISHED] release [optimized] target(s) in [..] ", dir = p.root().display(), @@ -1783,14 +1776,14 @@ fn compile_then_delete() { "#) .file("src/main.rs", "fn main() {}"); - assert_that(p.cargo_process("run"), execs().with_status(0)); + assert_that(p.cargo_process("run").arg("-v"), execs().with_status(0)); assert_that(&p.bin("foo"), existing_file()); if cfg!(windows) { // On windows unlinking immediately after running often fails, so sleep sleep_ms(100); } fs::remove_file(&p.bin("foo")).unwrap(); - assert_that(p.cargo("run"), + assert_that(p.cargo("run").arg("-v"), execs().with_status(0)); } @@ -2243,11 +2236,7 @@ fn explicit_color_config_is_propagated_to_rustc() { assert_that(p.cargo_process("build").arg("-v").arg("--color").arg("never"), execs().with_status(0).with_stderr("\ [COMPILING] test v0.0.0 ([..]) -[RUNNING] `rustc src[..]lib.rs --color never --crate-name test --crate-type lib -g \ - --out-dir [..]target[..]debug \ - --emit=dep-info,link \ - -L dependency=[..]target[..]debug \ - -L dependency=[..]target[..]debug[..]deps` +[RUNNING] `rustc [..] --color never [..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ")); } diff --git a/tests/cargo_alias_config.rs b/tests/cargo_alias_config.rs index 52352bcce..c026382e4 100644 --- a/tests/cargo_alias_config.rs +++ b/tests/cargo_alias_config.rs @@ -56,8 +56,7 @@ fn alias_config() { execs().with_status(0). with_stderr_contains("[COMPILING] foo v0.5.0 [..] [RUNNING] `rustc [..] --crate-name foo --crate-type \ -bin -g --out-dir [..] --emit=dep-info,link -L dependency=[..]\ --L dependency=[..]")); +bin -g --out-dir [..] --emit=dep-info,link -L dependency=[..]")); } #[test] diff --git a/tests/cross-compile.rs b/tests/cross-compile.rs index f078bbd94..55371af3a 100644 --- a/tests/cross-compile.rs +++ b/tests/cross-compile.rs @@ -362,7 +362,6 @@ fn linker_and_ar() { --emit=dep-info,link \ --target {target} \ -C ar=my-ar-tool -C linker=my-linker-tool \ - -L dependency={dir}[..]target[..]{target}[..]debug \ -L dependency={dir}[..]target[..]{target}[..]debug[..]deps` ", dir = p.root().display(), diff --git a/tests/plugins.rs b/tests/plugins.rs index 7adffed9e..2da8965da 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -147,7 +147,7 @@ fn plugin_with_dynamic_native_dependency() { fn main() { let src = PathBuf::from(env::var("SRC").unwrap()); - println!("cargo:rustc-flags=-L {}", src.parent().unwrap() + println!("cargo:rustc-flags=-L {}/deps", src.parent().unwrap() .display()); } "#) diff --git a/tests/profiles.rs b/tests/profiles.rs index 3036d6ca0..52fe00197 100644 --- a/tests/profiles.rs +++ b/tests/profiles.rs @@ -31,9 +31,8 @@ fn profile_overrides() { -C opt-level=1 \ -C debug-assertions=on \ -C rpath \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [optimized] target(s) in [..] ", sep = SEP, @@ -84,23 +83,19 @@ fn top_level_overrides_deps() { --crate-type dylib --crate-type rlib -C prefer-dynamic \ -C opt-level=1 \ -g \ - -C metadata=[..] \ - -C extra-filename=-[..] \ --out-dir {dir}{sep}target{sep}release{sep}deps \ --emit=dep-info,link \ - -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 src{sep}lib.rs --crate-name test --crate-type lib \ -C opt-level=1 \ -g \ - --out-dir {dir}{sep}target{sep}release \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}release \ -L dependency={dir}{sep}target{sep}release{sep}deps \ --extern foo={dir}{sep}target{sep}release{sep}deps{sep}\ - {prefix}foo-[..]{suffix} \ - --extern foo={dir}{sep}target{sep}release{sep}deps{sep}libfoo-[..].rlib` + {prefix}foo[..]{suffix} \ + --extern foo={dir}{sep}target{sep}release{sep}deps{sep}libfoo.rlib` [FINISHED] release [optimized + debuginfo] target(s) in [..] ", dir = p.root().display(), diff --git a/tests/run.rs b/tests/run.rs index 9723e7d19..90e195f6e 100644 --- a/tests/run.rs +++ b/tests/run.rs @@ -411,20 +411,16 @@ fn example_with_release_flag() { [COMPILING] bar v0.0.1 ({url}/bar) [RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \ -C opt-level=3 \ - -C metadata=[..] \ - -C extra-filename=[..] \ --out-dir {dir}{sep}target{sep}release{sep}deps \ --emit=dep-info,link \ - -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 examples{sep}a.rs --crate-name a --crate-type bin \ -C opt-level=3 \ --out-dir {dir}{sep}target{sep}release{sep}examples \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}release \ -L dependency={dir}{sep}target{sep}release{sep}deps \ - --extern bar={dir}{sep}target{sep}release{sep}deps{sep}libbar-[..].rlib` + --extern bar={dir}{sep}target{sep}release{sep}deps{sep}libbar.rlib` [FINISHED] release [optimized] target(s) in [..] [RUNNING] `target{sep}release{sep}examples{sep}a[..]` ", @@ -441,20 +437,16 @@ fast2")); [COMPILING] bar v0.0.1 ({url}/bar) [RUNNING] `rustc bar{sep}src{sep}bar.rs --crate-name bar --crate-type lib \ -g \ - -C metadata=[..] \ - -C extra-filename=[..] \ --out-dir {dir}{sep}target{sep}debug{sep}deps \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug{sep}deps \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [COMPILING] foo v0.0.1 ({url}) [RUNNING] `rustc examples{sep}a.rs --crate-name a --crate-type bin \ -g \ --out-dir {dir}{sep}target{sep}debug{sep}examples \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps \ - --extern bar={dir}{sep}target{sep}debug{sep}deps{sep}libbar-[..].rlib` + --extern bar={dir}{sep}target{sep}debug{sep}deps{sep}libbar.rlib` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] [RUNNING] `target{sep}debug{sep}examples{sep}a[..]` ", diff --git a/tests/rustc.rs b/tests/rustc.rs index 7255c4e00..79e49fdab 100644 --- a/tests/rustc.rs +++ b/tests/rustc.rs @@ -30,9 +30,8 @@ fn build_lib_for_foo() { .with_stderr(format!("\ [COMPILING] foo v0.0.1 ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, @@ -61,9 +60,8 @@ fn lib() { [COMPILING] foo v0.0.1 ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \ -C debug-assertions=off \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, @@ -91,17 +89,15 @@ fn build_main_and_allow_unstable_options() { .with_stderr(&format!("\ [COMPILING] {name} v{version} ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name {name} --crate-type lib -g \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [RUNNING] `rustc src{sep}main.rs --crate-name {name} --crate-type bin -g \ -C debug-assertions \ - --out-dir {dir}{sep}target{sep}debug \ + --out-dir [..] \ --emit=dep-info,link \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps \ - --extern {name}={dir}{sep}target{sep}debug{sep}lib{name}.rlib` + --extern {name}={dir}{sep}target[..]lib{name}.rlib` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, dir = p.root().display(), url = p.url(), @@ -156,12 +152,11 @@ fn build_with_args_to_one_of_multiple_binaries() { .with_stderr(format!("\ [COMPILING] foo v0.0.1 ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \ - --out-dir {dir}{sep}target{sep}debug [..]` + --out-dir [..]` [RUNNING] `rustc src{sep}bin{sep}bar.rs --crate-name bar --crate-type bin -g \ -C debug-assertions [..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] -", sep = SEP, - dir = p.root().display(), url = p.url()))); +", sep = SEP, url = p.url()))); } #[test] @@ -212,12 +207,11 @@ fn build_with_args_to_one_of_multiple_tests() { .with_stderr(format!("\ [COMPILING] foo v0.0.1 ({url}) [RUNNING] `rustc src{sep}lib.rs --crate-name foo --crate-type lib -g \ - --out-dir {dir}{sep}target{sep}debug [..]` + --out-dir [..]` [RUNNING] `rustc tests{sep}bar.rs --crate-name bar -g \ -C debug-assertions [..]--test[..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] -", sep = SEP, - dir = p.root().display(), url = p.url()))); +", sep = SEP, url = p.url()))); } #[test] @@ -255,7 +249,7 @@ fn build_foo_with_bar_dependency() { .with_status(0) .with_stderr(format!("\ [COMPILING] bar v0.1.0 ([..]) -[RUNNING] `[..] -g -C [..]` +[RUNNING] `[..] -g [..]` [COMPILING] foo v0.0.1 ({url}) [RUNNING] `[..] -g -C debug-assertions [..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] diff --git a/tests/rustdoc.rs b/tests/rustdoc.rs index de4bd8d57..da1336f05 100644 --- a/tests/rustdoc.rs +++ b/tests/rustdoc.rs @@ -24,7 +24,6 @@ fn rustdoc_simple() { [DOCUMENTING] foo v0.0.1 ({url}) [RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \ -o {dir}{sep}target{sep}doc \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, @@ -50,7 +49,6 @@ fn rustdoc_args() { [RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \ -o {dir}{sep}target{sep}doc \ --no-defaults \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, @@ -97,7 +95,6 @@ fn rustdoc_foo_with_bar_dependency() { [RUNNING] `rustdoc src{sep}lib.rs --crate-name foo \ -o {dir}{sep}target{sep}doc \ --no-defaults \ - -L dependency={dir}{sep}target{sep}debug \ -L dependency={dir}{sep}target{sep}debug{sep}deps \ --extern [..]` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] @@ -144,7 +141,6 @@ fn rustdoc_only_bar_dependency() { [RUNNING] `rustdoc [..]bar{sep}src{sep}lib.rs --crate-name bar \ -o {dir}{sep}target{sep}doc \ --no-defaults \ - -L dependency={dir}{sep}target{sep}debug{sep}deps \ -L dependency={dir}{sep}target{sep}debug{sep}deps` [FINISHED] debug [unoptimized + debuginfo] target(s) in [..] ", sep = SEP, diff --git a/tests/workspaces.rs b/tests/workspaces.rs index c482940c5..b17b56526 100644 --- a/tests/workspaces.rs +++ b/tests/workspaces.rs @@ -2,7 +2,7 @@ extern crate cargotest; extern crate hamcrest; -use std::io::Read; +use std::io::{Read, Write}; use std::fs::File; use cargotest::support::{project, execs}; @@ -827,3 +827,49 @@ fn lock_doesnt_change_depending_on_crate() { assert_eq!(lockfile, lockfile2); } + +#[test] +fn rebuild_please() { + let p = project("foo") + .file("Cargo.toml", r#" + [workspace] + members = ['lib', 'bin'] + "#) + .file("lib/Cargo.toml", r#" + [package] + name = "lib" + version = "0.1.0" + "#) + .file("lib/src/lib.rs", r#" + pub fn foo() -> u32 { 0 } + "#) + .file("bin/Cargo.toml", r#" + [package] + name = "bin" + version = "0.1.0" + + [dependencies] + lib = { path = "../lib" } + "#) + .file("bin/src/main.rs", r#" + extern crate lib; + + fn main() { + assert_eq!(lib::foo(), 0); + } + "#); + p.build(); + + assert_that(p.cargo("run").cwd(p.root().join("bin")), + execs().with_status(0)); + + t!(t!(File::create(p.root().join("lib/src/lib.rs"))).write_all(br#" + pub fn foo() -> u32 { 1 } + "#)); + + assert_that(p.cargo("build").cwd(p.root().join("lib")), + execs().with_status(0)); + + assert_that(p.cargo("run").cwd(p.root().join("bin")), + execs().with_status(101)); +}