@@ -271,11 +271,11 @@ fn compute_deps(
271
271
let mut dev_deps = Vec :: new ( ) ;
272
272
for ( dep_pkg_id, deps) in filtered_deps {
273
273
let dep_pkg = state. get ( dep_pkg_id) ;
274
- let ( has_artifact , artifact_lib ) = calc_artifact_deps (
274
+ let ( could_have_non_artifact_lib , has_artifact_lib ) = calc_artifact_deps (
275
275
unit, unit_for, dep_pkg_id, deps, state, dep_filter, & mut ret,
276
276
) ?;
277
277
278
- let lib = package_lib ( dep_pkg, has_artifact , artifact_lib ) ;
278
+ let lib = package_lib ( dep_pkg, could_have_non_artifact_lib , has_artifact_lib ) ;
279
279
let dep_lib = match lib {
280
280
Some ( t) => t,
281
281
None => continue ,
@@ -402,14 +402,15 @@ fn compute_deps(
402
402
///
403
403
/// `has_artifact` is true if `dep_pkg` has any artifact, and `artifact_lib` is true
404
404
/// if any of them wants a library to be available too.
405
- fn package_lib ( dep_pkg : & Package , has_artifact : bool , artifact_lib : bool ) -> Option < & Target > {
406
- dep_pkg. targets ( ) . iter ( ) . find ( |t| {
407
- if has_artifact {
408
- t. is_lib ( ) && artifact_lib
409
- } else {
410
- t. is_lib ( )
411
- }
412
- } )
405
+ fn package_lib (
406
+ dep_pkg : & Package ,
407
+ could_have_non_artifact_lib : bool ,
408
+ artifact_lib : bool ,
409
+ ) -> Option < & Target > {
410
+ dep_pkg
411
+ . targets ( )
412
+ . iter ( )
413
+ . find ( |t| t. is_lib ( ) && ( could_have_non_artifact_lib || artifact_lib) )
413
414
}
414
415
415
416
/// Find artifacts for all `deps` of `unit` and add units that build these artifacts
@@ -423,16 +424,24 @@ fn calc_artifact_deps(
423
424
filter : & dyn Fn ( & Unit , & Dependency ) -> bool ,
424
425
ret : & mut Vec < UnitDep > ,
425
426
) -> CargoResult < ( bool , bool ) > {
426
- let mut has_artifact = false ;
427
- let mut artifact_lib = false ;
427
+ let mut has_artifact_lib = false ;
428
+ let mut num_artifacts = 0 ;
428
429
let artifact_pkg = state. get ( dep_id) ;
430
+ let mut deps_past_filter = 0 ;
429
431
for ( dep, artifact) in deps
430
432
. iter ( )
431
- . filter ( |dep| filter ( unit, dep) )
433
+ . filter ( |dep| {
434
+ if filter ( unit, dep) {
435
+ deps_past_filter += 1 ;
436
+ true
437
+ } else {
438
+ false
439
+ }
440
+ } )
432
441
. filter_map ( |dep| dep. artifact ( ) . map ( |a| ( dep, a) ) )
433
442
{
434
- has_artifact = true ;
435
- artifact_lib |= artifact . is_lib ( ) ;
443
+ has_artifact_lib |= artifact . is_lib ( ) ;
444
+ num_artifacts += 1 ;
436
445
// Custom build scripts (build/compile) never get artifact dependencies,
437
446
// but the run-build-script step does (where it is handled).
438
447
if !unit. target . is_custom_build ( ) {
@@ -456,7 +465,8 @@ fn calc_artifact_deps(
456
465
) ?) ;
457
466
}
458
467
}
459
- Ok ( ( has_artifact, artifact_lib) )
468
+ let could_be_non_artifact_lib = deps_past_filter != num_artifacts;
469
+ Ok ( ( could_be_non_artifact_lib, has_artifact_lib) )
460
470
}
461
471
462
472
/// Returns the dependencies needed to run a build script.
@@ -506,22 +516,25 @@ fn compute_deps_custom_build(
506
516
IS_NO_ARTIFACT_DEP ,
507
517
) ?;
508
518
519
+ let mut result = vec ! [ compile_script_unit] ;
520
+
521
+ // Include any artifact dependencies.
522
+ //
523
+ // This is essentially the same as `calc_artifact_deps`, but there are some
524
+ // subtle differences that require this to be implemented differently.
509
525
let artifact_build_deps = state. deps ( unit, script_unit_for, & |_unit, dep| {
510
526
dep. kind ( ) == DepKind :: Build && dep. artifact ( ) . is_some ( )
511
527
} ) ;
512
528
513
- if artifact_build_deps. is_empty ( ) {
514
- Ok ( vec ! [ compile_script_unit] )
515
- } else {
516
- let mut artifact_units: Vec < _ > = build_artifact_requirements_to_units (
517
- unit,
518
- unit_for. root_compile_kind ( ) ,
519
- artifact_build_deps,
520
- state,
521
- ) ?;
522
- artifact_units. push ( compile_script_unit) ;
523
- Ok ( artifact_units)
524
- }
529
+ build_artifact_requirements_to_units (
530
+ unit,
531
+ unit_for. root_compile_kind ( ) ,
532
+ artifact_build_deps,
533
+ state,
534
+ & mut result,
535
+ ) ?;
536
+
537
+ Ok ( result)
525
538
}
526
539
527
540
/// Given a `parent` unit which is a build script with artifact dependencies `artifact_deps`,
@@ -537,8 +550,8 @@ fn build_artifact_requirements_to_units(
537
550
root_unit_compile_target : CompileKind ,
538
551
artifact_deps : Vec < ( PackageId , & HashSet < Dependency > ) > ,
539
552
state : & State < ' _ , ' _ > ,
540
- ) -> CargoResult < Vec < UnitDep > > {
541
- let mut ret = Vec :: new ( ) ;
553
+ ret : & mut Vec < UnitDep > ,
554
+ ) -> CargoResult < ( ) > {
542
555
// This really wants to be true for build dependencies, otherwise resolver = "2"
543
556
// will fail. // It means that the host features will be separated from normal
544
557
// features, thus won't be unified with them.
@@ -564,7 +577,7 @@ fn build_artifact_requirements_to_units(
564
577
) ?) ;
565
578
}
566
579
}
567
- Ok ( ret )
580
+ Ok ( ( ) )
568
581
}
569
582
570
583
/// Given a `parent` unit containing a dependency `dep` whose package is `artifact_pkg`,
@@ -682,11 +695,11 @@ fn compute_deps_doc(
682
695
// the documentation of the library being built.
683
696
let mut ret = Vec :: new ( ) ;
684
697
for ( id, deps) in deps {
685
- let ( has_artifact , artifact_lib ) =
698
+ let ( could_have_non_artifact_lib , has_artifact_lib ) =
686
699
calc_artifact_deps ( unit, unit_for, id, deps, state, dep_filter, & mut ret) ?;
687
700
688
701
let dep_pkg = state. get ( id) ;
689
- let lib = package_lib ( dep_pkg, has_artifact , artifact_lib ) ;
702
+ let lib = package_lib ( dep_pkg, could_have_non_artifact_lib , has_artifact_lib ) ;
690
703
let dep_lib = match lib {
691
704
Some ( lib) => lib,
692
705
None => continue ,
0 commit comments