Skip to content

Commit 1a8df6a

Browse files
committed
Auto merge of #9068 - alexcrichton:backport-fix, r=Eh2406
[BETA] Fix `links` vars showing up for testing packages This is a beta backport of #9065
2 parents 75d5d8c + 658ee07 commit 1a8df6a

File tree

3 files changed

+98
-19
lines changed

3 files changed

+98
-19
lines changed

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ struct State<'a, 'cfg> {
4747
target_data: &'a RustcTargetData,
4848
profiles: &'a Profiles,
4949
interner: &'a UnitInterner,
50+
51+
/// A set of edges in `unit_dependencies` where (a, b) means that the
52+
/// dependency from a to b was added purely because it was a dev-dependency.
53+
/// This is used during `connect_run_custom_build_deps`.
54+
dev_dependency_edges: HashSet<(Unit, Unit)>,
5055
}
5156

5257
pub fn build_unit_dependencies<'a, 'cfg>(
@@ -86,6 +91,7 @@ pub fn build_unit_dependencies<'a, 'cfg>(
8691
target_data,
8792
profiles,
8893
interner,
94+
dev_dependency_edges: HashSet::new(),
8995
};
9096

9197
let std_unit_deps = calc_deps_of_std(&mut state, std_roots)?;
@@ -98,7 +104,7 @@ pub fn build_unit_dependencies<'a, 'cfg>(
98104
attach_std_deps(&mut state, std_roots, std_unit_deps);
99105
}
100106

101-
connect_run_custom_build_deps(&mut state.unit_dependencies);
107+
connect_run_custom_build_deps(&mut state);
102108

103109
// Dependencies are used in tons of places throughout the backend, many of
104110
// which affect the determinism of the build itself. As a result be sure
@@ -258,7 +264,8 @@ fn compute_deps(
258264
});
259265

260266
let mut ret = Vec::new();
261-
for (id, _) in filtered_deps {
267+
let mut dev_deps = Vec::new();
268+
for (id, deps) in filtered_deps {
262269
let pkg = state.get(id);
263270
let lib = match pkg.targets().iter().find(|t| t.is_lib()) {
264271
Some(t) => t,
@@ -270,6 +277,7 @@ fn compute_deps(
270277
// If it is a custom build script, then it *only* has build dependencies.
271278
.with_host_features(unit.target.is_custom_build() || lib.proc_macro());
272279

280+
let start = ret.len();
273281
if state.config.cli_unstable().dual_proc_macros && lib.proc_macro() && !unit.kind.is_host()
274282
{
275283
let unit_dep = new_unit_dep(state, unit, pkg, lib, dep_unit_for, unit.kind, mode)?;
@@ -289,7 +297,18 @@ fn compute_deps(
289297
)?;
290298
ret.push(unit_dep);
291299
}
300+
301+
// If the unit added was a dev-dependency unit, then record that in the
302+
// dev-dependencies array. We'll add this to
303+
// `state.dev_dependency_edges` at the end and process it later in
304+
// `connect_run_custom_build_deps`.
305+
if deps.iter().all(|d| !d.is_transitive()) {
306+
for dep in ret[start..].iter() {
307+
dev_deps.push((unit.clone(), dep.unit.clone()));
308+
}
309+
}
292310
}
311+
state.dev_dependency_edges.extend(dev_deps);
293312

294313
// If this target is a build script, then what we've collected so far is
295314
// all we need. If this isn't a build script, then it depends on the
@@ -621,26 +640,18 @@ fn new_unit_dep_with_profile(
621640
///
622641
/// Here we take the entire `deps` map and add more dependencies from execution
623642
/// of one build script to execution of another build script.
624-
fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
643+
fn connect_run_custom_build_deps(state: &mut State<'_, '_>) {
625644
let mut new_deps = Vec::new();
626645

627646
{
647+
let state = &*state;
628648
// First up build a reverse dependency map. This is a mapping of all
629649
// `RunCustomBuild` known steps to the unit which depends on them. For
630650
// example a library might depend on a build script, so this map will
631651
// have the build script as the key and the library would be in the
632652
// 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.
639653
let mut reverse_deps_map = HashMap::new();
640-
for (unit, deps) in unit_dependencies.iter() {
641-
if unit.mode.is_any_test() {
642-
continue;
643-
}
654+
for (unit, deps) in state.unit_dependencies.iter() {
644655
for dep in deps {
645656
if dep.unit.mode == CompileMode::RunCustomBuild {
646657
reverse_deps_map
@@ -660,7 +671,8 @@ fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
660671
// `links`, then we depend on that package's build script! Here we use
661672
// `dep_build_script` to manufacture an appropriate build script unit to
662673
// depend on.
663-
for unit in unit_dependencies
674+
for unit in state
675+
.unit_dependencies
664676
.keys()
665677
.filter(|k| k.mode == CompileMode::RunCustomBuild)
666678
{
@@ -674,16 +686,34 @@ fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
674686
let to_add = reverse_deps
675687
.iter()
676688
// Get all sibling dependencies of `unit`
677-
.flat_map(|reverse_dep| unit_dependencies[reverse_dep].iter())
689+
.flat_map(|reverse_dep| {
690+
state.unit_dependencies[reverse_dep]
691+
.iter()
692+
.map(move |a| (reverse_dep, a))
693+
})
678694
// Only deps with `links`.
679-
.filter(|other| {
695+
.filter(|(_parent, other)| {
680696
other.unit.pkg != unit.pkg
681697
&& other.unit.target.is_linkable()
682698
&& other.unit.pkg.manifest().links().is_some()
683699
})
700+
// Skip dependencies induced via dev-dependencies since
701+
// connections between `links` and build scripts only happens
702+
// via normal dependencies. Otherwise since dev-dependencies can
703+
// be cyclic we could have cyclic build-script executions.
704+
.filter_map(move |(parent, other)| {
705+
if state
706+
.dev_dependency_edges
707+
.contains(&((*parent).clone(), other.unit.clone()))
708+
{
709+
None
710+
} else {
711+
Some(other)
712+
}
713+
})
684714
// Get the RunCustomBuild for other lib.
685715
.filter_map(|other| {
686-
unit_dependencies[&other.unit]
716+
state.unit_dependencies[&other.unit]
687717
.iter()
688718
.find(|other_dep| other_dep.unit.mode == CompileMode::RunCustomBuild)
689719
.cloned()
@@ -699,7 +729,11 @@ fn connect_run_custom_build_deps(unit_dependencies: &mut UnitGraph) {
699729

700730
// And finally, add in all the missing dependencies!
701731
for (unit, new_deps) in new_deps {
702-
unit_dependencies.get_mut(&unit).unwrap().extend(new_deps);
732+
state
733+
.unit_dependencies
734+
.get_mut(&unit)
735+
.unwrap()
736+
.extend(new_deps);
703737
}
704738
}
705739

tests/testsuite/build_script.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4158,3 +4158,48 @@ fn rerun_if_directory() {
41584158
dirty();
41594159
fresh();
41604160
}
4161+
4162+
#[cargo_test]
4163+
fn test_with_dep_metadata() {
4164+
let p = project()
4165+
.file(
4166+
"Cargo.toml",
4167+
r#"
4168+
[package]
4169+
name = "foo"
4170+
version = "0.1.0"
4171+
4172+
[dependencies]
4173+
bar = { path = 'bar' }
4174+
"#,
4175+
)
4176+
.file("src/lib.rs", "")
4177+
.file(
4178+
"build.rs",
4179+
r#"
4180+
fn main() {
4181+
assert_eq!(std::env::var("DEP_BAR_FOO").unwrap(), "bar");
4182+
}
4183+
"#,
4184+
)
4185+
.file(
4186+
"bar/Cargo.toml",
4187+
r#"
4188+
[package]
4189+
name = "bar"
4190+
version = "0.1.0"
4191+
links = 'bar'
4192+
"#,
4193+
)
4194+
.file("bar/src/lib.rs", "")
4195+
.file(
4196+
"bar/build.rs",
4197+
r#"
4198+
fn main() {
4199+
println!("cargo:foo=bar");
4200+
}
4201+
"#,
4202+
)
4203+
.build();
4204+
p.cargo("test --lib").run();
4205+
}

tests/testsuite/cache_messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn color() {
105105
return s.replace("\x1b[0m\x1b[0m", "\x1b[0m");
106106
#[cfg(not(windows))]
107107
return s.to_string();
108-
};
108+
}
109109

110110
let compare = |a, b| {
111111
assert_eq!(normalize(a), normalize(b));

0 commit comments

Comments
 (0)