@@ -455,13 +455,12 @@ fn calculate<'a, 'cfg>(
455455
456456 // Next, recursively calculate the fingerprint for all of our dependencies.
457457 //
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)
465464 . iter ( )
466465 . filter ( |u| !u. target . is_custom_build ( ) && !u. target . is_bin ( ) )
467466 . map ( |dep| {
@@ -475,8 +474,9 @@ fn calculate<'a, 'cfg>(
475474 } )
476475 } )
477476 . collect :: < CargoResult < Vec < _ > > > ( ) ?;
477+ deps. sort_by ( |a, b| a. pkg_id . cmp ( & b. pkg_id ) ) ;
478478
479- // And finally, calculate what our own local fingerprint is
479+ // And finally, calculate what our own local fingerprint is.
480480 let local = if use_dep_info ( unit) {
481481 let dep_info = dep_info_loc ( cx, unit) ;
482482 let mtime = dep_info_mtime_if_fresh ( unit. pkg , & dep_info) ?;
@@ -485,8 +485,32 @@ fn calculate<'a, 'cfg>(
485485 let fingerprint = pkg_fingerprint ( & cx. bcx , unit. pkg ) ?;
486486 LocalFingerprint :: Precalculated ( fingerprint)
487487 } ;
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+
490514 let extra_flags = if unit. mode . is_doc ( ) {
491515 bcx. rustdocflags_args ( unit) ?
492516 } else {
@@ -502,7 +526,7 @@ fn calculate<'a, 'cfg>(
502526 path : util:: hash_u64 ( & super :: path_args ( & cx. bcx , unit) . 0 ) ,
503527 features : format ! ( "{:?}" , bcx. resolve. features_sorted( unit. pkg. package_id( ) ) ) ,
504528 deps,
505- local : vec ! [ local ] ,
529+ local,
506530 memoized_hash : Mutex :: new ( None ) ,
507531 edition : unit. target . edition ( ) ,
508532 rustflags : extra_flags,
@@ -595,19 +619,13 @@ fn build_script_local_fingerprints<'a, 'cfg>(
595619 cx : & mut Context < ' a , ' cfg > ,
596620 unit : & Unit < ' a > ,
597621) -> CargoResult < ( Vec < LocalFingerprint > , Option < PathBuf > ) > {
598- let state = cx. build_state . outputs . lock ( ) . unwrap ( ) ;
599622 // First up, if this build script is entirely overridden, then we just
600623 // 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) {
605625 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 ) ) ;
611629 }
612630
613631 // Next up we look at the previously listed dependencies for the build
@@ -633,6 +651,24 @@ fn build_script_local_fingerprints<'a, 'cfg>(
633651 ) )
634652}
635653
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+
636672fn local_fingerprints_deps (
637673 deps : & BuildDeps ,
638674 target_root : & Path ,
0 commit comments