@@ -415,20 +415,25 @@ pub fn create_bcx<'a, 'cfg>(
415
415
remove_duplicate_doc ( build_config, & units, & mut unit_graph) ;
416
416
}
417
417
418
- if build_config
418
+ let host_kind_requested = build_config
419
419
. requested_kinds
420
420
. 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 {
423
428
// 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.
426
431
let new_graph = rebuild_unit_graph_shared (
427
432
interner,
428
433
unit_graph,
429
434
& units,
430
435
& scrape_units,
431
- explicit_host_kind,
436
+ host_kind_requested . then_some ( explicit_host_kind) ,
432
437
) ;
433
438
// This would be nicer with destructuring assignment.
434
439
units = new_graph. 0 ;
@@ -540,29 +545,31 @@ pub fn create_bcx<'a, 'cfg>(
540
545
/// This is used to rebuild the unit graph, sharing host dependencies if possible.
541
546
///
542
547
/// 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.
545
550
///
546
551
/// This is necessary because if normal dependencies used `CompileKind::Host`,
547
552
/// 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
549
555
/// 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
551
557
/// `CompileKind::Host`, then they would end up being identical, causing a
552
558
/// collision in the `UnitGraph`, and Cargo would end up randomly choosing one
553
559
/// value or the other.
554
560
///
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
556
562
/// building the unit graph, and then run this second pass which will try to
557
563
/// combine shared dependencies safely. By adding a hash of the dependencies
558
564
/// 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.
560
567
fn rebuild_unit_graph_shared (
561
568
interner : & UnitInterner ,
562
569
unit_graph : UnitGraph ,
563
570
roots : & [ Unit ] ,
564
571
scrape_units : & [ Unit ] ,
565
- to_host : CompileKind ,
572
+ to_host : Option < CompileKind > ,
566
573
) -> ( Vec < Unit > , Vec < Unit > , UnitGraph ) {
567
574
let mut result = UnitGraph :: new ( ) ;
568
575
// Map of the old unit to the new unit, used to avoid recursing into units
@@ -595,7 +602,7 @@ fn traverse_and_share(
595
602
new_graph : & mut UnitGraph ,
596
603
unit_graph : & UnitGraph ,
597
604
unit : & Unit ,
598
- to_host : CompileKind ,
605
+ to_host : Option < CompileKind > ,
599
606
) -> Unit {
600
607
if let Some ( new_unit) = memo. get ( unit) {
601
608
// Already computed, no need to recompute.
@@ -615,10 +622,9 @@ fn traverse_and_share(
615
622
} )
616
623
. collect ( ) ;
617
624
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 ,
622
628
} ;
623
629
let new_unit = interner. intern (
624
630
& unit. pkg ,
0 commit comments