@@ -455,13 +455,12 @@ fn calculate<'a, 'cfg>(
455
455
456
456
// Next, recursively calculate the fingerprint for all of our dependencies.
457
457
//
458
- // Skip the fingerprints of build scripts as they may not always be
459
- // available and the dirtiness propagation for modification is tracked
460
- // elsewhere. Also skip fingerprints of binaries because they don't actually
461
- // induce a recompile, they're just dependencies in the sense that they need
462
- // to be built.
463
- let deps = cx. dep_targets ( unit) ;
464
- let deps = deps
458
+ // Skip the fingerprints of build scripts, they are included below in the
459
+ // `local` vec. Also skip fingerprints of binaries because they don't
460
+ // actually induce a recompile, they're just dependencies in the sense
461
+ // that they need to be built.
462
+ let mut deps = cx
463
+ . dep_targets ( unit)
465
464
. iter ( )
466
465
. filter ( |u| !u. target . is_custom_build ( ) && !u. target . is_bin ( ) )
467
466
. map ( |dep| {
@@ -475,8 +474,9 @@ fn calculate<'a, 'cfg>(
475
474
} )
476
475
} )
477
476
. collect :: < CargoResult < Vec < _ > > > ( ) ?;
477
+ deps. sort_by ( |a, b| a. pkg_id . cmp ( & b. pkg_id ) ) ;
478
478
479
- // And finally, calculate what our own local fingerprint is
479
+ // And finally, calculate what our own local fingerprint is.
480
480
let local = if use_dep_info ( unit) {
481
481
let dep_info = dep_info_loc ( cx, unit) ;
482
482
let mtime = dep_info_mtime_if_fresh ( unit. pkg , & dep_info) ?;
@@ -485,8 +485,32 @@ fn calculate<'a, 'cfg>(
485
485
let fingerprint = pkg_fingerprint ( & cx. bcx , unit. pkg ) ?;
486
486
LocalFingerprint :: Precalculated ( fingerprint)
487
487
} ;
488
- let mut deps = deps;
489
- deps. sort_by ( |a, b| a. pkg_id . cmp ( & b. pkg_id ) ) ;
488
+ let mut local = vec ! [ local] ;
489
+ // Include fingerprint for any build scripts this unit requires.
490
+ local. extend (
491
+ cx. dep_targets ( unit)
492
+ . iter ( )
493
+ . filter ( |u| u. mode . is_run_custom_build ( ) )
494
+ . map ( |dep| {
495
+ // If the build script is overridden, use the override info as
496
+ // the override. Otherwise, use the last invocation time of
497
+ // the build script. If the build script re-runs during this
498
+ // run, dirty propagation within the JobQueue will ensure that
499
+ // this gets invalidated. This is only here to catch the
500
+ // situation when cargo is run a second time for another
501
+ // target that wasn't built previously (such as `cargo build`
502
+ // then `cargo test`).
503
+ build_script_override_fingerprint ( cx, unit) . unwrap_or_else ( || {
504
+ let ts_path = cx
505
+ . files ( )
506
+ . build_script_run_dir ( dep)
507
+ . join ( "invoked.timestamp" ) ;
508
+ let ts_path_mtime = paths:: mtime ( & ts_path) . ok ( ) ;
509
+ LocalFingerprint :: mtime ( cx. files ( ) . target_root ( ) , ts_path_mtime, & ts_path)
510
+ } )
511
+ } ) ,
512
+ ) ;
513
+
490
514
let extra_flags = if unit. mode . is_doc ( ) {
491
515
bcx. rustdocflags_args ( unit) ?
492
516
} else {
@@ -502,7 +526,7 @@ fn calculate<'a, 'cfg>(
502
526
path : util:: hash_u64 ( & super :: path_args ( & cx. bcx , unit) . 0 ) ,
503
527
features : format ! ( "{:?}" , bcx. resolve. features_sorted( unit. pkg. package_id( ) ) ) ,
504
528
deps,
505
- local : vec ! [ local ] ,
529
+ local,
506
530
memoized_hash : Mutex :: new ( None ) ,
507
531
edition : unit. target . edition ( ) ,
508
532
rustflags : extra_flags,
@@ -595,19 +619,13 @@ fn build_script_local_fingerprints<'a, 'cfg>(
595
619
cx : & mut Context < ' a , ' cfg > ,
596
620
unit : & Unit < ' a > ,
597
621
) -> CargoResult < ( Vec < LocalFingerprint > , Option < PathBuf > ) > {
598
- let state = cx. build_state . outputs . lock ( ) . unwrap ( ) ;
599
622
// First up, if this build script is entirely overridden, then we just
600
623
// return the hash of what we overrode it with.
601
- //
602
- // Note that the `None` here means that we don't want to update the local
603
- // fingerprint afterwards because this is all just overridden.
604
- if let Some ( output) = state. get ( & ( unit. pkg . package_id ( ) , unit. kind ) ) {
624
+ if let Some ( fingerprint) = build_script_override_fingerprint ( cx, unit) {
605
625
debug ! ( "override local fingerprints deps" ) ;
606
- let s = format ! (
607
- "overridden build state with hash: {}" ,
608
- util:: hash_u64( output)
609
- ) ;
610
- return Ok ( ( vec ! [ LocalFingerprint :: Precalculated ( s) ] , None ) ) ;
626
+ // Note that the `None` here means that we don't want to update the local
627
+ // fingerprint afterwards because this is all just overridden.
628
+ return Ok ( ( vec ! [ fingerprint] , None ) ) ;
611
629
}
612
630
613
631
// Next up we look at the previously listed dependencies for the build
@@ -633,6 +651,24 @@ fn build_script_local_fingerprints<'a, 'cfg>(
633
651
) )
634
652
}
635
653
654
+ /// Create a local fingerprint for an overridden build script.
655
+ /// Returns None if it is not overridden.
656
+ fn build_script_override_fingerprint < ' a , ' cfg > (
657
+ cx : & mut Context < ' a , ' cfg > ,
658
+ unit : & Unit < ' a > ,
659
+ ) -> Option < LocalFingerprint > {
660
+ let state = cx. build_state . outputs . lock ( ) . unwrap ( ) ;
661
+ state
662
+ . get ( & ( unit. pkg . package_id ( ) , unit. kind ) )
663
+ . map ( |output| {
664
+ let s = format ! (
665
+ "overridden build state with hash: {}" ,
666
+ util:: hash_u64( output)
667
+ ) ;
668
+ LocalFingerprint :: Precalculated ( s)
669
+ } )
670
+ }
671
+
636
672
fn local_fingerprints_deps (
637
673
deps : & BuildDeps ,
638
674
target_root : & Path ,
0 commit comments