Skip to content

Commit 385bba3

Browse files
committed
fix: share artifact and build dependencies
This prevents collisions for transitive dependencies Signed-off-by: Roman Volosatovs <[email protected]>
1 parent 548b252 commit 385bba3

File tree

1 file changed

+24
-18
lines changed
  • src/cargo/ops/cargo_compile

1 file changed

+24
-18
lines changed

src/cargo/ops/cargo_compile/mod.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -415,20 +415,25 @@ pub fn create_bcx<'a, 'cfg>(
415415
remove_duplicate_doc(build_config, &units, &mut unit_graph);
416416
}
417417

418-
if build_config
418+
let host_kind_requested = build_config
419419
.requested_kinds
420420
.iter()
421-
.any(CompileKind::is_host)
422-
{
421+
.any(CompileKind::is_host);
422+
let should_share_deps = host_kind_requested
423+
|| config.cli_unstable().bindeps
424+
&& unit_graph
425+
.iter()
426+
.any(|(unit, _)| unit.artifact_target_for_features.is_some());
427+
if should_share_deps {
423428
// Rebuild the unit graph, replacing the explicit host targets with
424-
// CompileKind::Host, merging any dependencies shared with build
425-
// dependencies.
429+
// CompileKind::Host, removing `artifact_target_for_features` and merging any dependencies
430+
// shared with build and artifact dependencies.
426431
let new_graph = rebuild_unit_graph_shared(
427432
interner,
428433
unit_graph,
429434
&units,
430435
&scrape_units,
431-
explicit_host_kind,
436+
host_kind_requested.then_some(explicit_host_kind),
432437
);
433438
// This would be nicer with destructuring assignment.
434439
units = new_graph.0;
@@ -540,29 +545,31 @@ pub fn create_bcx<'a, 'cfg>(
540545
/// This is used to rebuild the unit graph, sharing host dependencies if possible.
541546
///
542547
/// This will translate any unit's `CompileKind::Target(host)` to
543-
/// `CompileKind::Host` if the kind is equal to `to_host`. This also handles
544-
/// generating the unit `dep_hash`, and merging shared units if possible.
548+
/// `CompileKind::Host` if `to_host` is not `None` and the kind is equal to `to_host`.
549+
/// This also handles generating the unit `dep_hash`, and merging shared units if possible.
545550
///
546551
/// This is necessary because if normal dependencies used `CompileKind::Host`,
547552
/// there would be no way to distinguish those units from build-dependency
548-
/// units. This can cause a problem if a shared normal/build dependency needs
553+
/// units or artifact dependency units.
554+
/// This can cause a problem if a shared normal/build/artifact dependency needs
549555
/// to link to another dependency whose features differ based on whether or
550-
/// not it is a normal or build dependency. If both units used
556+
/// not it is a normal, build or artifact dependency. If all units used
551557
/// `CompileKind::Host`, then they would end up being identical, causing a
552558
/// collision in the `UnitGraph`, and Cargo would end up randomly choosing one
553559
/// value or the other.
554560
///
555-
/// The solution is to keep normal and build dependencies separate when
561+
/// The solution is to keep normal, build and artifact dependencies separate when
556562
/// building the unit graph, and then run this second pass which will try to
557563
/// combine shared dependencies safely. By adding a hash of the dependencies
558564
/// to the `Unit`, this allows the `CompileKind` to be changed back to `Host`
559-
/// without fear of an unwanted collision.
565+
/// and `artifact_target_for_features` to be removed without fear of an unwanted
566+
/// collision for build or artifact dependencies.
560567
fn rebuild_unit_graph_shared(
561568
interner: &UnitInterner,
562569
unit_graph: UnitGraph,
563570
roots: &[Unit],
564571
scrape_units: &[Unit],
565-
to_host: CompileKind,
572+
to_host: Option<CompileKind>,
566573
) -> (Vec<Unit>, Vec<Unit>, UnitGraph) {
567574
let mut result = UnitGraph::new();
568575
// Map of the old unit to the new unit, used to avoid recursing into units
@@ -595,7 +602,7 @@ fn traverse_and_share(
595602
new_graph: &mut UnitGraph,
596603
unit_graph: &UnitGraph,
597604
unit: &Unit,
598-
to_host: CompileKind,
605+
to_host: Option<CompileKind>,
599606
) -> Unit {
600607
if let Some(new_unit) = memo.get(unit) {
601608
// Already computed, no need to recompute.
@@ -615,10 +622,9 @@ fn traverse_and_share(
615622
})
616623
.collect();
617624
let new_dep_hash = dep_hash.finish();
618-
let new_kind = if unit.kind == to_host {
619-
CompileKind::Host
620-
} else {
621-
unit.kind
625+
let new_kind = match to_host {
626+
Some(to_host) if to_host == unit.kind => CompileKind::Host,
627+
_ => unit.kind,
622628
};
623629
let new_unit = interner.intern(
624630
&unit.pkg,

0 commit comments

Comments
 (0)