@@ -40,6 +40,7 @@ pub struct Context<'a, 'cfg: 'a> {
40
40
pub compilation : Compilation < ' cfg > ,
41
41
pub packages : & ' a PackageSet < ' cfg > ,
42
42
pub build_state : Arc < BuildState > ,
43
+ pub build_script_overridden : HashSet < ( PackageId , Kind ) > ,
43
44
pub build_explicit_deps : HashMap < Unit < ' a > , BuildDeps > ,
44
45
pub fingerprints : HashMap < Unit < ' a > , Arc < Fingerprint > > ,
45
46
pub compiled : HashSet < Unit < ' a > > ,
@@ -55,7 +56,9 @@ pub struct Context<'a, 'cfg: 'a> {
55
56
host_info : TargetInfo ,
56
57
profiles : & ' a Profiles ,
57
58
incremental_enabled : bool ,
59
+
58
60
target_filenames : HashMap < Unit < ' a > , Arc < Vec < ( PathBuf , Option < PathBuf > , bool ) > > > ,
61
+ target_metadatas : HashMap < Unit < ' a > , Option < Metadata > > ,
59
62
}
60
63
61
64
#[ derive( Clone , Default ) ]
@@ -82,7 +85,7 @@ impl TargetInfo {
82
85
}
83
86
}
84
87
85
- #[ derive( Clone ) ]
88
+ #[ derive( Clone , Hash , Eq , PartialEq , Ord , PartialOrd ) ]
86
89
pub struct Metadata ( u64 ) ;
87
90
88
91
impl < ' a , ' cfg > Context < ' a , ' cfg > {
@@ -154,7 +157,11 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
154
157
used_in_plugin : HashSet :: new ( ) ,
155
158
incremental_enabled : incremental_enabled,
156
159
jobserver : jobserver,
160
+ build_script_overridden : HashSet :: new ( ) ,
161
+
162
+ // TODO: Pre-Calculate these with a topo-sort, rather than lazy-calculating
157
163
target_filenames : HashMap :: new ( ) ,
164
+ target_metadatas : HashMap :: new ( ) ,
158
165
} )
159
166
}
160
167
@@ -362,21 +369,21 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
362
369
363
370
/// Returns the directory for the specified unit where fingerprint
364
371
/// information is stored.
365
- pub fn fingerprint_dir ( & mut self , unit : & Unit ) -> PathBuf {
372
+ pub fn fingerprint_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
366
373
let dir = self . pkg_dir ( unit) ;
367
374
self . layout ( unit. kind ) . fingerprint ( ) . join ( dir)
368
375
}
369
376
370
377
/// Returns the appropriate directory layout for either a plugin or not.
371
- pub fn build_script_dir ( & mut self , unit : & Unit ) -> PathBuf {
378
+ pub fn build_script_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
372
379
assert ! ( unit. target. is_custom_build( ) ) ;
373
380
assert ! ( !unit. profile. run_custom_build) ;
374
381
let dir = self . pkg_dir ( unit) ;
375
382
self . layout ( Kind :: Host ) . build ( ) . join ( dir)
376
383
}
377
384
378
385
/// Returns the appropriate directory layout for either a plugin or not.
379
- pub fn build_script_out_dir ( & mut self , unit : & Unit ) -> PathBuf {
386
+ pub fn build_script_out_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
380
387
assert ! ( unit. target. is_custom_build( ) ) ;
381
388
assert ! ( unit. profile. run_custom_build) ;
382
389
let dir = self . pkg_dir ( unit) ;
@@ -394,7 +401,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
394
401
395
402
/// Returns the appropriate output directory for the specified package and
396
403
/// target.
397
- pub fn out_dir ( & mut self , unit : & Unit ) -> PathBuf {
404
+ pub fn out_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
398
405
if unit. profile . doc {
399
406
self . layout ( unit. kind ) . root ( ) . parent ( ) . unwrap ( ) . join ( "doc" )
400
407
} else if unit. target . is_custom_build ( ) {
@@ -406,7 +413,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
406
413
}
407
414
}
408
415
409
- fn pkg_dir ( & mut self , unit : & Unit ) -> String {
416
+ fn pkg_dir ( & mut self , unit : & Unit < ' a > ) -> String {
410
417
let name = unit. pkg . package_id ( ) . name ( ) ;
411
418
match self . target_metadata ( unit) {
412
419
Some ( meta) => format ! ( "{}-{}" , name, meta) ,
@@ -440,7 +447,17 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
440
447
/// We build to the path: "{filename}-{target_metadata}"
441
448
/// We use a linking step to link/copy to a predictable filename
442
449
/// like `target/debug/libfoo.{a,so,rlib}` and such.
443
- pub fn target_metadata ( & mut self , unit : & Unit ) -> Option < Metadata > {
450
+ pub fn target_metadata ( & mut self , unit : & Unit < ' a > ) -> Option < Metadata > {
451
+ if let Some ( cache) = self . target_metadatas . get ( unit) {
452
+ return cache. clone ( )
453
+ }
454
+
455
+ let metadata = self . calc_target_metadata ( unit) ;
456
+ self . target_metadatas . insert ( * unit, metadata. clone ( ) ) ;
457
+ metadata
458
+ }
459
+
460
+ fn calc_target_metadata ( & mut self , unit : & Unit < ' a > ) -> Option < Metadata > {
444
461
// No metadata for dylibs because of a couple issues
445
462
// - OSX encodes the dylib name in the executable
446
463
// - Windows rustc multiple files of which we can't easily link all of them
@@ -483,6 +500,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
483
500
// when changing feature sets each lib is separately cached.
484
501
self . resolve . features_sorted ( unit. pkg . package_id ( ) ) . hash ( & mut hasher) ;
485
502
503
+ // Mix in the target-metadata of all the dependencies of this target
504
+ if let Ok ( deps) = self . dep_targets ( unit) {
505
+ let mut deps_metadata = deps. into_iter ( ) . map ( |dep_unit| {
506
+ self . target_metadata ( & dep_unit)
507
+ } ) . collect :: < Vec < _ > > ( ) ;
508
+ deps_metadata. sort ( ) ;
509
+ deps_metadata. hash ( & mut hasher) ;
510
+ }
511
+
486
512
// Throw in the profile we're compiling with. This helps caching
487
513
// panic=abort and panic=unwind artifacts, additionally with various
488
514
// settings like debuginfo and whatnot.
@@ -512,7 +538,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
512
538
}
513
539
514
540
/// Returns the file stem for a given target/profile combo (with metadata)
515
- pub fn file_stem ( & mut self , unit : & Unit ) -> String {
541
+ pub fn file_stem ( & mut self , unit : & Unit < ' a > ) -> String {
516
542
match self . target_metadata ( unit) {
517
543
Some ( ref metadata) => format ! ( "{}-{}" , unit. target. crate_name( ) ,
518
544
metadata) ,
@@ -537,7 +563,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
537
563
538
564
/// Returns an Option because in some cases we don't want to link
539
565
/// (eg a dependent lib)
540
- pub fn link_stem ( & mut self , unit : & Unit ) -> Option < ( PathBuf , String ) > {
566
+ pub fn link_stem ( & mut self , unit : & Unit < ' a > ) -> Option < ( PathBuf , String ) > {
541
567
let src_dir = self . out_dir ( unit) ;
542
568
let bin_stem = self . bin_stem ( unit) ;
543
569
let file_stem = self . file_stem ( unit) ;
@@ -578,6 +604,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
578
604
return Ok ( cache. clone ( ) )
579
605
}
580
606
607
+ let result = self . calc_target_filenames ( unit) ;
608
+ if let Ok ( ref ret) = result {
609
+ self . target_filenames . insert ( * unit, ret. clone ( ) ) ;
610
+ }
611
+ result
612
+ }
613
+
614
+ fn calc_target_filenames ( & mut self , unit : & Unit < ' a > )
615
+ -> CargoResult < Arc < Vec < ( PathBuf , Option < PathBuf > , bool ) > > > {
581
616
let out_dir = self . out_dir ( unit) ;
582
617
let stem = self . file_stem ( unit) ;
583
618
let link_stem = self . link_stem ( unit) ;
@@ -659,9 +694,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
659
694
}
660
695
info ! ( "Target filenames: {:?}" , ret) ;
661
696
662
- let ret = Arc :: new ( ret) ;
663
- self . target_filenames . insert ( * unit, ret. clone ( ) ) ;
664
- Ok ( ret)
697
+ Ok ( Arc :: new ( ret) )
665
698
}
666
699
667
700
/// For a package, return all targets which are registered as dependencies
@@ -776,7 +809,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
776
809
// actually depend on anything, we've reached the end of the dependency
777
810
// chain as we've got all the info we're gonna get.
778
811
let key = ( unit. pkg . package_id ( ) . clone ( ) , unit. kind ) ;
779
- if self . build_state . outputs . lock ( ) . unwrap ( ) . contains_key ( & key) {
812
+ if self . build_script_overridden . contains ( & key) {
780
813
return Ok ( Vec :: new ( ) )
781
814
}
782
815
0 commit comments