@@ -259,6 +259,16 @@ struct CompilerFlag {
259
259
260
260
type Env = Option < Arc < OsStr > > ;
261
261
262
+ #[ derive( Debug , Default ) ]
263
+ struct BuildCache {
264
+ env_cache : RwLock < HashMap < Box < str > , Env > > ,
265
+ apple_sdk_root_cache : RwLock < HashMap < Box < str > , Arc < OsStr > > > ,
266
+ apple_versions_cache : RwLock < HashMap < Box < str > , Arc < str > > > ,
267
+ cached_compiler_family : RwLock < HashMap < Box < Path > , ToolFamily > > ,
268
+ known_flag_support_status_cache : RwLock < HashMap < CompilerFlag , bool > > ,
269
+ target_info_parser : target:: TargetInfoParser ,
270
+ }
271
+
262
272
/// A builder for compilation of a native library.
263
273
///
264
274
/// A `Build` is the main type of the `cc` crate and is used to control all the
@@ -271,7 +281,6 @@ pub struct Build {
271
281
objects : Vec < Arc < Path > > ,
272
282
flags : Vec < Arc < OsStr > > ,
273
283
flags_supported : Vec < Arc < OsStr > > ,
274
- known_flag_support_status_cache : Arc < RwLock < HashMap < CompilerFlag , bool > > > ,
275
284
ar_flags : Vec < Arc < OsStr > > ,
276
285
asm_flags : Vec < Arc < OsStr > > ,
277
286
no_default_flags : bool ,
@@ -306,12 +315,9 @@ pub struct Build {
306
315
warnings_into_errors : bool ,
307
316
warnings : Option < bool > ,
308
317
extra_warnings : Option < bool > ,
309
- env_cache : Arc < RwLock < HashMap < Box < str > , Env > > > ,
310
- apple_sdk_root_cache : Arc < RwLock < HashMap < Box < str > , Arc < OsStr > > > > ,
311
- apple_versions_cache : Arc < RwLock < HashMap < Box < str > , Arc < str > > > > ,
312
318
emit_rerun_if_env_changed : bool ,
313
- cached_compiler_family : Arc < RwLock < HashMap < Box < Path > , ToolFamily > > > ,
314
319
shell_escaped_flags : Option < bool > ,
320
+ build_cache : Arc < BuildCache > ,
315
321
}
316
322
317
323
/// Represents the types of errors that may occur while using cc-rs.
@@ -399,7 +405,6 @@ impl Build {
399
405
objects : Vec :: new ( ) ,
400
406
flags : Vec :: new ( ) ,
401
407
flags_supported : Vec :: new ( ) ,
402
- known_flag_support_status_cache : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
403
408
ar_flags : Vec :: new ( ) ,
404
409
asm_flags : Vec :: new ( ) ,
405
410
no_default_flags : false ,
@@ -431,12 +436,9 @@ impl Build {
431
436
warnings : None ,
432
437
extra_warnings : None ,
433
438
warnings_into_errors : false ,
434
- env_cache : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
435
- apple_sdk_root_cache : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
436
- apple_versions_cache : Arc :: new ( RwLock :: new ( HashMap :: new ( ) ) ) ,
437
439
emit_rerun_if_env_changed : true ,
438
- cached_compiler_family : Arc :: default ( ) ,
439
440
shell_escaped_flags : None ,
441
+ build_cache : Arc :: default ( ) ,
440
442
}
441
443
}
442
444
@@ -634,14 +636,15 @@ impl Build {
634
636
& self ,
635
637
flag : & OsStr ,
636
638
compiler_path : & Path ,
637
- target : & TargetInfo ,
639
+ target : & TargetInfo < ' _ > ,
638
640
) -> Result < bool , Error > {
639
641
let compiler_flag = CompilerFlag {
640
642
compiler : compiler_path. into ( ) ,
641
643
flag : flag. into ( ) ,
642
644
} ;
643
645
644
646
if let Some ( is_supported) = self
647
+ . build_cache
645
648
. known_flag_support_status_cache
646
649
. read ( )
647
650
. unwrap ( )
@@ -686,7 +689,7 @@ impl Build {
686
689
}
687
690
688
691
let mut cmd = compiler. to_command ( ) ;
689
- let is_arm = matches ! ( & * target. arch, "aarch64" | "arm" ) ;
692
+ let is_arm = matches ! ( target. arch, "aarch64" | "arm" ) ;
690
693
let clang = compiler. is_like_clang ( ) ;
691
694
let gnu = compiler. family == ToolFamily :: Gnu ;
692
695
command_add_output_file (
@@ -711,7 +714,8 @@ impl Build {
711
714
let output = cmd. output ( ) ?;
712
715
let is_supported = output. status . success ( ) && output. stderr . is_empty ( ) ;
713
716
714
- self . known_flag_support_status_cache
717
+ self . build_cache
718
+ . known_flag_support_status_cache
715
719
. write ( )
716
720
. unwrap ( )
717
721
. insert ( compiler_flag, is_supported) ;
@@ -1433,7 +1437,7 @@ impl Build {
1433
1437
libtst = true ;
1434
1438
} else if cfg ! ( target_env = "msvc" ) {
1435
1439
libdir. push ( "lib" ) ;
1436
- match & * target. arch {
1440
+ match target. arch {
1437
1441
"x86_64" => {
1438
1442
libdir. push ( "x64" ) ;
1439
1443
libtst = true ;
@@ -1725,7 +1729,7 @@ impl Build {
1725
1729
. map ( Cow :: Owned ) ?,
1726
1730
)
1727
1731
} ;
1728
- let is_arm = matches ! ( & * target. arch, "aarch64" | "arm" ) ;
1732
+ let is_arm = matches ! ( target. arch, "aarch64" | "arm" ) ;
1729
1733
command_add_output_file (
1730
1734
& mut cmd,
1731
1735
& obj. dst ,
@@ -1932,7 +1936,7 @@ impl Build {
1932
1936
fn add_default_flags (
1933
1937
& self ,
1934
1938
cmd : & mut Tool ,
1935
- target : & TargetInfo ,
1939
+ target : & TargetInfo < ' _ > ,
1936
1940
opt_level : & str ,
1937
1941
) -> Result < ( ) , Error > {
1938
1942
let raw_target = self . get_raw_target ( ) ?;
@@ -2290,7 +2294,7 @@ impl Build {
2290
2294
// get the 32i/32imac/32imc/64gc/64imac/... part
2291
2295
let arch = & target. full_arch [ 5 ..] ;
2292
2296
if arch. starts_with ( "64" ) {
2293
- if matches ! ( & * target. os, "linux" | "freebsd" | "netbsd" ) {
2297
+ if matches ! ( target. os, "linux" | "freebsd" | "netbsd" ) {
2294
2298
cmd. args . push ( ( "-march=rv64gc" ) . into ( ) ) ;
2295
2299
cmd. args . push ( "-mabi=lp64d" . into ( ) ) ;
2296
2300
} else {
@@ -2528,7 +2532,7 @@ impl Build {
2528
2532
2529
2533
fn apple_flags ( & self , cmd : & mut Tool ) -> Result < ( ) , Error > {
2530
2534
let target = self . get_target ( ) ?;
2531
- let arch_str = & * target. full_arch ;
2535
+ let arch_str = target. full_arch ;
2532
2536
2533
2537
let arch = if target. os == "macos" {
2534
2538
match arch_str {
@@ -2582,7 +2586,7 @@ impl Build {
2582
2586
}
2583
2587
} ;
2584
2588
2585
- let sdk_details = apple_os_sdk_parts ( & target. os , & arch) ;
2589
+ let sdk_details = apple_os_sdk_parts ( target. os , & arch) ;
2586
2590
let min_version = self . apple_deployment_target ( & target) ;
2587
2591
2588
2592
match arch {
@@ -2684,7 +2688,7 @@ impl Build {
2684
2688
if let Some ( c) = & self . compiler {
2685
2689
return Ok ( Tool :: new (
2686
2690
( * * c) . to_owned ( ) ,
2687
- & self . cached_compiler_family ,
2691
+ & self . build_cache . cached_compiler_family ,
2688
2692
& self . cargo_output ,
2689
2693
out_dir,
2690
2694
) ) ;
@@ -2725,7 +2729,7 @@ impl Build {
2725
2729
let mut t = Tool :: with_clang_driver (
2726
2730
tool,
2727
2731
driver_mode,
2728
- & self . cached_compiler_family ,
2732
+ & self . build_cache . cached_compiler_family ,
2729
2733
& self . cargo_output ,
2730
2734
out_dir,
2731
2735
) ;
@@ -2752,7 +2756,7 @@ impl Build {
2752
2756
} else {
2753
2757
Some ( Tool :: new (
2754
2758
PathBuf :: from ( tool) ,
2755
- & self . cached_compiler_family ,
2759
+ & self . build_cache . cached_compiler_family ,
2756
2760
& self . cargo_output ,
2757
2761
out_dir,
2758
2762
) )
@@ -2817,7 +2821,7 @@ impl Build {
2817
2821
2818
2822
let mut t = Tool :: new (
2819
2823
PathBuf :: from ( compiler) ,
2820
- & self . cached_compiler_family ,
2824
+ & self . build_cache . cached_compiler_family ,
2821
2825
& self . cargo_output ,
2822
2826
out_dir,
2823
2827
) ;
@@ -2841,7 +2845,7 @@ impl Build {
2841
2845
nvcc,
2842
2846
None ,
2843
2847
self . cuda ,
2844
- & self . cached_compiler_family ,
2848
+ & self . build_cache . cached_compiler_family ,
2845
2849
& self . cargo_output ,
2846
2850
out_dir,
2847
2851
) ;
@@ -3466,10 +3470,13 @@ impl Build {
3466
3470
. or_else ( || prefixes. first ( ) . copied ( ) )
3467
3471
}
3468
3472
3469
- fn get_target ( & self ) -> Result < TargetInfo , Error > {
3473
+ fn get_target ( & self ) -> Result < TargetInfo < ' _ > , Error > {
3470
3474
match & self . target {
3471
3475
Some ( t) => t. parse ( ) ,
3472
- None => TargetInfo :: from_cargo_environment_variables ( ) ,
3476
+ None => self
3477
+ . build_cache
3478
+ . target_info_parser
3479
+ . parse_from_cargo_environment_variables ( ) ,
3473
3480
}
3474
3481
}
3475
3482
@@ -3509,7 +3516,7 @@ impl Build {
3509
3516
// Tentatively matches the DWARF version defaults as of rustc 1.62.
3510
3517
let target = self . get_target ( ) . ok ( ) ?;
3511
3518
if matches ! (
3512
- & * target. os,
3519
+ target. os,
3513
3520
"android" | "dragonfly" | "freebsd" | "netbsd" | "openbsd"
3514
3521
) || target. vendor == "apple"
3515
3522
|| ( target. os == "windows" && target. env == "gnu" )
@@ -3559,7 +3566,7 @@ impl Build {
3559
3566
_ => false ,
3560
3567
}
3561
3568
}
3562
- if let Some ( val) = self . env_cache . read ( ) . unwrap ( ) . get ( v) . cloned ( ) {
3569
+ if let Some ( val) = self . build_cache . env_cache . read ( ) . unwrap ( ) . get ( v) . cloned ( ) {
3563
3570
return val;
3564
3571
}
3565
3572
// Excluding `PATH` prevents spurious rebuilds on Windows, see
@@ -3574,7 +3581,11 @@ impl Build {
3574
3581
v,
3575
3582
OptionOsStrDisplay ( r. as_deref( ) )
3576
3583
) ) ;
3577
- self . env_cache . write ( ) . unwrap ( ) . insert ( v. into ( ) , r. clone ( ) ) ;
3584
+ self . build_cache
3585
+ . env_cache
3586
+ . write ( )
3587
+ . unwrap ( )
3588
+ . insert ( v. into ( ) , r. clone ( ) ) ;
3578
3589
r
3579
3590
}
3580
3591
@@ -3710,6 +3721,7 @@ impl Build {
3710
3721
3711
3722
fn apple_sdk_root ( & self , sdk : & str ) -> Result < Arc < OsStr > , Error > {
3712
3723
if let Some ( ret) = self
3724
+ . build_cache
3713
3725
. apple_sdk_root_cache
3714
3726
. read ( )
3715
3727
. expect ( "apple_sdk_root_cache lock failed" )
@@ -3719,16 +3731,18 @@ impl Build {
3719
3731
return Ok ( ret) ;
3720
3732
}
3721
3733
let sdk_path = self . apple_sdk_root_inner ( sdk) ?;
3722
- self . apple_sdk_root_cache
3734
+ self . build_cache
3735
+ . apple_sdk_root_cache
3723
3736
. write ( )
3724
3737
. expect ( "apple_sdk_root_cache lock failed" )
3725
3738
. insert ( sdk. into ( ) , sdk_path. clone ( ) ) ;
3726
3739
Ok ( sdk_path)
3727
3740
}
3728
3741
3729
- fn apple_deployment_target ( & self , target : & TargetInfo ) -> Arc < str > {
3742
+ fn apple_deployment_target ( & self , target : & TargetInfo < ' _ > ) -> Arc < str > {
3730
3743
let sdk = target. apple_sdk_name ( ) ;
3731
3744
if let Some ( ret) = self
3745
+ . build_cache
3732
3746
. apple_versions_cache
3733
3747
. read ( )
3734
3748
. expect ( "apple_versions_cache lock failed" )
@@ -3778,7 +3792,7 @@ impl Build {
3778
3792
. split ( '.' )
3779
3793
. map ( |v| v. parse :: < u32 > ( ) . expect ( "integer version" ) ) ;
3780
3794
3781
- match & * target. os {
3795
+ match target. os {
3782
3796
"macos" => {
3783
3797
let major = deployment_target. next ( ) . unwrap_or ( 0 ) ;
3784
3798
let minor = deployment_target. next ( ) . unwrap_or ( 0 ) ;
@@ -3823,7 +3837,7 @@ impl Build {
3823
3837
//
3824
3838
// The ordering of env -> XCode SDK -> old rustc defaults is intentional for performance when using
3825
3839
// an explicit target.
3826
- let version: Arc < str > = match & * target. os {
3840
+ let version: Arc < str > = match target. os {
3827
3841
"macos" => deployment_from_env ( "MACOSX_DEPLOYMENT_TARGET" )
3828
3842
. and_then ( maybe_cpp_version_baseline)
3829
3843
. or_else ( default_deployment_from_sdk)
@@ -3856,7 +3870,8 @@ impl Build {
3856
3870
os => unreachable ! ( "unknown Apple OS: {}" , os) ,
3857
3871
} ;
3858
3872
3859
- self . apple_versions_cache
3873
+ self . build_cache
3874
+ . apple_versions_cache
3860
3875
. write ( )
3861
3876
. expect ( "apple_versions_cache lock failed" )
3862
3877
. insert ( sdk. into ( ) , version. clone ( ) ) ;
@@ -3930,12 +3945,12 @@ impl Build {
3930
3945
None
3931
3946
}
3932
3947
3933
- fn windows_registry_find ( & self , target : & TargetInfo , tool : & str ) -> Option < Command > {
3948
+ fn windows_registry_find ( & self , target : & TargetInfo < ' _ > , tool : & str ) -> Option < Command > {
3934
3949
self . windows_registry_find_tool ( target, tool)
3935
3950
. map ( |c| c. to_command ( ) )
3936
3951
}
3937
3952
3938
- fn windows_registry_find_tool ( & self , target : & TargetInfo , tool : & str ) -> Option < Tool > {
3953
+ fn windows_registry_find_tool ( & self , target : & TargetInfo < ' _ > , tool : & str ) -> Option < Tool > {
3939
3954
struct BuildEnvGetter < ' s > ( & ' s Build ) ;
3940
3955
3941
3956
impl windows_registry:: EnvGetter for BuildEnvGetter < ' _ > {
@@ -4074,8 +4089,8 @@ fn autodetect_android_compiler(raw_target: &str, gnu: &str, clang: &str) -> Stri
4074
4089
}
4075
4090
4076
4091
// Rust and clang/cc don't agree on how to name the target.
4077
- fn map_darwin_target_from_rust_to_compiler_architecture ( target : & TargetInfo ) -> & str {
4078
- match & * target. full_arch {
4092
+ fn map_darwin_target_from_rust_to_compiler_architecture < ' a > ( target : & TargetInfo < ' a > ) -> & ' a str {
4093
+ match target. full_arch {
4079
4094
"aarch64" => "arm64" ,
4080
4095
"arm64_32" => "arm64_32" ,
4081
4096
"arm64e" => "arm64e" ,
0 commit comments