mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-05 12:25:13 +00:00
Use trimmed down deserialization impl for config
This reduces binary size from 10.1MiB (6.2MiB for just rustbuild code) to 9.7MiB (5.8MiB for just rustbuild code). This also reduces compile time from ~6.1s for incr recompilation to ~5.6s. There is still a lot of unnecessary code due to the toml crate monomorphizing every deserialization impl 5 times.
This commit is contained in:
parent
88609e5126
commit
a0b4d2136d
@ -17,7 +17,7 @@ use crate::channel::GitInfo;
|
||||
pub use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Flags};
|
||||
use crate::util::{exe, t};
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
macro_rules! check_ci_llvm {
|
||||
($name:expr) => {
|
||||
@ -364,13 +364,11 @@ impl Merge for TomlConfig {
|
||||
// rustbuild.
|
||||
macro_rules! define_config {
|
||||
($(#[$attr:meta])* struct $name:ident {
|
||||
$($field:ident: $field_ty:ty,)*
|
||||
$($field:ident: Option<$field_ty:ty> = $field_key:literal,)*
|
||||
}) => {
|
||||
$(#[$attr])*
|
||||
#[derive(Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
struct $name {
|
||||
$($field: $field_ty,)*
|
||||
$($field: Option<$field_ty>,)*
|
||||
}
|
||||
|
||||
impl Merge for $name {
|
||||
@ -382,6 +380,99 @@ macro_rules! define_config {
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
// The following is a trimmed version of what serde_derive generates. All parts not relevant
|
||||
// for toml deserialization have been removed. This reduces the binary size and improves
|
||||
// compile time of rustbuild.
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[allow(non_camel_case_types)]
|
||||
enum FieldName {
|
||||
$($field,)*
|
||||
}
|
||||
struct FieldNameVisitor;
|
||||
impl<'de> serde::de::Visitor<'de> for FieldNameVisitor {
|
||||
type Value = FieldName;
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("field identifier")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match value {
|
||||
$($field_key => Ok(FieldName::$field),)*
|
||||
_ => Err(serde::de::Error::unknown_field(value, FIELDS)),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'de> Deserialize<'de> for FieldName {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Deserializer::deserialize_identifier(deserializer, FieldNameVisitor)
|
||||
}
|
||||
}
|
||||
struct Field;
|
||||
impl<'de> serde::de::Visitor<'de> for Field {
|
||||
type Value = $name;
|
||||
fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(concat!("struct ", stringify!($name)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::MapAccess<'de>,
|
||||
{
|
||||
$(let mut $field: Option<$field_ty> = None;)*
|
||||
while let Some(key) =
|
||||
match serde::de::MapAccess::next_key::<FieldName>(&mut map) {
|
||||
Ok(val) => val,
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
{
|
||||
match key {
|
||||
$(FieldName::$field => {
|
||||
if $field.is_some() {
|
||||
return Err(<A::Error as serde::de::Error>::duplicate_field(
|
||||
$field_key,
|
||||
));
|
||||
}
|
||||
$field = match serde::de::MapAccess::next_value::<$field_ty>(
|
||||
&mut map,
|
||||
) {
|
||||
Ok(val) => Some(val),
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
})*
|
||||
}
|
||||
}
|
||||
Ok($name { $($field),* })
|
||||
}
|
||||
}
|
||||
const FIELDS: &'static [&'static str] = &[
|
||||
$($field_key,)*
|
||||
];
|
||||
Deserializer::deserialize_struct(
|
||||
deserializer,
|
||||
stringify!($name),
|
||||
FIELDS,
|
||||
Field,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,101 +480,101 @@ define_config! {
|
||||
/// TOML representation of various global build decisions.
|
||||
#[derive(Default)]
|
||||
struct Build {
|
||||
build: Option<String>,
|
||||
host: Option<Vec<String>>,
|
||||
target: Option<Vec<String>>,
|
||||
build_dir: Option<String>,
|
||||
cargo: Option<String>,
|
||||
rustc: Option<String>,
|
||||
rustfmt: Option<PathBuf>,
|
||||
docs: Option<bool>,
|
||||
compiler_docs: Option<bool>,
|
||||
docs_minification: Option<bool>,
|
||||
submodules: Option<bool>,
|
||||
fast_submodules: Option<bool>,
|
||||
gdb: Option<String>,
|
||||
nodejs: Option<String>,
|
||||
npm: Option<String>,
|
||||
python: Option<String>,
|
||||
locked_deps: Option<bool>,
|
||||
vendor: Option<bool>,
|
||||
full_bootstrap: Option<bool>,
|
||||
extended: Option<bool>,
|
||||
tools: Option<HashSet<String>>,
|
||||
verbose: Option<usize>,
|
||||
sanitizers: Option<bool>,
|
||||
profiler: Option<bool>,
|
||||
cargo_native_static: Option<bool>,
|
||||
low_priority: Option<bool>,
|
||||
configure_args: Option<Vec<String>>,
|
||||
local_rebuild: Option<bool>,
|
||||
print_step_timings: Option<bool>,
|
||||
print_step_rusage: Option<bool>,
|
||||
check_stage: Option<u32>,
|
||||
doc_stage: Option<u32>,
|
||||
build_stage: Option<u32>,
|
||||
test_stage: Option<u32>,
|
||||
install_stage: Option<u32>,
|
||||
dist_stage: Option<u32>,
|
||||
bench_stage: Option<u32>,
|
||||
patch_binaries_for_nix: Option<bool>,
|
||||
build: Option<String> = "build",
|
||||
host: Option<Vec<String>> = "host",
|
||||
target: Option<Vec<String>> = "target",
|
||||
build_dir: Option<String> = "build-dir",
|
||||
cargo: Option<String> = "cargo",
|
||||
rustc: Option<String> = "rustc",
|
||||
rustfmt: Option<PathBuf> = "rustfmt",
|
||||
docs: Option<bool> = "docs",
|
||||
compiler_docs: Option<bool> = "compiler-docs",
|
||||
docs_minification: Option<bool> = "docs-minification",
|
||||
submodules: Option<bool> = "submodules",
|
||||
fast_submodules: Option<bool> = "fast-submodules",
|
||||
gdb: Option<String> = "gdb",
|
||||
nodejs: Option<String> = "nodejs",
|
||||
npm: Option<String> = "npm",
|
||||
python: Option<String> = "python",
|
||||
locked_deps: Option<bool> = "locked-deps",
|
||||
vendor: Option<bool> = "vendor",
|
||||
full_bootstrap: Option<bool> = "full-bootstrap",
|
||||
extended: Option<bool> = "extended",
|
||||
tools: Option<HashSet<String>> = "tools",
|
||||
verbose: Option<usize> = "verbose",
|
||||
sanitizers: Option<bool> = "sanitizers",
|
||||
profiler: Option<bool> = "profiler",
|
||||
cargo_native_static: Option<bool> = "cargo-native-static",
|
||||
low_priority: Option<bool> = "low-priority",
|
||||
configure_args: Option<Vec<String>> = "configure-args",
|
||||
local_rebuild: Option<bool> = "local-rebuild",
|
||||
print_step_timings: Option<bool> = "print-step-timings",
|
||||
print_step_rusage: Option<bool> = "print-step-rusage",
|
||||
check_stage: Option<u32> = "check-stage",
|
||||
doc_stage: Option<u32> = "doc-stage",
|
||||
build_stage: Option<u32> = "build-stage",
|
||||
test_stage: Option<u32> = "test-stage",
|
||||
install_stage: Option<u32> = "install-stage",
|
||||
dist_stage: Option<u32> = "dist-stage",
|
||||
bench_stage: Option<u32> = "bench-stage",
|
||||
patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix",
|
||||
}
|
||||
}
|
||||
|
||||
define_config! {
|
||||
/// TOML representation of various global install decisions.
|
||||
struct Install {
|
||||
prefix: Option<String>,
|
||||
sysconfdir: Option<String>,
|
||||
docdir: Option<String>,
|
||||
bindir: Option<String>,
|
||||
libdir: Option<String>,
|
||||
mandir: Option<String>,
|
||||
datadir: Option<String>,
|
||||
prefix: Option<String> = "prefix",
|
||||
sysconfdir: Option<String> = "sysconfdir",
|
||||
docdir: Option<String> = "docdir",
|
||||
bindir: Option<String> = "bindir",
|
||||
libdir: Option<String> = "libdir",
|
||||
mandir: Option<String> = "mandir",
|
||||
datadir: Option<String> = "datadir",
|
||||
}
|
||||
}
|
||||
|
||||
define_config! {
|
||||
/// TOML representation of how the LLVM build is configured.
|
||||
struct Llvm {
|
||||
skip_rebuild: Option<bool>,
|
||||
optimize: Option<bool>,
|
||||
thin_lto: Option<bool>,
|
||||
release_debuginfo: Option<bool>,
|
||||
assertions: Option<bool>,
|
||||
tests: Option<bool>,
|
||||
plugins: Option<bool>,
|
||||
ccache: Option<StringOrBool>,
|
||||
version_check: Option<bool>,
|
||||
static_libstdcpp: Option<bool>,
|
||||
ninja: Option<bool>,
|
||||
targets: Option<String>,
|
||||
experimental_targets: Option<String>,
|
||||
link_jobs: Option<u32>,
|
||||
link_shared: Option<bool>,
|
||||
version_suffix: Option<String>,
|
||||
clang_cl: Option<String>,
|
||||
cflags: Option<String>,
|
||||
cxxflags: Option<String>,
|
||||
ldflags: Option<String>,
|
||||
use_libcxx: Option<bool>,
|
||||
use_linker: Option<String>,
|
||||
allow_old_toolchain: Option<bool>,
|
||||
polly: Option<bool>,
|
||||
clang: Option<bool>,
|
||||
download_ci_llvm: Option<StringOrBool>,
|
||||
build_config: Option<HashMap<String, String>>,
|
||||
skip_rebuild: Option<bool> = "skip-rebuild",
|
||||
optimize: Option<bool> = "optimize",
|
||||
thin_lto: Option<bool> = "thin-lto",
|
||||
release_debuginfo: Option<bool> = "release-debuginfo",
|
||||
assertions: Option<bool> = "assertions",
|
||||
tests: Option<bool> = "tests",
|
||||
plugins: Option<bool> = "plugins",
|
||||
ccache: Option<StringOrBool> = "ccache",
|
||||
version_check: Option<bool> = "version-check",
|
||||
static_libstdcpp: Option<bool> = "static-libstdcpp",
|
||||
ninja: Option<bool> = "ninja",
|
||||
targets: Option<String> = "targets",
|
||||
experimental_targets: Option<String> = "experimental-targets",
|
||||
link_jobs: Option<u32> = "link-jobs",
|
||||
link_shared: Option<bool> = "link-shared",
|
||||
version_suffix: Option<String> = "version-suffix",
|
||||
clang_cl: Option<String> = "clang-cl",
|
||||
cflags: Option<String> = "cflags",
|
||||
cxxflags: Option<String> = "cxxflags",
|
||||
ldflags: Option<String> = "ldflags",
|
||||
use_libcxx: Option<bool> = "use-libcxx",
|
||||
use_linker: Option<String> = "use-linker",
|
||||
allow_old_toolchain: Option<bool> = "allow-old-toolchain",
|
||||
polly: Option<bool> = "polly",
|
||||
clang: Option<bool> = "clang",
|
||||
download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
|
||||
build_config: Option<HashMap<String, String>> = "build-config",
|
||||
}
|
||||
}
|
||||
|
||||
define_config! {
|
||||
struct Dist {
|
||||
sign_folder: Option<String>,
|
||||
gpg_password_file: Option<String>,
|
||||
upload_addr: Option<String>,
|
||||
src_tarball: Option<bool>,
|
||||
missing_tools: Option<bool>,
|
||||
compression_formats: Option<Vec<String>>,
|
||||
sign_folder: Option<String> = "sign-folder",
|
||||
gpg_password_file: Option<String> = "gpg-password-file",
|
||||
upload_addr: Option<String> = "upload-addr",
|
||||
src_tarball: Option<bool> = "src-tarball",
|
||||
missing_tools: Option<bool> = "missing-tools",
|
||||
compression_formats: Option<Vec<String>> = "compression-formats",
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,76 +594,76 @@ impl Default for StringOrBool {
|
||||
define_config! {
|
||||
/// TOML representation of how the Rust build is configured.
|
||||
struct Rust {
|
||||
optimize: Option<bool>,
|
||||
debug: Option<bool>,
|
||||
codegen_units: Option<u32>,
|
||||
codegen_units_std: Option<u32>,
|
||||
debug_assertions: Option<bool>,
|
||||
debug_assertions_std: Option<bool>,
|
||||
overflow_checks: Option<bool>,
|
||||
overflow_checks_std: Option<bool>,
|
||||
debug_logging: Option<bool>,
|
||||
debuginfo_level: Option<u32>,
|
||||
debuginfo_level_rustc: Option<u32>,
|
||||
debuginfo_level_std: Option<u32>,
|
||||
debuginfo_level_tools: Option<u32>,
|
||||
debuginfo_level_tests: Option<u32>,
|
||||
run_dsymutil: Option<bool>,
|
||||
backtrace: Option<bool>,
|
||||
incremental: Option<bool>,
|
||||
parallel_compiler: Option<bool>,
|
||||
default_linker: Option<String>,
|
||||
channel: Option<String>,
|
||||
description: Option<String>,
|
||||
musl_root: Option<String>,
|
||||
rpath: Option<bool>,
|
||||
verbose_tests: Option<bool>,
|
||||
optimize_tests: Option<bool>,
|
||||
codegen_tests: Option<bool>,
|
||||
ignore_git: Option<bool>,
|
||||
dist_src: Option<bool>,
|
||||
save_toolstates: Option<String>,
|
||||
codegen_backends: Option<Vec<String>>,
|
||||
lld: Option<bool>,
|
||||
use_lld: Option<bool>,
|
||||
llvm_tools: Option<bool>,
|
||||
deny_warnings: Option<bool>,
|
||||
backtrace_on_ice: Option<bool>,
|
||||
verify_llvm_ir: Option<bool>,
|
||||
thin_lto_import_instr_limit: Option<u32>,
|
||||
remap_debuginfo: Option<bool>,
|
||||
jemalloc: Option<bool>,
|
||||
test_compare_mode: Option<bool>,
|
||||
llvm_libunwind: Option<String>,
|
||||
control_flow_guard: Option<bool>,
|
||||
new_symbol_mangling: Option<bool>,
|
||||
profile_generate: Option<String>,
|
||||
profile_use: Option<String>,
|
||||
optimize: Option<bool> = "optimize",
|
||||
debug: Option<bool> = "debug",
|
||||
codegen_units: Option<u32> = "codegen-units",
|
||||
codegen_units_std: Option<u32> = "codegen-units-std",
|
||||
debug_assertions: Option<bool> = "debug-assertions",
|
||||
debug_assertions_std: Option<bool> = "debug-assertions-std",
|
||||
overflow_checks: Option<bool> = "overflow-checks",
|
||||
overflow_checks_std: Option<bool> = "overflow-checks-std",
|
||||
debug_logging: Option<bool> = "debug-logging",
|
||||
debuginfo_level: Option<u32> = "debuginfo-level",
|
||||
debuginfo_level_rustc: Option<u32> = "debuginfo-level-rustc",
|
||||
debuginfo_level_std: Option<u32> = "debuginfo-level-std",
|
||||
debuginfo_level_tools: Option<u32> = "debuginfo-level-tools",
|
||||
debuginfo_level_tests: Option<u32> = "debuginfo-level-tests",
|
||||
run_dsymutil: Option<bool> = "run-dsymutil",
|
||||
backtrace: Option<bool> = "backtrace",
|
||||
incremental: Option<bool> = "incremental",
|
||||
parallel_compiler: Option<bool> = "parallel-compiler",
|
||||
default_linker: Option<String> = "default-linker",
|
||||
channel: Option<String> = "channel",
|
||||
description: Option<String> = "description",
|
||||
musl_root: Option<String> = "musl-root",
|
||||
rpath: Option<bool> = "rpath",
|
||||
verbose_tests: Option<bool> = "verbose-tests",
|
||||
optimize_tests: Option<bool> = "optimize-tests",
|
||||
codegen_tests: Option<bool> = "codegen-tests",
|
||||
ignore_git: Option<bool> = "ignore-git",
|
||||
dist_src: Option<bool> = "dist-src",
|
||||
save_toolstates: Option<String> = "save-toolstates",
|
||||
codegen_backends: Option<Vec<String>> = "codegen-backends",
|
||||
lld: Option<bool> = "lld",
|
||||
use_lld: Option<bool> = "use-lld",
|
||||
llvm_tools: Option<bool> = "llvm-tools",
|
||||
deny_warnings: Option<bool> = "deny-warnings",
|
||||
backtrace_on_ice: Option<bool> = "backtrace-on-ice",
|
||||
verify_llvm_ir: Option<bool> = "verify-llvm-ir",
|
||||
thin_lto_import_instr_limit: Option<u32> = "thin-lto-import-instr-limit",
|
||||
remap_debuginfo: Option<bool> = "remap-debuginfo",
|
||||
jemalloc: Option<bool> = "jemalloc",
|
||||
test_compare_mode: Option<bool> = "test-compare-mode",
|
||||
llvm_libunwind: Option<String> = "llvm-libunwind",
|
||||
control_flow_guard: Option<bool> = "control-flow-guard",
|
||||
new_symbol_mangling: Option<bool> = "new-symbol-mangling",
|
||||
profile_generate: Option<String> = "profile-generate",
|
||||
profile_use: Option<String> = "profile-use",
|
||||
// ignored; this is set from an env var set by bootstrap.py
|
||||
download_rustc: Option<StringOrBool>,
|
||||
download_rustc: Option<StringOrBool> = "download-rustc",
|
||||
}
|
||||
}
|
||||
|
||||
define_config! {
|
||||
/// TOML representation of how each build target is configured.
|
||||
struct TomlTarget {
|
||||
cc: Option<String>,
|
||||
cxx: Option<String>,
|
||||
ar: Option<String>,
|
||||
ranlib: Option<String>,
|
||||
default_linker: Option<PathBuf>,
|
||||
linker: Option<String>,
|
||||
llvm_config: Option<String>,
|
||||
llvm_filecheck: Option<String>,
|
||||
android_ndk: Option<String>,
|
||||
sanitizers: Option<bool>,
|
||||
profiler: Option<bool>,
|
||||
crt_static: Option<bool>,
|
||||
musl_root: Option<String>,
|
||||
musl_libdir: Option<String>,
|
||||
wasi_root: Option<String>,
|
||||
qemu_rootfs: Option<String>,
|
||||
no_std: Option<bool>,
|
||||
cc: Option<String> = "cc",
|
||||
cxx: Option<String> = "cxx",
|
||||
ar: Option<String> = "ar",
|
||||
ranlib: Option<String> = "ranlib",
|
||||
default_linker: Option<PathBuf> = "default-linker",
|
||||
linker: Option<String> = "linker",
|
||||
llvm_config: Option<String> = "llvm-config",
|
||||
llvm_filecheck: Option<String> = "llvm-filecheck",
|
||||
android_ndk: Option<String> = "android-ndk",
|
||||
sanitizers: Option<bool> = "sanitizers",
|
||||
profiler: Option<bool> = "profiler",
|
||||
crt_static: Option<bool> = "crt-static",
|
||||
musl_root: Option<String> = "musl-root",
|
||||
musl_libdir: Option<String> = "musl-libdir",
|
||||
wasi_root: Option<String> = "wasi-root",
|
||||
qemu_rootfs: Option<String> = "qemu-rootfs",
|
||||
no_std: Option<bool> = "no-std",
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user