Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dep-info files emitting paths relative to deps' roots #9421

Merged
merged 3 commits into from
Apr 29, 2021
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
3 changes: 3 additions & 0 deletions src/cargo/core/compiler/output_depinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ fn add_deps_for_unit(
if let Some(metadata) = cx.find_build_script_metadata(unit) {
if let Some(output) = cx.build_script_outputs.lock().unwrap().get(metadata) {
for path in &output.rerun_if_changed {
// The paths we have saved from the unit are of arbitrary relativeness and may be
// relative to the crate root of the dependency.
let path = unit.pkg.root().join(path);
deps.insert(path.into());
}
}
Expand Down
114 changes: 113 additions & 1 deletion tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Tests for build.rs scripts.

use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::registry::Package;
use cargo_test_support::{basic_manifest, cross_compile, is_coarse_mtime, project};
use cargo_test_support::{lines_match, paths::CargoPathExt};
use cargo_test_support::{rustc_host, sleep_ms, slow_cpu_multiplier, symlink_supported};
use cargo_util::paths::remove_dir_all;
use std::env;
Expand Down Expand Up @@ -2602,6 +2602,118 @@ fn fresh_builds_possible_with_multiple_metadata_overrides() {
.run();
}

#[cargo_test]
fn generate_good_d_files() {
// this is here to stop regression on an issue where build.rs rerun-if-changed paths aren't
// made absolute properly, which in turn interacts poorly with the dep-info-basedir setting,
// and the dep-info files have other-crate-relative paths spat out in them
let p = project()
.file(
"awoo/Cargo.toml",
r#"
[project]
name = "awoo"
version = "0.5.0"
build = "build.rs"
"#,
)
.file("awoo/src/lib.rs", "")
.file(
"awoo/build.rs",
r#"
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=barkbarkbark");
}
"#,
)
.file(
"Cargo.toml",
r#"
[project]
name = "meow"
version = "0.5.0"
[dependencies]
awoo = { path = "awoo" }
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v").run();

let dot_d_path = p.bin("meow").with_extension("d");
println!("*meow at* {:?}", dot_d_path);
let dot_d = fs::read_to_string(&dot_d_path).unwrap();

println!("*.d file content*: {}", &dot_d);

#[cfg(windows)]
assert!(
lines_match(
"[..]\\target\\debug\\meow.exe: [..]\\awoo\\barkbarkbark [..]\\awoo\\build.rs[..]",
&dot_d
) || lines_match(
"[..]\\target\\debug\\meow.exe: [..]\\awoo\\build.rs [..]\\awoo\\barkbarkbark[..]",
&dot_d
)
);
#[cfg(not(windows))]
assert!(
lines_match(
"[..]/target/debug/meow: [..]/awoo/barkbarkbark [..]/awoo/build.rs[..]",
&dot_d
) || lines_match(
"[..]/target/debug/meow: [..]/awoo/build.rs [..]/awoo/barkbarkbark[..]",
&dot_d
)
);

// paths relative to dependency roots should not be allowed
assert!(!dot_d
.split_whitespace()
.any(|v| v == "barkbarkbark" || v == "build.rs"));

p.change_file(
".cargo/config.toml",
r#"
[build]
dep-info-basedir="."
"#,
);
p.cargo("build -v").run();

let dot_d = fs::read_to_string(&dot_d_path).unwrap();

println!("*.d file content with dep-info-basedir*: {}", &dot_d);

#[cfg(windows)]
assert!(
lines_match(
"target\\debug\\meow.exe: [..]awoo\\barkbarkbark [..]awoo\\build.rs[..]",
&dot_d
) || lines_match(
"target\\debug\\meow.exe: [..]awoo\\build.rs [..]awoo\\barkbarkbark[..]",
&dot_d
)
);
#[cfg(not(windows))]
assert!(
lines_match(
"target/debug/meow: [..]awoo/barkbarkbark [..]awoo/build.rs[..]",
&dot_d
) || lines_match(
"target/debug/meow: [..]awoo/build.rs [..]awoo/barkbarkbark[..]",
&dot_d
)
);

// paths relative to dependency roots should not be allowed
assert!(!dot_d
.split_whitespace()
.any(|v| v == "barkbarkbark" || v == "build.rs"));
}

#[cargo_test]
fn rebuild_only_on_explicit_paths() {
let p = project()
Expand Down