Skip to content

Commit 9eb0c38

Browse files
authored
Reduce size of cc::Build and size of generated targets (#1257)
1 parent c3ad44e commit 9eb0c38

File tree

12 files changed

+2246
-2142
lines changed

12 files changed

+2246
-2142
lines changed

dev-tools/gen-target-info/src/main.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ const PRELUDE: &str = r#"//! This file is generated code. Please edit the genera
1212

1313
fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std::io::Result<()> {
1414
writeln!(f, "use super::TargetInfo;")?;
15-
writeln!(f, "use std::borrow::Cow;")?;
1615
writeln!(f)?;
17-
writeln!(f, "pub(crate) const LIST: &[(&str, TargetInfo)] = &[")?;
16+
writeln!(
17+
f,
18+
"pub(crate) const LIST: &[(&str, TargetInfo<'static>)] = &["
19+
)?;
1820

1921
for (triple, spec) in &target_specs.0 {
2022
let full_arch = triple.split_once('-').unwrap().0;
@@ -42,15 +44,15 @@ fn generate_target_mapping(f: &mut File, target_specs: &RustcTargetSpecs) -> std
4244
writeln!(f, " (")?;
4345
writeln!(f, " {triple:?},")?;
4446
writeln!(f, " TargetInfo {{")?;
45-
writeln!(f, " full_arch: Cow::Borrowed({full_arch:?}),")?;
46-
writeln!(f, " arch: Cow::Borrowed({arch:?}),")?;
47-
writeln!(f, " vendor: Cow::Borrowed({vendor:?}),")?;
48-
writeln!(f, " os: Cow::Borrowed({os:?}),")?;
49-
writeln!(f, " env: Cow::Borrowed({env:?}),")?;
50-
writeln!(f, " abi: Cow::Borrowed({abi:?}),")?;
47+
writeln!(f, " full_arch: {full_arch:?},")?;
48+
writeln!(f, " arch: {arch:?},")?;
49+
writeln!(f, " vendor: {vendor:?},")?;
50+
writeln!(f, " os: {os:?},")?;
51+
writeln!(f, " env: {env:?},")?;
52+
writeln!(f, " abi: {abi:?},")?;
5153
writeln!(
5254
f,
53-
" unversioned_llvm_target: Cow::Borrowed({unversioned_llvm_target:?}),"
55+
" unversioned_llvm_target: {unversioned_llvm_target:?},"
5456
)?;
5557
writeln!(f, " }},")?;
5658
writeln!(f, " ),")?;

src/lib.rs

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,16 @@ struct CompilerFlag {
259259

260260
type Env = Option<Arc<OsStr>>;
261261

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+
262272
/// A builder for compilation of a native library.
263273
///
264274
/// A `Build` is the main type of the `cc` crate and is used to control all the
@@ -271,7 +281,6 @@ pub struct Build {
271281
objects: Vec<Arc<Path>>,
272282
flags: Vec<Arc<OsStr>>,
273283
flags_supported: Vec<Arc<OsStr>>,
274-
known_flag_support_status_cache: Arc<RwLock<HashMap<CompilerFlag, bool>>>,
275284
ar_flags: Vec<Arc<OsStr>>,
276285
asm_flags: Vec<Arc<OsStr>>,
277286
no_default_flags: bool,
@@ -306,12 +315,9 @@ pub struct Build {
306315
warnings_into_errors: bool,
307316
warnings: Option<bool>,
308317
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>>>>,
312318
emit_rerun_if_env_changed: bool,
313-
cached_compiler_family: Arc<RwLock<HashMap<Box<Path>, ToolFamily>>>,
314319
shell_escaped_flags: Option<bool>,
320+
build_cache: Arc<BuildCache>,
315321
}
316322

317323
/// Represents the types of errors that may occur while using cc-rs.
@@ -399,7 +405,6 @@ impl Build {
399405
objects: Vec::new(),
400406
flags: Vec::new(),
401407
flags_supported: Vec::new(),
402-
known_flag_support_status_cache: Arc::new(RwLock::new(HashMap::new())),
403408
ar_flags: Vec::new(),
404409
asm_flags: Vec::new(),
405410
no_default_flags: false,
@@ -431,12 +436,9 @@ impl Build {
431436
warnings: None,
432437
extra_warnings: None,
433438
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())),
437439
emit_rerun_if_env_changed: true,
438-
cached_compiler_family: Arc::default(),
439440
shell_escaped_flags: None,
441+
build_cache: Arc::default(),
440442
}
441443
}
442444

@@ -634,14 +636,15 @@ impl Build {
634636
&self,
635637
flag: &OsStr,
636638
compiler_path: &Path,
637-
target: &TargetInfo,
639+
target: &TargetInfo<'_>,
638640
) -> Result<bool, Error> {
639641
let compiler_flag = CompilerFlag {
640642
compiler: compiler_path.into(),
641643
flag: flag.into(),
642644
};
643645

644646
if let Some(is_supported) = self
647+
.build_cache
645648
.known_flag_support_status_cache
646649
.read()
647650
.unwrap()
@@ -686,7 +689,7 @@ impl Build {
686689
}
687690

688691
let mut cmd = compiler.to_command();
689-
let is_arm = matches!(&*target.arch, "aarch64" | "arm");
692+
let is_arm = matches!(target.arch, "aarch64" | "arm");
690693
let clang = compiler.is_like_clang();
691694
let gnu = compiler.family == ToolFamily::Gnu;
692695
command_add_output_file(
@@ -711,7 +714,8 @@ impl Build {
711714
let output = cmd.output()?;
712715
let is_supported = output.status.success() && output.stderr.is_empty();
713716

714-
self.known_flag_support_status_cache
717+
self.build_cache
718+
.known_flag_support_status_cache
715719
.write()
716720
.unwrap()
717721
.insert(compiler_flag, is_supported);
@@ -1433,7 +1437,7 @@ impl Build {
14331437
libtst = true;
14341438
} else if cfg!(target_env = "msvc") {
14351439
libdir.push("lib");
1436-
match &*target.arch {
1440+
match target.arch {
14371441
"x86_64" => {
14381442
libdir.push("x64");
14391443
libtst = true;
@@ -1725,7 +1729,7 @@ impl Build {
17251729
.map(Cow::Owned)?,
17261730
)
17271731
};
1728-
let is_arm = matches!(&*target.arch, "aarch64" | "arm");
1732+
let is_arm = matches!(target.arch, "aarch64" | "arm");
17291733
command_add_output_file(
17301734
&mut cmd,
17311735
&obj.dst,
@@ -1932,7 +1936,7 @@ impl Build {
19321936
fn add_default_flags(
19331937
&self,
19341938
cmd: &mut Tool,
1935-
target: &TargetInfo,
1939+
target: &TargetInfo<'_>,
19361940
opt_level: &str,
19371941
) -> Result<(), Error> {
19381942
let raw_target = self.get_raw_target()?;
@@ -2290,7 +2294,7 @@ impl Build {
22902294
// get the 32i/32imac/32imc/64gc/64imac/... part
22912295
let arch = &target.full_arch[5..];
22922296
if arch.starts_with("64") {
2293-
if matches!(&*target.os, "linux" | "freebsd" | "netbsd") {
2297+
if matches!(target.os, "linux" | "freebsd" | "netbsd") {
22942298
cmd.args.push(("-march=rv64gc").into());
22952299
cmd.args.push("-mabi=lp64d".into());
22962300
} else {
@@ -2528,7 +2532,7 @@ impl Build {
25282532

25292533
fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
25302534
let target = self.get_target()?;
2531-
let arch_str = &*target.full_arch;
2535+
let arch_str = target.full_arch;
25322536

25332537
let arch = if target.os == "macos" {
25342538
match arch_str {
@@ -2582,7 +2586,7 @@ impl Build {
25822586
}
25832587
};
25842588

2585-
let sdk_details = apple_os_sdk_parts(&target.os, &arch);
2589+
let sdk_details = apple_os_sdk_parts(target.os, &arch);
25862590
let min_version = self.apple_deployment_target(&target);
25872591

25882592
match arch {
@@ -2684,7 +2688,7 @@ impl Build {
26842688
if let Some(c) = &self.compiler {
26852689
return Ok(Tool::new(
26862690
(**c).to_owned(),
2687-
&self.cached_compiler_family,
2691+
&self.build_cache.cached_compiler_family,
26882692
&self.cargo_output,
26892693
out_dir,
26902694
));
@@ -2725,7 +2729,7 @@ impl Build {
27252729
let mut t = Tool::with_clang_driver(
27262730
tool,
27272731
driver_mode,
2728-
&self.cached_compiler_family,
2732+
&self.build_cache.cached_compiler_family,
27292733
&self.cargo_output,
27302734
out_dir,
27312735
);
@@ -2752,7 +2756,7 @@ impl Build {
27522756
} else {
27532757
Some(Tool::new(
27542758
PathBuf::from(tool),
2755-
&self.cached_compiler_family,
2759+
&self.build_cache.cached_compiler_family,
27562760
&self.cargo_output,
27572761
out_dir,
27582762
))
@@ -2817,7 +2821,7 @@ impl Build {
28172821

28182822
let mut t = Tool::new(
28192823
PathBuf::from(compiler),
2820-
&self.cached_compiler_family,
2824+
&self.build_cache.cached_compiler_family,
28212825
&self.cargo_output,
28222826
out_dir,
28232827
);
@@ -2841,7 +2845,7 @@ impl Build {
28412845
nvcc,
28422846
None,
28432847
self.cuda,
2844-
&self.cached_compiler_family,
2848+
&self.build_cache.cached_compiler_family,
28452849
&self.cargo_output,
28462850
out_dir,
28472851
);
@@ -3466,10 +3470,13 @@ impl Build {
34663470
.or_else(|| prefixes.first().copied())
34673471
}
34683472

3469-
fn get_target(&self) -> Result<TargetInfo, Error> {
3473+
fn get_target(&self) -> Result<TargetInfo<'_>, Error> {
34703474
match &self.target {
34713475
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(),
34733480
}
34743481
}
34753482

@@ -3509,7 +3516,7 @@ impl Build {
35093516
// Tentatively matches the DWARF version defaults as of rustc 1.62.
35103517
let target = self.get_target().ok()?;
35113518
if matches!(
3512-
&*target.os,
3519+
target.os,
35133520
"android" | "dragonfly" | "freebsd" | "netbsd" | "openbsd"
35143521
) || target.vendor == "apple"
35153522
|| (target.os == "windows" && target.env == "gnu")
@@ -3559,7 +3566,7 @@ impl Build {
35593566
_ => false,
35603567
}
35613568
}
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() {
35633570
return val;
35643571
}
35653572
// Excluding `PATH` prevents spurious rebuilds on Windows, see
@@ -3574,7 +3581,11 @@ impl Build {
35743581
v,
35753582
OptionOsStrDisplay(r.as_deref())
35763583
));
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());
35783589
r
35793590
}
35803591

@@ -3710,6 +3721,7 @@ impl Build {
37103721

37113722
fn apple_sdk_root(&self, sdk: &str) -> Result<Arc<OsStr>, Error> {
37123723
if let Some(ret) = self
3724+
.build_cache
37133725
.apple_sdk_root_cache
37143726
.read()
37153727
.expect("apple_sdk_root_cache lock failed")
@@ -3719,16 +3731,18 @@ impl Build {
37193731
return Ok(ret);
37203732
}
37213733
let sdk_path = self.apple_sdk_root_inner(sdk)?;
3722-
self.apple_sdk_root_cache
3734+
self.build_cache
3735+
.apple_sdk_root_cache
37233736
.write()
37243737
.expect("apple_sdk_root_cache lock failed")
37253738
.insert(sdk.into(), sdk_path.clone());
37263739
Ok(sdk_path)
37273740
}
37283741

3729-
fn apple_deployment_target(&self, target: &TargetInfo) -> Arc<str> {
3742+
fn apple_deployment_target(&self, target: &TargetInfo<'_>) -> Arc<str> {
37303743
let sdk = target.apple_sdk_name();
37313744
if let Some(ret) = self
3745+
.build_cache
37323746
.apple_versions_cache
37333747
.read()
37343748
.expect("apple_versions_cache lock failed")
@@ -3778,7 +3792,7 @@ impl Build {
37783792
.split('.')
37793793
.map(|v| v.parse::<u32>().expect("integer version"));
37803794

3781-
match &*target.os {
3795+
match target.os {
37823796
"macos" => {
37833797
let major = deployment_target.next().unwrap_or(0);
37843798
let minor = deployment_target.next().unwrap_or(0);
@@ -3823,7 +3837,7 @@ impl Build {
38233837
//
38243838
// The ordering of env -> XCode SDK -> old rustc defaults is intentional for performance when using
38253839
// an explicit target.
3826-
let version: Arc<str> = match &*target.os {
3840+
let version: Arc<str> = match target.os {
38273841
"macos" => deployment_from_env("MACOSX_DEPLOYMENT_TARGET")
38283842
.and_then(maybe_cpp_version_baseline)
38293843
.or_else(default_deployment_from_sdk)
@@ -3856,7 +3870,8 @@ impl Build {
38563870
os => unreachable!("unknown Apple OS: {}", os),
38573871
};
38583872

3859-
self.apple_versions_cache
3873+
self.build_cache
3874+
.apple_versions_cache
38603875
.write()
38613876
.expect("apple_versions_cache lock failed")
38623877
.insert(sdk.into(), version.clone());
@@ -3930,12 +3945,12 @@ impl Build {
39303945
None
39313946
}
39323947

3933-
fn windows_registry_find(&self, target: &TargetInfo, tool: &str) -> Option<Command> {
3948+
fn windows_registry_find(&self, target: &TargetInfo<'_>, tool: &str) -> Option<Command> {
39343949
self.windows_registry_find_tool(target, tool)
39353950
.map(|c| c.to_command())
39363951
}
39373952

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> {
39393954
struct BuildEnvGetter<'s>(&'s Build);
39403955

39413956
impl windows_registry::EnvGetter for BuildEnvGetter<'_> {
@@ -4074,8 +4089,8 @@ fn autodetect_android_compiler(raw_target: &str, gnu: &str, clang: &str) -> Stri
40744089
}
40754090

40764091
// 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 {
40794094
"aarch64" => "arm64",
40804095
"arm64_32" => "arm64_32",
40814096
"arm64e" => "arm64e",

src/parallel/job_token.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use std::marker::PhantomData;
22

3-
use crate::Error;
4-
5-
use super::once_lock::OnceLock;
3+
use crate::{utilities::OnceLock, Error};
64

75
pub(crate) struct JobToken(PhantomData<()>);
86

src/parallel/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
pub(crate) mod async_executor;
22
pub(crate) mod job_token;
3-
pub(crate) mod once_lock;
43
pub(crate) mod stderr;

0 commit comments

Comments
 (0)