Skip to content

Commit dd41106

Browse files
committed
Auto merge of #8969 - alexcrichton:fix-cycle, r=ehuss
Fix the unit dependency graph with dev-dependency `links` This commit fixes #8966 by updating the unit generation logic to avoid generating an erroneous circular dependency between the execution of two build scripts. This has been present for Cargo in a long time since #5651 (an accidental regression), but the situation appears rare enough that we didn't get to it until now! Closes #8966
2 parents d274fcf + 4761ada commit dd41106

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

src/cargo/core/compiler/unit_dependencies.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,17 @@ fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
630630
// example a library might depend on a build script, so this map will
631631
// have the build script as the key and the library would be in the
632632
// value's set.
633+
//
634+
// Note that as an important part here we're skipping "test" units. Test
635+
// units depend on the execution of a build script, but
636+
// links-dependencies only propagate through `[dependencies]`, nothing
637+
// else. We don't want to pull in a links-dependency through a
638+
// dev-dependency since that could create a cycle.
633639
let mut reverse_deps_map = HashMap::new();
634640
for (unit, deps) in unit_dependencies.iter() {
641+
if unit.mode.is_any_test() {
642+
continue;
643+
}
635644
for dep in deps {
636645
if dep.unit.mode == CompileMode::RunCustomBuild {
637646
reverse_deps_map
@@ -655,15 +664,16 @@ fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
655664
.keys()
656665
.filter(|k| k.mode == CompileMode::RunCustomBuild)
657666
{
658-
// This is the lib that runs this custom build.
667+
// This list of dependencies all depend on `unit`, an execution of
668+
// the build script.
659669
let reverse_deps = match reverse_deps_map.get(unit) {
660670
Some(set) => set,
661671
None => continue,
662672
};
663673

664674
let to_add = reverse_deps
665675
.iter()
666-
// Get all deps for lib.
676+
// Get all sibling dependencies of `unit`
667677
.flat_map(|reverse_dep| unit_dependencies[reverse_dep].iter())
668678
// Only deps with `links`.
669679
.filter(|other| {

tests/testsuite/build_script.rs

+37
Original file line numberDiff line numberDiff line change
@@ -4034,3 +4034,40 @@ Caused by:
40344034
// Restore permissions so that the directory can be deleted.
40354035
fs::set_permissions(&path, fs::Permissions::from_mode(0o755)).unwrap();
40364036
}
4037+
4038+
#[cargo_test]
4039+
fn dev_dep_with_links() {
4040+
let p = project()
4041+
.file(
4042+
"Cargo.toml",
4043+
r#"
4044+
[package]
4045+
name = "foo"
4046+
version = "0.1.0"
4047+
authors = []
4048+
links = "x"
4049+
4050+
[dev-dependencies]
4051+
bar = { path = "./bar" }
4052+
"#,
4053+
)
4054+
.file("build.rs", "fn main() {}")
4055+
.file("src/lib.rs", "")
4056+
.file(
4057+
"bar/Cargo.toml",
4058+
r#"
4059+
[package]
4060+
name = "bar"
4061+
version = "0.1.0"
4062+
authors = []
4063+
links = "y"
4064+
4065+
[dependencies]
4066+
foo = { path = ".." }
4067+
"#,
4068+
)
4069+
.file("bar/build.rs", "fn main() {}")
4070+
.file("bar/src/lib.rs", "")
4071+
.build();
4072+
p.cargo("check --tests").run()
4073+
}

0 commit comments

Comments
 (0)