@@ -55,7 +55,9 @@ pub struct Context<'a, 'cfg: 'a> {
55
55
host_info : TargetInfo ,
56
56
profiles : & ' a Profiles ,
57
57
incremental_enabled : bool ,
58
+
58
59
target_filenames : HashMap < Unit < ' a > , Arc < Vec < ( PathBuf , Option < PathBuf > , bool ) > > > ,
60
+ target_metadatas : HashMap < Unit < ' a > , Option < Metadata > > ,
59
61
}
60
62
61
63
#[ derive( Clone , Default ) ]
@@ -154,7 +156,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
154
156
used_in_plugin : HashSet :: new ( ) ,
155
157
incremental_enabled : incremental_enabled,
156
158
jobserver : jobserver,
159
+
160
+ // TODO: Pre-Calculate these with a topo-sort, rather than lazy-calculating
157
161
target_filenames : HashMap :: new ( ) ,
162
+ target_metadatas : HashMap :: new ( ) ,
158
163
} )
159
164
}
160
165
@@ -362,21 +367,21 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
362
367
363
368
/// Returns the directory for the specified unit where fingerprint
364
369
/// information is stored.
365
- pub fn fingerprint_dir ( & mut self , unit : & Unit ) -> PathBuf {
370
+ pub fn fingerprint_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
366
371
let dir = self . pkg_dir ( unit) ;
367
372
self . layout ( unit. kind ) . fingerprint ( ) . join ( dir)
368
373
}
369
374
370
375
/// Returns the appropriate directory layout for either a plugin or not.
371
- pub fn build_script_dir ( & mut self , unit : & Unit ) -> PathBuf {
376
+ pub fn build_script_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
372
377
assert ! ( unit. target. is_custom_build( ) ) ;
373
378
assert ! ( !unit. profile. run_custom_build) ;
374
379
let dir = self . pkg_dir ( unit) ;
375
380
self . layout ( Kind :: Host ) . build ( ) . join ( dir)
376
381
}
377
382
378
383
/// Returns the appropriate directory layout for either a plugin or not.
379
- pub fn build_script_out_dir ( & mut self , unit : & Unit ) -> PathBuf {
384
+ pub fn build_script_out_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
380
385
assert ! ( unit. target. is_custom_build( ) ) ;
381
386
assert ! ( unit. profile. run_custom_build) ;
382
387
let dir = self . pkg_dir ( unit) ;
@@ -394,7 +399,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
394
399
395
400
/// Returns the appropriate output directory for the specified package and
396
401
/// target.
397
- pub fn out_dir ( & mut self , unit : & Unit ) -> PathBuf {
402
+ pub fn out_dir ( & mut self , unit : & Unit < ' a > ) -> PathBuf {
398
403
if unit. profile . doc {
399
404
self . layout ( unit. kind ) . root ( ) . parent ( ) . unwrap ( ) . join ( "doc" )
400
405
} else if unit. target . is_custom_build ( ) {
@@ -406,7 +411,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
406
411
}
407
412
}
408
413
409
- fn pkg_dir ( & mut self , unit : & Unit ) -> String {
414
+ fn pkg_dir ( & mut self , unit : & Unit < ' a > ) -> String {
410
415
let name = unit. pkg . package_id ( ) . name ( ) ;
411
416
match self . target_metadata ( unit) {
412
417
Some ( meta) => format ! ( "{}-{}" , name, meta) ,
@@ -440,7 +445,17 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
440
445
/// We build to the path: "{filename}-{target_metadata}"
441
446
/// We use a linking step to link/copy to a predictable filename
442
447
/// like `target/debug/libfoo.{a,so,rlib}` and such.
443
- pub fn target_metadata ( & mut self , unit : & Unit ) -> Option < Metadata > {
448
+ pub fn target_metadata ( & mut self , unit : & Unit < ' a > ) -> Option < Metadata > {
449
+ if let Some ( cache) = self . target_metadatas . get ( unit) {
450
+ return cache. clone ( )
451
+ }
452
+
453
+ let metadata = self . calc_target_metadata ( unit) ;
454
+ self . target_metadatas . insert ( * unit, metadata. clone ( ) ) ;
455
+ metadata
456
+ }
457
+
458
+ fn calc_target_metadata ( & mut self , unit : & Unit < ' a > ) -> Option < Metadata > {
444
459
// No metadata for dylibs because of a couple issues
445
460
// - OSX encodes the dylib name in the executable
446
461
// - Windows rustc multiple files of which we can't easily link all of them
@@ -521,7 +536,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
521
536
}
522
537
523
538
/// Returns the file stem for a given target/profile combo (with metadata)
524
- pub fn file_stem ( & mut self , unit : & Unit ) -> String {
539
+ pub fn file_stem ( & mut self , unit : & Unit < ' a > ) -> String {
525
540
match self . target_metadata ( unit) {
526
541
Some ( ref metadata) => format ! ( "{}-{}" , unit. target. crate_name( ) ,
527
542
metadata) ,
@@ -546,7 +561,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
546
561
547
562
/// Returns an Option because in some cases we don't want to link
548
563
/// (eg a dependent lib)
549
- pub fn link_stem ( & mut self , unit : & Unit ) -> Option < ( PathBuf , String ) > {
564
+ pub fn link_stem ( & mut self , unit : & Unit < ' a > ) -> Option < ( PathBuf , String ) > {
550
565
let src_dir = self . out_dir ( unit) ;
551
566
let bin_stem = self . bin_stem ( unit) ;
552
567
let file_stem = self . file_stem ( unit) ;
@@ -587,6 +602,15 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
587
602
return Ok ( cache. clone ( ) )
588
603
}
589
604
605
+ let result = self . calc_target_filenames ( unit) ;
606
+ if let Ok ( ref ret) = result {
607
+ self . target_filenames . insert ( * unit, ret. clone ( ) ) ;
608
+ }
609
+ result
610
+ }
611
+
612
+ fn calc_target_filenames ( & mut self , unit : & Unit < ' a > )
613
+ -> CargoResult < Arc < Vec < ( PathBuf , Option < PathBuf > , bool ) > > > {
590
614
let out_dir = self . out_dir ( unit) ;
591
615
let stem = self . file_stem ( unit) ;
592
616
let link_stem = self . link_stem ( unit) ;
@@ -668,9 +692,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
668
692
}
669
693
info ! ( "Target filenames: {:?}" , ret) ;
670
694
671
- let ret = Arc :: new ( ret) ;
672
- self . target_filenames . insert ( * unit, ret. clone ( ) ) ;
673
- Ok ( ret)
695
+ Ok ( Arc :: new ( ret) )
674
696
}
675
697
676
698
fn used_deps ( & self , unit : & Unit < ' a > ) -> CargoResult < Vec < Unit < ' a > > > {
0 commit comments