From 6cce6f606aae1d1cbd46fa0ddc7cfa2edfc39746 Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Wed, 3 Jul 2019 17:38:26 +0200 Subject: [PATCH 1/3] Test that cargo rebuilds if symlink changed target --- tests/testsuite/build.rs | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index e1fae224237..2bd36af1c9e 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -4703,3 +4703,58 @@ d ) .run(); } + +#[cargo_test] +#[cfg(not(target_os = "windows"))] +fn symlink_rebuild() { + + // Create a crate foo that depends on one crate: a. + // After the initial build we swap the 'a' directory for a symlink to 'b'. + // Since the underlying crate changed, cargo should perform a rebuild. + let project = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + [dependencies] + a = { path = "a" } + "#, + ) + .file("src/main.rs", "fn main(){}") + .file("a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + "#, + ) + .file("a/src/lib.rs", "") + .file("b/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + "#, + ) + .file("b/src/lib.rs", "pub fn not_a(){}"); + + let foo = project + .build(); + + foo.cargo("build -p foo") + .with_status(0) + .with_stderr_contains("[..] Compiling a v0.1.0 [..]") + .run(); + + let root = foo.root(); + + fs::remove_dir_all(root.join("a")).unwrap(); + std::os::unix::fs::symlink(root.join("b"), root.join("a")).unwrap(); + + foo.cargo("build -p foo") + .with_status(0) + .with_stderr_contains("[..] Compiling a v0.1.0 [..]") + .run(); +} From 854f8757a4094fd77f9ad3a94cb0840e36f6fb6c Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Fri, 28 Jun 2019 15:34:08 +0200 Subject: [PATCH 2/3] Canonicalize path_args src --- src/cargo/core/compiler/mod.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 628ac8bbff8..5c8728d683b 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -688,6 +688,7 @@ fn path_args(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>) -> (PathBuf, PathBuf) TargetSourcePath::Metabuild => unit.pkg.manifest().metabuild_path(bcx.ws.target_dir()), }; assert!(src.is_absolute()); + let src = canonicalize_path_arg(&src).unwrap_or(src); if unit.pkg.package_id().source_id().is_path() { if let Ok(path) = src.strip_prefix(ws_root) { return (path.to_path_buf(), ws_root.to_path_buf()); @@ -696,6 +697,19 @@ fn path_args(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>) -> (PathBuf, PathBuf) (src, unit.pkg.root().to_path_buf()) } +#[cfg(windows)] +// On Windows cargo cannot read back the canonicalized paths. The paths are +// canonicalized to resolve symlinks, which aren't as ordinary on Windows as +// they are on other platforms, so we simply skip this. +pub fn canonicalize_path_arg>(path: P) -> CargoResult { + Ok(path.as_ref().to_path_buf()) +} + +#[cfg(not(windows))] +pub fn canonicalize_path_arg>(path: P) -> CargoResult { + Ok(fs::canonicalize(path)?) +} + fn add_path_args(bcx: &BuildContext<'_, '_>, unit: &Unit<'_>, cmd: &mut ProcessBuilder) { let (arg, cwd) = path_args(bcx, unit); cmd.arg(arg); From 979904e092b39bb6aafe62a3ff3d994d3d8b6247 Mon Sep 17 00:00:00 2001 From: Nicolas Mattia Date: Thu, 4 Jul 2019 12:50:40 +0200 Subject: [PATCH 3/3] Fix formatting --- tests/testsuite/build.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 2bd36af1c9e..8f1c6891111 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -4707,7 +4707,6 @@ d #[cargo_test] #[cfg(not(target_os = "windows"))] fn symlink_rebuild() { - // Create a crate foo that depends on one crate: a. // After the initial build we swap the 'a' directory for a symlink to 'b'. // Since the underlying crate changed, cargo should perform a rebuild. @@ -4723,25 +4722,26 @@ fn symlink_rebuild() { "#, ) .file("src/main.rs", "fn main(){}") - .file("a/Cargo.toml", - r#" - [package] - name = "a" - version = "0.1.0" - "#, - ) + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + "#, + ) .file("a/src/lib.rs", "") - .file("b/Cargo.toml", - r#" - [package] - name = "a" - version = "0.1.0" - "#, - ) + .file( + "b/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + "#, + ) .file("b/src/lib.rs", "pub fn not_a(){}"); - let foo = project - .build(); + let foo = project.build(); foo.cargo("build -p foo") .with_status(0)