From 77c3d6edfa30cf4c9dc010d96324f6f72579f36b Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 18 Aug 2025 09:37:50 +0530 Subject: [PATCH 01/10] remove default config --- src/bootstrap/src/core/config/config.rs | 1068 +++++++++++------------ src/bootstrap/src/core/config/mod.rs | 6 - src/bootstrap/src/core/download.rs | 71 +- 3 files changed, 563 insertions(+), 582 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 5eea54360238d..692c05456f69e 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -13,7 +13,6 @@ //! and the `bootstrap.toml` file—merging them, applying defaults, and performing //! cross-component validation. The main `parse_inner` function and its supporting //! helpers reside here, transforming raw `Toml` data into the structured `Config` type. - use std::cell::Cell; use std::collections::{BTreeSet, HashMap, HashSet}; use std::io::IsTerminal; @@ -48,7 +47,7 @@ use crate::core::config::toml::rust::{ use crate::core::config::toml::target::Target; use crate::core::config::{ DebuginfoLevel, DryRun, GccCiMode, LlvmLibunwind, Merge, ReplaceOpt, RustcLto, SplitDebuginfo, - StringOrBool, set, threads_from_config, + StringOrBool, threads_from_config, }; use crate::core::download::{ DownloadContext, download_beta_toolchain, is_download_ci_available, maybe_download_rustfmt, @@ -463,35 +462,32 @@ impl Config { "flags.exclude" = ?flags_exclude ); - // First initialize the bare minimum that we need for further operation - source directory - // and execution context. - let mut config = Config::default_opts(); - let exec_ctx = ExecutionContext::new(flags_verbose, flags_cmd.fail_fast()); + // Set config values based on flags. - config.exec_ctx = exec_ctx; + let mut exec_ctx = ExecutionContext::new(flags_verbose, flags_cmd.fail_fast()); + exec_ctx.set_dry_run(if flags_dry_run { DryRun::UserSelected } else { DryRun::Disabled }); + let mut src = { + let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + // Undo `src/bootstrap` + manifest_dir.parent().unwrap().parent().unwrap().to_owned() + }; - if let Some(src) = compute_src_directory(flags_src, &config.exec_ctx) { - config.src = src; + if let Some(src_) = compute_src_directory(flags_src, &exec_ctx) { + src = src_; } // Now load the TOML config, as soon as possible - let (mut toml, toml_path) = load_toml_config(&config.src, flags_config, &get_toml); - config.config = toml_path.clone(); - - postprocess_toml( - &mut toml, - &config.src, - toml_path, - config.exec_ctx(), - &flags_set, - &get_toml, - ); + let (mut toml, toml_path) = load_toml_config(&src, flags_config, &get_toml); + + let is_running_on_ci = flags_ci.unwrap_or(CiEnv::is_ci()); + + postprocess_toml(&mut toml, &src, toml_path.clone(), &exec_ctx, &flags_set, &get_toml); // Now override TOML values with flags, to make sure that we won't later override flags with // TOML values by accident instead, because flags have higher priority. let Build { description: build_description, - build: mut build_build, + build: build_build, host: build_host, target: build_target, build_dir: build_build_dir, @@ -538,7 +534,7 @@ impl Config { metrics: _, android_ndk: build_android_ndk, optimized_compiler_builtins: build_optimized_compiler_builtins, - jobs: mut build_jobs, + jobs: build_jobs, compiletest_diff_tool: build_compiletest_diff_tool, compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest, tidy_extra_checks: build_tidy_extra_checks, @@ -558,226 +554,179 @@ impl Config { } = toml.install.unwrap_or_default(); let Rust { - optimize: rust_optimize, + optimize: rust_optimize_, debug: rust_debug, - codegen_units: rust_codegen_units, - codegen_units_std: rust_codegen_units_std, + codegen_units: rust_codegen_units_, + codegen_units_std: rust_codegen_units_std_, rustc_debug_assertions: rust_rustc_debug_assertions, std_debug_assertions: rust_std_debug_assertions, tools_debug_assertions: rust_tools_debug_assertions, - overflow_checks: rust_overflow_checks, - overflow_checks_std: rust_overflow_checks_std, - debug_logging: rust_debug_logging, + overflow_checks: rust_overflow_checks_, + overflow_checks_std: rust_overflow_checks_std_, + debug_logging: rust_debug_logging_, debuginfo_level: rust_debuginfo_level, - debuginfo_level_rustc: rust_debuginfo_level_rustc, - debuginfo_level_std: rust_debuginfo_level_std, - debuginfo_level_tools: rust_debuginfo_level_tools, - debuginfo_level_tests: rust_debuginfo_level_tests, + debuginfo_level_rustc: rust_debuginfo_level_rustc_, + debuginfo_level_std: rust_debuginfo_level_std_, + debuginfo_level_tools: rust_debuginfo_level_tools_, + debuginfo_level_tests: rust_debuginfo_level_tests_, backtrace: rust_backtrace, incremental: rust_incremental, - randomize_layout: rust_randomize_layout, + randomize_layout: rust_randomize_layout_, default_linker: rust_default_linker, channel: rust_channel, musl_root: rust_musl_root, - rpath: rust_rpath, + rpath: rust_rpath_, verbose_tests: rust_verbose_tests, - optimize_tests: rust_optimize_tests, + optimize_tests: rust_optimize_tests_, codegen_tests: rust_codegen_tests, omit_git_hash: rust_omit_git_hash, - dist_src: rust_dist_src, + dist_src: rust_dist_src_, save_toolstates: rust_save_toolstates, - codegen_backends: rust_codegen_backends, + codegen_backends: rust_codegen_backends_, lld: rust_lld_enabled, llvm_tools: rust_llvm_tools, llvm_bitcode_linker: rust_llvm_bitcode_linker, deny_warnings: rust_deny_warnings, backtrace_on_ice: rust_backtrace_on_ice, - verify_llvm_ir: rust_verify_llvm_ir, - thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit, - remap_debuginfo: rust_remap_debuginfo, + verify_llvm_ir: rust_verify_llvm_ir_, + thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit_, + remap_debuginfo: rust_remap_debuginfo_, jemalloc: rust_jemalloc, test_compare_mode: rust_test_compare_mode, llvm_libunwind: rust_llvm_libunwind, control_flow_guard: rust_control_flow_guard, ehcont_guard: rust_ehcont_guard, - new_symbol_mangling: rust_new_symbol_mangling, - profile_generate: rust_profile_generate, - profile_use: rust_profile_use, + new_symbol_mangling: rust_new_symbol_mangling_, + profile_generate: rust_profile_generate_, + profile_use: rust_profile_use_, download_rustc: rust_download_rustc, - lto: rust_lto, - validate_mir_opts: rust_validate_mir_opts, - frame_pointers: rust_frame_pointers, - stack_protector: rust_stack_protector, - strip: rust_strip, + lto: rust_lto_, + validate_mir_opts: rust_validate_mir_opts_, + frame_pointers: rust_frame_pointers_, + stack_protector: rust_stack_protector_, + strip: rust_strip_, lld_mode: rust_lld_mode, - std_features: rust_std_features, + std_features: rust_std_features_, } = toml.rust.unwrap_or_default(); let Llvm { - optimize: llvm_optimize, - thin_lto: llvm_thin_lto, - release_debuginfo: llvm_release_debuginfo, - assertions: llvm_assertions, - tests: llvm_tests, - enzyme: llvm_enzyme, + optimize: llvm_optimize_, + thin_lto: llvm_thin_lto_, + release_debuginfo: llvm_release_debuginfo_, + assertions: llvm_assertions_, + tests: llvm_tests_, + enzyme: llvm_enzyme_, plugins: llvm_plugin, static_libstdcpp: llvm_static_libstdcpp, - libzstd: llvm_libzstd, + libzstd: llvm_libzstd_, ninja: llvm_ninja, - targets: llvm_targets, - experimental_targets: llvm_experimental_targets, - link_jobs: llvm_link_jobs, - link_shared: llvm_link_shared, - version_suffix: llvm_version_suffix, - clang_cl: llvm_clang_cl, - cflags: llvm_cflags, - cxxflags: llvm_cxxflags, - ldflags: llvm_ldflags, - use_libcxx: llvm_use_libcxx, - use_linker: llvm_use_linker, - allow_old_toolchain: llvm_allow_old_toolchain, - offload: llvm_offload, - polly: llvm_polly, - clang: llvm_clang, - enable_warnings: llvm_enable_warnings, + targets: llvm_targets_, + experimental_targets: llvm_experimental_targets_, + link_jobs: llvm_link_jobs_, + link_shared: llvm_link_shared_, + version_suffix: llvm_version_suffix_, + clang_cl: llvm_clang_cl_, + cflags: llvm_cflags_, + cxxflags: llvm_cxxflags_, + ldflags: llvm_ldflags_, + use_libcxx: llvm_use_libcxx_, + use_linker: llvm_use_linker_, + allow_old_toolchain: llvm_allow_old_toolchain_, + offload: llvm_offload_, + polly: llvm_polly_, + clang: llvm_clang_, + enable_warnings: llvm_enable_warnings_, download_ci_llvm: llvm_download_ci_llvm, - build_config: llvm_build_config, + build_config: llvm_build_config_, } = toml.llvm.unwrap_or_default(); let Dist { - sign_folder: dist_sign_folder, - upload_addr: dist_upload_addr, - src_tarball: dist_src_tarball, - compression_formats: dist_compression_formats, - compression_profile: dist_compression_profile, - include_mingw_linker: dist_include_mingw_linker, - vendor: dist_vendor, + sign_folder: dist_sign_folder_, + upload_addr: dist_upload_addr_, + src_tarball: dist_src_tarball_, + compression_formats: dist_compression_formats_, + compression_profile: dist_compression_profile_, + include_mingw_linker: dist_include_mingw_linker_, + vendor: dist_vendor_, } = toml.dist.unwrap_or_default(); let Gcc { download_ci_gcc: gcc_download_ci_gcc } = toml.gcc.unwrap_or_default(); - if cfg!(test) { - // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the - // same ones used to call the tests (if custom ones are not defined in the toml). If we - // don't do that, bootstrap will use its own detection logic to find a suitable rustc - // and Cargo, which doesn't work when the caller is specìfying a custom local rustc or - // Cargo in their bootstrap.toml. - build_rustc = build_rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into())); - build_cargo = build_cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); - } - - build_jobs = flags_jobs.or(build_jobs); - build_build = flags_build.or(build_build); - - let build_dir = flags_build_dir.or(build_build_dir.map(PathBuf::from)); - let host = if let Some(TargetSelectionList(hosts)) = flags_host { - Some(hosts) - } else { - build_host - .map(|file_host| file_host.iter().map(|h| TargetSelection::from_user(h)).collect()) - }; - let target = if let Some(TargetSelectionList(targets)) = flags_target { - Some(targets) - } else { - build_target.map(|file_target| { - file_target.iter().map(|h| TargetSelection::from_user(h)).collect() - }) - }; - - if let Some(rustc) = &build_rustc - && !flags_skip_stage0_validation - { - check_stage0_version(rustc, "rustc", &config.src, config.exec_ctx()); - } - if let Some(cargo) = &build_cargo - && !flags_skip_stage0_validation - { - check_stage0_version(cargo, "cargo", &config.src, config.exec_ctx()); + if rust_optimize_.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) { + eprintln!( + "WARNING: setting `optimize` to `false` is known to cause errors and \ + should be considered unsupported. Refer to `bootstrap.example.toml` \ + for more details." + ); } // Prefer CLI verbosity flags if set (`flags_verbose` > 0), otherwise take the value from // TOML. - config - .exec_ctx - .set_verbosity(cmp::max(build_verbose.unwrap_or_default() as u8, flags_verbose)); + exec_ctx.set_verbosity(cmp::max(build_verbose.unwrap_or_default() as u8, flags_verbose)); + + let stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); + let bootstrap_cache_path = build_bootstrap_cache_path; + let patch_binaries_for_nix = build_patch_binaries_for_nix; + + let path_modification_cache = Arc::new(Mutex::new(HashMap::new())); + + let host_target = flags_build + .or(build_build) + .map(|build| TargetSelection::from_user(&build)) + .unwrap_or_else(get_host_target); + let hosts = flags_host + .map(|TargetSelectionList(hosts)| hosts) + .or_else(|| { + build_host.map(|h| h.iter().map(|t| TargetSelection::from_user(t)).collect()) + }) + .unwrap_or_else(|| vec![host_target]); - let mut paths: Vec = flags_skip.into_iter().chain(flags_exclude).collect(); - if let Some(exclude) = build_exclude { - paths.extend(exclude); - } + let submodules = build_submodules; + let llvm_assertions = llvm_assertions_.unwrap_or(false); - // Set config values based on flags. - config.paths = flags_paths; - config.include_default_paths = flags_include_default_paths; - config.rustc_error_format = flags_rustc_error_format; - config.json_output = flags_json_output; - config.compile_time_deps = flags_compile_time_deps; - config.on_fail = flags_on_fail; - config.cmd = flags_cmd; - config.incremental = flags_incremental; - config.set_dry_run(if flags_dry_run { DryRun::UserSelected } else { DryRun::Disabled }); - config.dump_bootstrap_shims = flags_dump_bootstrap_shims; - config.keep_stage = flags_keep_stage; - config.keep_stage_std = flags_keep_stage_std; - config.color = flags_color; - config.free_args = flags_free_args; - config.llvm_profile_use = flags_llvm_profile_use; - config.llvm_profile_generate = flags_llvm_profile_generate; - config.enable_bolt_settings = flags_enable_bolt_settings; - config.bypass_bootstrap_lock = flags_bypass_bootstrap_lock; - config.is_running_on_ci = flags_ci.unwrap_or(CiEnv::is_ci()); - config.skip_std_check_if_no_download_rustc = flags_skip_std_check_if_no_download_rustc; - - // Infer the rest of the configuration. + let mut target_config = HashMap::new(); + let mut download_rustc_commit = None; + let llvm_link_shared = Cell::default(); + let mut llvm_from_ci = false; + let mut channel = "dev".to_string(); + let mut out = flags_build_dir + .or(build_build_dir.map(PathBuf::from)) + .unwrap_or_else(|| PathBuf::from("build")); + let mut rust_info = GitInfo::Absent; if cfg!(test) { // Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly. - config.out = Path::new( - &env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"), - ) - .parent() - .unwrap() - .to_path_buf(); - } - - config.compiletest_allow_stage0 = build_compiletest_allow_stage0.unwrap_or(false); - config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); - - config.change_id = toml.change_id.inner; - - config.skip = paths - .into_iter() - .map(|p| { - // Never return top-level path here as it would break `--skip` - // logic on rustc's internal test framework which is utilized - // by compiletest. - if cfg!(windows) { - PathBuf::from(p.to_str().unwrap().replace('/', "\\")) - } else { - p - } - }) - .collect(); - - #[cfg(feature = "tracing")] - span!( - target: "CONFIG_HANDLING", - tracing::Level::TRACE, - "normalizing and combining `flag.skip`/`flag.exclude` paths", - "config.skip" = ?config.skip, - ); - - config.jobs = Some(threads_from_config(build_jobs.unwrap_or(0))); - if let Some(build) = build_build { - config.host_target = TargetSelection::from_user(&build); + if out == PathBuf::from("build") { + out = Path::new( + &env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"), + ) + .parent() + .unwrap() + .to_path_buf(); + } + // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the + // same ones used to call the tests (if custom ones are not defined in the toml). If we + // don't do that, bootstrap will use its own detection logic to find a suitable rustc + // and Cargo, which doesn't work when the caller is specìfying a custom local rustc or + // Cargo in their bootstrap.toml. + build_rustc = build_rustc.take().or(std::env::var_os("RUSTC").map(|p| p.into())); + build_cargo = build_cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); } - set(&mut config.out, build_dir); // NOTE: Bootstrap spawns various commands with different working directories. // To avoid writing to random places on the file system, `config.out` needs to be an absolute path. - if !config.out.is_absolute() { + if !out.is_absolute() { // `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead. - config.out = absolute(&config.out).expect("can't make empty path absolute"); + out = absolute(&out).expect("can't make empty path absolute"); + } + + if !flags_skip_stage0_validation { + if let Some(rustc) = &build_rustc { + check_stage0_version(rustc, "rustc", &src, &exec_ctx); + } + if let Some(cargo) = &build_cargo { + check_stage0_version(cargo, "cargo", &src, &exec_ctx); + } } if build_cargo_clippy.is_some() && build_rustc.is_none() { @@ -786,146 +735,74 @@ impl Config { ); } - config.initial_rustc = if let Some(rustc) = build_rustc { - rustc - } else { - let dwn_ctx = DownloadContext::from(&config); - download_beta_toolchain(dwn_ctx); - config - .out - .join(config.host_target) - .join("stage0") - .join("bin") - .join(exe("rustc", config.host_target)) - }; + let mut dwn_ctx = DownloadContext::new( + path_modification_cache.clone(), + &src, + rust_info.clone(), + &submodules, + download_rustc_commit.clone(), + host_target, + llvm_from_ci, + target_config.clone(), + out.clone(), + patch_binaries_for_nix, + &exec_ctx, + &stage0_metadata, + llvm_assertions, + &bootstrap_cache_path, + is_running_on_ci, + ); + + let initial_rustc = build_rustc.unwrap_or_else(|| { + download_beta_toolchain(&dwn_ctx); + out.join(host_target).join("stage0").join("bin").join(exe("rustc", host_target)) + }); - config.initial_sysroot = t!(PathBuf::from_str( - command(&config.initial_rustc) + let initial_sysroot = t!(PathBuf::from_str( + command(&initial_rustc) .args(["--print", "sysroot"]) .run_in_dry_run() - .run_capture_stdout(&config) + .run_capture_stdout(&exec_ctx) .stdout() .trim() )); - config.initial_cargo_clippy = build_cargo_clippy; - - config.initial_cargo = if let Some(cargo) = build_cargo { - cargo - } else { - let dwn_ctx = DownloadContext::from(&config); - download_beta_toolchain(dwn_ctx); - config.initial_sysroot.join("bin").join(exe("cargo", config.host_target)) - }; + let initial_cargo = build_cargo.unwrap_or_else(|| { + download_beta_toolchain(&mut dwn_ctx); + initial_sysroot.join("bin").join(exe("cargo", host_target)) + }); // NOTE: it's important this comes *after* we set `initial_rustc` just above. - if config.dry_run() { - let dir = config.out.join("tmp-dry-run"); - t!(fs::create_dir_all(&dir)); - config.out = dir; + if exec_ctx.dry_run() { + out = out.join("tmp-dry-run"); + fs::create_dir_all(&out).expect("Failed to create dry-run directory"); + dwn_ctx.out = out.clone(); } - config.hosts = if let Some(hosts) = host { hosts } else { vec![config.host_target] }; - config.targets = if let Some(targets) = target { - targets - } else { - // If target is *not* configured, then default to the host - // toolchains. - config.hosts.clone() - }; - - config.nodejs = build_nodejs.map(PathBuf::from); - config.npm = build_npm.map(PathBuf::from); - config.gdb = build_gdb.map(PathBuf::from); - config.lldb = build_lldb.map(PathBuf::from); - config.python = build_python.map(PathBuf::from); - config.reuse = build_reuse.map(PathBuf::from); - config.submodules = build_submodules; - config.android_ndk = build_android_ndk; - config.bootstrap_cache_path = build_bootstrap_cache_path; - set(&mut config.low_priority, build_low_priority); - set(&mut config.compiler_docs, build_compiler_docs); - set(&mut config.library_docs_private_items, build_library_docs_private_items); - set(&mut config.docs_minification, build_docs_minification); - set(&mut config.docs, build_docs); - set(&mut config.locked_deps, build_locked_deps); - set(&mut config.full_bootstrap, build_full_bootstrap); - set(&mut config.extended, build_extended); - config.tools = build_tools; - set(&mut config.tool, build_tool); - set(&mut config.sanitizers, build_sanitizers); - set(&mut config.profiler, build_profiler); - set(&mut config.cargo_native_static, build_cargo_native_static); - set(&mut config.configure_args, build_configure_args); - set(&mut config.local_rebuild, build_local_rebuild); - set(&mut config.print_step_timings, build_print_step_timings); - set(&mut config.print_step_rusage, build_print_step_rusage); - config.patch_binaries_for_nix = build_patch_binaries_for_nix; - - // Verbose flag is a good default for `rust.verbose-tests`. - config.verbose_tests = config.is_verbose(); - - config.prefix = install_prefix.map(PathBuf::from); - config.sysconfdir = install_sysconfdir.map(PathBuf::from); - config.datadir = install_datadir.map(PathBuf::from); - config.docdir = install_docdir.map(PathBuf::from); - set(&mut config.bindir, install_bindir.map(PathBuf::from)); - config.libdir = install_libdir.map(PathBuf::from); - config.mandir = install_mandir.map(PathBuf::from); - - config.llvm_assertions = llvm_assertions.unwrap_or(false); - - let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel"))); + let file_content = t!(fs::read_to_string(src.join("src/ci/channel"))); let ci_channel = file_content.trim_end(); let is_user_configured_rust_channel = match rust_channel { - Some(channel) if channel == "auto-detect" => { - config.channel = ci_channel.into(); + Some(channel_) if channel_ == "auto-detect" => { + channel = ci_channel.into(); true } - Some(channel) => { - config.channel = channel; + Some(channel_) => { + channel = channel_; true } None => false, }; - let default = config.channel == "dev"; - config.omit_git_hash = rust_omit_git_hash.unwrap_or(default); + let omit_git_hash = rust_omit_git_hash.unwrap_or(channel == "dev"); - config.rust_info = git_info(&config.exec_ctx, config.omit_git_hash, &config.src); - config.cargo_info = - git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/cargo")); - config.rust_analyzer_info = git_info( - &config.exec_ctx, - config.omit_git_hash, - &config.src.join("src/tools/rust-analyzer"), - ); - config.clippy_info = - git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/clippy")); - config.miri_info = - git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/miri")); - config.rustfmt_info = - git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/rustfmt")); - config.enzyme_info = - git_info(&config.exec_ctx, config.omit_git_hash, &config.src.join("src/tools/enzyme")); - config.in_tree_llvm_info = - git_info(&config.exec_ctx, false, &config.src.join("src/llvm-project")); - config.in_tree_gcc_info = git_info(&config.exec_ctx, false, &config.src.join("src/gcc")); - - config.vendor = build_vendor.unwrap_or( - config.rust_info.is_from_tarball() - && config.src.join("vendor").exists() - && config.src.join(".cargo/config.toml").exists(), - ); + rust_info = git_info(&exec_ctx, omit_git_hash, &src); + dwn_ctx.rust_info = rust_info.clone(); - if !is_user_configured_rust_channel && config.rust_info.is_from_tarball() { - config.channel = ci_channel.into(); + if !is_user_configured_rust_channel && rust_info.is_from_tarball() { + channel = ci_channel.into(); } - config.rust_profile_use = flags_rust_profile_use; - config.rust_profile_generate = flags_rust_profile_generate; - // FIXME(#133381): alt rustc builds currently do *not* have rustc debug assertions // enabled. We should not download a CI alt rustc if we need rustc to have debug // assertions (e.g. for crashes test suite). This can be changed once something like @@ -951,17 +828,35 @@ impl Config { ); } - let dwn_ctx = DownloadContext::from(&config); - config.download_rustc_commit = - download_ci_rustc_commit(dwn_ctx, rust_download_rustc, config.llvm_assertions); + download_rustc_commit = + download_ci_rustc_commit(&dwn_ctx, rust_download_rustc, llvm_assertions); + dwn_ctx.download_rustc_commit = download_rustc_commit.clone(); - if debug_assertions_requested && config.download_rustc_commit.is_some() { + if debug_assertions_requested && download_rustc_commit.is_some() { eprintln!( "WARN: `rust.debug-assertions = true` will prevent downloading CI rustc as alt CI \ rustc is not currently built with debug assertions." ); // We need to put this later down_ci_rustc_commit. - config.download_rustc_commit = None; + download_rustc_commit = None; + dwn_ctx.download_rustc_commit = None; + } + + // We need to override `rust.channel` if it's manually specified when using the CI rustc. + // This is because if the compiler uses a different channel than the one specified in bootstrap.toml, + // tests may fail due to using a different channel than the one used by the compiler during tests. + if let Some(commit) = &download_rustc_commit + && is_user_configured_rust_channel + { + println!( + "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." + ); + + let channel_ = read_file_by_commit(&dwn_ctx, Path::new("src/ci/channel"), commit) + .trim() + .to_owned(); + + channel = channel_; } if let Some(t) = toml.target { @@ -969,24 +864,22 @@ impl Config { let mut target = Target::from_triple(&triple); if let Some(ref s) = cfg.llvm_config { - if config.download_rustc_commit.is_some() - && triple == *config.host_target.triple - { + if download_rustc_commit.is_some() && triple == *host_target.triple { panic!( "setting llvm_config for the host is incompatible with download-rustc" ); } - target.llvm_config = Some(config.src.join(s)); + target.llvm_config = Some(src.join(s)); } if let Some(patches) = cfg.llvm_has_rust_patches { assert!( - config.submodules == Some(false) || cfg.llvm_config.is_some(), + submodules == Some(false) || cfg.llvm_config.is_some(), "use of `llvm-has-rust-patches` is restricted to cases where either submodules are disabled or llvm-config been provided" ); target.llvm_has_rust_patches = Some(patches); } if let Some(ref s) = cfg.llvm_filecheck { - target.llvm_filecheck = Some(config.src.join(s)); + target.llvm_filecheck = Some(src.join(s)); } target.llvm_libunwind = cfg.llvm_libunwind.as_ref().map(|v| { v.parse().unwrap_or_else(|_| { @@ -1023,82 +916,11 @@ impl Config { }) }); - config.target_config.insert(TargetSelection::from_user(&triple), target); + target_config.insert(TargetSelection::from_user(&triple), target); } + dwn_ctx.target_config = target_config.clone(); } - if rust_optimize.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) { - eprintln!( - "WARNING: setting `optimize` to `false` is known to cause errors and \ - should be considered unsupported. Refer to `bootstrap.example.toml` \ - for more details." - ); - } - - config.rust_new_symbol_mangling = rust_new_symbol_mangling; - set(&mut config.rust_optimize_tests, rust_optimize_tests); - set(&mut config.codegen_tests, rust_codegen_tests); - set(&mut config.rust_rpath, rust_rpath); - set(&mut config.rust_strip, rust_strip); - set(&mut config.rust_frame_pointers, rust_frame_pointers); - config.rust_stack_protector = rust_stack_protector; - set(&mut config.jemalloc, rust_jemalloc); - set(&mut config.test_compare_mode, rust_test_compare_mode); - set(&mut config.backtrace, rust_backtrace); - set(&mut config.rust_dist_src, rust_dist_src); - set(&mut config.verbose_tests, rust_verbose_tests); - // in the case "false" is set explicitly, do not overwrite the command line args - if let Some(true) = rust_incremental { - config.incremental = true; - } - set(&mut config.lld_mode, rust_lld_mode); - set(&mut config.llvm_bitcode_linker_enabled, rust_llvm_bitcode_linker); - - config.rust_randomize_layout = rust_randomize_layout.unwrap_or_default(); - config.llvm_tools_enabled = rust_llvm_tools.unwrap_or(true); - - config.llvm_enzyme = config.channel == "dev" || config.channel == "nightly"; - config.rustc_default_linker = rust_default_linker; - config.musl_root = rust_musl_root.map(PathBuf::from); - config.save_toolstates = rust_save_toolstates.map(PathBuf::from); - set( - &mut config.deny_warnings, - match flags_warnings { - Warnings::Deny => Some(true), - Warnings::Warn => Some(false), - Warnings::Default => rust_deny_warnings, - }, - ); - set(&mut config.backtrace_on_ice, rust_backtrace_on_ice); - set(&mut config.rust_verify_llvm_ir, rust_verify_llvm_ir); - config.rust_thin_lto_import_instr_limit = rust_thin_lto_import_instr_limit; - set(&mut config.rust_remap_debuginfo, rust_remap_debuginfo); - set(&mut config.control_flow_guard, rust_control_flow_guard); - set(&mut config.ehcont_guard, rust_ehcont_guard); - config.llvm_libunwind_default = - rust_llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); - set( - &mut config.rust_codegen_backends, - rust_codegen_backends.map(|backends| parse_codegen_backends(backends, "rust")), - ); - - config.rust_codegen_units = rust_codegen_units.map(threads_from_config); - config.rust_codegen_units_std = rust_codegen_units_std.map(threads_from_config); - - if config.rust_profile_use.is_none() { - config.rust_profile_use = rust_profile_use; - } - - if config.rust_profile_generate.is_none() { - config.rust_profile_generate = rust_profile_generate; - } - - config.rust_lto = - rust_lto.as_deref().map(|value| RustcLto::from_str(value).unwrap()).unwrap_or_default(); - config.rust_validate_mir_opts = rust_validate_mir_opts; - - config.rust_optimize = rust_optimize.unwrap_or(RustOptimize::Bool(true)); - // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will // build our internal lld and use it as the default linker, by setting the `rust.lld` config // to true by default: @@ -1111,105 +933,24 @@ impl Config { // thus, disabled // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g. // when the config sets `rust.lld = false` - if default_lld_opt_in_targets().contains(&config.host_target.triple.to_string()) - && config.hosts == [config.host_target] + let lld_enabled = if default_lld_opt_in_targets().contains(&host_target.triple.to_string()) + && hosts == [host_target] { - let no_llvm_config = config - .target_config - .get(&config.host_target) - .is_none_or(|target_config| target_config.llvm_config.is_none()); - let enable_lld = config.llvm_from_ci || no_llvm_config; - // Prefer the config setting in case an explicit opt-out is needed. - config.lld_enabled = rust_lld_enabled.unwrap_or(enable_lld); + let no_llvm_config = + target_config.get(&host_target).map_or(true, |config| config.llvm_config.is_none()); + rust_lld_enabled.unwrap_or(llvm_from_ci || no_llvm_config) } else { - set(&mut config.lld_enabled, rust_lld_enabled); - } - - let default_std_features = BTreeSet::from([String::from("panic-unwind")]); - config.rust_std_features = rust_std_features.unwrap_or(default_std_features); - - let default = rust_debug == Some(true); - config.rustc_debug_assertions = rust_rustc_debug_assertions.unwrap_or(default); - config.std_debug_assertions = - rust_std_debug_assertions.unwrap_or(config.rustc_debug_assertions); - config.tools_debug_assertions = - rust_tools_debug_assertions.unwrap_or(config.rustc_debug_assertions); - config.rust_overflow_checks = rust_overflow_checks.unwrap_or(default); - config.rust_overflow_checks_std = - rust_overflow_checks_std.unwrap_or(config.rust_overflow_checks); - - config.rust_debug_logging = rust_debug_logging.unwrap_or(config.rustc_debug_assertions); - - let with_defaults = |debuginfo_level_specific: Option<_>| { - debuginfo_level_specific.or(rust_debuginfo_level).unwrap_or( - if rust_debug == Some(true) { - DebuginfoLevel::Limited - } else { - DebuginfoLevel::None - }, - ) + rust_lld_enabled.unwrap_or(false) }; - config.rust_debuginfo_level_rustc = with_defaults(rust_debuginfo_level_rustc); - config.rust_debuginfo_level_std = with_defaults(rust_debuginfo_level_std); - config.rust_debuginfo_level_tools = with_defaults(rust_debuginfo_level_tools); - config.rust_debuginfo_level_tests = - rust_debuginfo_level_tests.unwrap_or(DebuginfoLevel::None); - - config.reproducible_artifacts = flags_reproducible_artifact; - config.description = build_description; - - // We need to override `rust.channel` if it's manually specified when using the CI rustc. - // This is because if the compiler uses a different channel than the one specified in bootstrap.toml, - // tests may fail due to using a different channel than the one used by the compiler during tests. - if let Some(commit) = &config.download_rustc_commit - && is_user_configured_rust_channel - { - println!( - "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." - ); - let dwn_ctx = DownloadContext::from(&config); - let channel = - read_file_by_commit(dwn_ctx, Path::new("src/ci/channel"), commit).trim().to_owned(); - - config.channel = channel; + if let Some(v) = llvm_link_shared_ { + llvm_link_shared.set(Some(v)); } - set(&mut config.ninja_in_file, llvm_ninja); - set(&mut config.llvm_optimize, llvm_optimize); - set(&mut config.llvm_thin_lto, llvm_thin_lto); - set(&mut config.llvm_release_debuginfo, llvm_release_debuginfo); - set(&mut config.llvm_static_stdcpp, llvm_static_libstdcpp); - set(&mut config.llvm_libzstd, llvm_libzstd); - if let Some(v) = llvm_link_shared { - config.llvm_link_shared.set(Some(v)); - } - config.llvm_targets.clone_from(&llvm_targets); - config.llvm_experimental_targets.clone_from(&llvm_experimental_targets); - config.llvm_link_jobs = llvm_link_jobs; - config.llvm_version_suffix.clone_from(&llvm_version_suffix); - config.llvm_clang_cl.clone_from(&llvm_clang_cl); - config.llvm_tests = llvm_tests.unwrap_or_default(); - config.llvm_enzyme = llvm_enzyme.unwrap_or_default(); - config.llvm_plugins = llvm_plugin.unwrap_or_default(); - - config.llvm_cflags.clone_from(&llvm_cflags); - config.llvm_cxxflags.clone_from(&llvm_cxxflags); - config.llvm_ldflags.clone_from(&llvm_ldflags); - set(&mut config.llvm_use_libcxx, llvm_use_libcxx); - config.llvm_use_linker.clone_from(&llvm_use_linker); - config.llvm_allow_old_toolchain = llvm_allow_old_toolchain.unwrap_or(false); - config.llvm_offload = llvm_offload.unwrap_or(false); - config.llvm_polly = llvm_polly.unwrap_or(false); - config.llvm_clang = llvm_clang.unwrap_or(false); - config.llvm_enable_warnings = llvm_enable_warnings.unwrap_or(false); - config.llvm_build_config = llvm_build_config.clone().unwrap_or(Default::default()); - - let dwn_ctx = DownloadContext::from(&config); - config.llvm_from_ci = - parse_download_ci_llvm(dwn_ctx, llvm_download_ci_llvm, config.llvm_assertions); - - if config.llvm_from_ci { + llvm_from_ci = parse_download_ci_llvm(&dwn_ctx, llvm_download_ci_llvm, llvm_assertions); + dwn_ctx.llvm_from_ci = llvm_from_ci; + + if llvm_from_ci { let warn = |option: &str| { println!( "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build." @@ -1223,7 +964,7 @@ impl Config { warn("static-libstdcpp"); } - if llvm_link_shared.is_some() { + if llvm_link_shared_.is_some() { warn("link-shared"); } @@ -1232,7 +973,7 @@ impl Config { // config to the ones used to build the LLVM artifacts on CI, and only notify users // if they've chosen a different value. - if llvm_libzstd.is_some() { + if llvm_libzstd_.is_some() { println!( "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ @@ -1244,66 +985,30 @@ impl Config { } } - if !config.llvm_from_ci && config.llvm_thin_lto && llvm_link_shared.is_none() { + if !llvm_from_ci && llvm_thin_lto_.unwrap_or(false) && llvm_link_shared_.is_none() { // If we're building with ThinLTO on, by default we want to link // to LLVM shared, to avoid re-doing ThinLTO (which happens in // the link step) with each stage. - config.llvm_link_shared.set(Some(true)); - } - - config.gcc_ci_mode = match gcc_download_ci_gcc { - Some(value) => match value { - true => GccCiMode::DownloadFromCi, - false => GccCiMode::BuildLocally, - }, - None => GccCiMode::default(), - }; - - match build_ccache { - Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), - Some(StringOrBool::Bool(true)) => { - config.ccache = Some("ccache".to_string()); - } - Some(StringOrBool::Bool(false)) | None => {} + llvm_link_shared.set(Some(true)); } - if config.llvm_from_ci { - let triple = &config.host_target.triple; - let dwn_ctx = DownloadContext::from(&config); - let ci_llvm_bin = ci_llvm_root(dwn_ctx).join("bin"); - let build_target = config - .target_config - .entry(config.host_target) - .or_insert_with(|| Target::from_triple(triple)); + if llvm_from_ci { + let triple = &host_target.triple; + let ci_llvm_bin = ci_llvm_root(&dwn_ctx).join("bin"); + let build_target = + target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple)); + dwn_ctx.target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple)); check_ci_llvm!(build_target.llvm_config); check_ci_llvm!(build_target.llvm_filecheck); - build_target.llvm_config = - Some(ci_llvm_bin.join(exe("llvm-config", config.host_target))); - build_target.llvm_filecheck = - Some(ci_llvm_bin.join(exe("FileCheck", config.host_target))); + build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", host_target))); + build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", host_target))); } - config.dist_sign_folder = dist_sign_folder.map(PathBuf::from); - config.dist_upload_addr = dist_upload_addr; - config.dist_compression_formats = dist_compression_formats; - set(&mut config.dist_compression_profile, dist_compression_profile); - set(&mut config.rust_dist_src, dist_src_tarball); - set(&mut config.dist_include_mingw_linker, dist_include_mingw_linker); - config.dist_vendor = dist_vendor.unwrap_or_else(|| { - // If we're building from git or tarball sources, enable it by default. - config.rust_info.is_managed_git_subrepository() || config.rust_info.is_from_tarball() - }); - - config.initial_rustfmt = if let Some(r) = build_rustfmt { - Some(r) - } else { - let dwn_ctx = DownloadContext::from(&config); - maybe_download_rustfmt(dwn_ctx) - }; + let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx)); - if matches!(config.lld_mode, LldMode::SelfContained) - && !config.lld_enabled + if matches!(rust_lld_mode.unwrap_or_default(), LldMode::SelfContained) + && !lld_enabled && flags_stage.unwrap_or(0) > 0 { panic!( @@ -1311,29 +1016,13 @@ impl Config { ); } - let dwn_ctx = DownloadContext::from(&config); - if config.lld_enabled && is_system_llvm(dwn_ctx, config.host_target) { + if lld_enabled && is_system_llvm(&dwn_ctx, host_target) { panic!("Cannot enable LLD with `rust.lld = true` when using external llvm-config."); } - config.optimized_compiler_builtins = - build_optimized_compiler_builtins.unwrap_or(config.channel != "dev"); - config.compiletest_diff_tool = build_compiletest_diff_tool; - config.compiletest_use_stage0_libtest = - build_compiletest_use_stage0_libtest.unwrap_or(true); - config.tidy_extra_checks = build_tidy_extra_checks; - - let download_rustc = config.download_rustc_commit.is_some(); - config.explicit_stage_from_cli = flags_stage.is_some(); - config.explicit_stage_from_config = build_test_stage.is_some() - || build_build_stage.is_some() - || build_doc_stage.is_some() - || build_dist_stage.is_some() - || build_install_stage.is_some() - || build_check_stage.is_some() - || build_bench_stage.is_some(); - - config.stage = match config.cmd { + let download_rustc = download_rustc_commit.is_some(); + + let stage = match flags_cmd { Subcommand::Check { .. } => flags_stage.or(build_check_stage).unwrap_or(1), Subcommand::Clippy { .. } | Subcommand::Fix => { flags_stage.or(build_check_stage).unwrap_or(1) @@ -1362,7 +1051,7 @@ impl Config { }; // Now check that the selected stage makes sense, and if not, print a warning and end - match (config.stage, &config.cmd) { + match (stage, &flags_cmd) { (0, Subcommand::Build { .. }) => { eprintln!("ERROR: cannot build anything on stage 0. Use at least stage 1."); exit!(1); @@ -1382,7 +1071,7 @@ impl Config { _ => {} } - if config.compile_time_deps && !matches!(config.cmd, Subcommand::Check { .. }) { + if flags_compile_time_deps && !matches!(flags_cmd, Subcommand::Check { .. }) { eprintln!( "WARNING: Can't use --compile-time-deps with any subcommand other than check." ); @@ -1391,8 +1080,8 @@ impl Config { // CI should always run stage 2 builds, unless it specifically states otherwise #[cfg(not(test))] - if flags_stage.is_none() && config.is_running_on_ci { - match config.cmd { + if flags_stage.is_none() && is_running_on_ci { + match flags_cmd { Subcommand::Test { .. } | Subcommand::Miri { .. } | Subcommand::Doc { .. } @@ -1401,9 +1090,8 @@ impl Config { | Subcommand::Dist | Subcommand::Install => { assert_eq!( - config.stage, 2, - "x.py should be run with `--stage 2` on CI, but was run with `--stage {}`", - config.stage, + stage, 2, + "x.py should be run with `--stage 2` on CI, but was run with `--stage {stage}`", ); } Subcommand::Clean { .. } @@ -1418,7 +1106,267 @@ impl Config { } } - config + let with_defaults = |debuginfo_level_specific: Option<_>| { + debuginfo_level_specific.or(rust_debuginfo_level).unwrap_or( + if rust_debug == Some(true) { + DebuginfoLevel::Limited + } else { + DebuginfoLevel::None + }, + ) + }; + + Config { + change_id: toml.change_id.inner, + bypass_bootstrap_lock: flags_bypass_bootstrap_lock, + ccache: match build_ccache { + Some(StringOrBool::String(s)) => Some(s), + Some(StringOrBool::Bool(true)) => Some("ccache".to_string()), + _ => None, + }, + ninja_in_file: llvm_ninja.unwrap_or(true), + compiler_docs: build_compiler_docs.unwrap_or(false), + library_docs_private_items: build_library_docs_private_items.unwrap_or(false), + docs_minification: build_docs_minification.unwrap_or(true), + docs: build_docs.unwrap_or(true), + locked_deps: build_locked_deps.unwrap_or(false), + full_bootstrap: build_full_bootstrap.unwrap_or(false), + bootstrap_cache_path, + extended: build_extended.unwrap_or(false), + tools: build_tools, + tool: build_tool.unwrap_or_default(), + sanitizers: build_sanitizers.unwrap_or(false), + profiler: build_profiler.unwrap_or(false), + include_default_paths: flags_include_default_paths, + rustc_error_format: flags_rustc_error_format, + json_output: flags_json_output, + compile_time_deps: flags_compile_time_deps, + test_compare_mode: rust_test_compare_mode.unwrap_or(false), + color: flags_color, + android_ndk: build_android_ndk, + optimized_compiler_builtins: build_optimized_compiler_builtins + .unwrap_or(channel != "dev"), + stdout_is_tty: std::io::stdout().is_terminal(), + stderr_is_tty: std::io::stderr().is_terminal(), + on_fail: flags_on_fail, + explicit_stage_from_cli: flags_stage.is_some(), + explicit_stage_from_config: build_test_stage.is_some() + || build_build_stage.is_some() + || build_doc_stage.is_some() + || build_dist_stage.is_some() + || build_install_stage.is_some() + || build_check_stage.is_some() + || build_bench_stage.is_some(), + + keep_stage: flags_keep_stage, + keep_stage_std: flags_keep_stage_std, + jobs: Some(threads_from_config(flags_jobs.or(build_jobs).unwrap_or(0))), + incremental: flags_incremental || rust_incremental == Some(true), + dump_bootstrap_shims: flags_dump_bootstrap_shims, + free_args: flags_free_args, + deny_warnings: match flags_warnings { + Warnings::Deny => true, + Warnings::Warn => false, + Warnings::Default => rust_deny_warnings.unwrap_or(true), + }, + backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), + llvm_tests: llvm_tests_.unwrap_or_default(), + llvm_enzyme: llvm_enzyme_.unwrap_or_default(), + llvm_offload: llvm_offload_.unwrap_or(false), + llvm_plugins: llvm_plugin.unwrap_or_default(), + llvm_optimize: llvm_optimize_.unwrap_or(true), + llvm_release_debuginfo: llvm_release_debuginfo_.unwrap_or(false), + llvm_static_stdcpp: llvm_static_libstdcpp.unwrap_or(false), + llvm_libzstd: llvm_libzstd_.unwrap_or(false), + llvm_clang_cl: llvm_clang_cl_, + llvm_targets: llvm_targets_, + llvm_experimental_targets: llvm_experimental_targets_, + llvm_link_jobs: llvm_link_jobs_, + llvm_version_suffix: llvm_version_suffix_, + llvm_use_linker: llvm_use_linker_, + llvm_allow_old_toolchain: llvm_allow_old_toolchain_.unwrap_or(false), + llvm_polly: llvm_polly_.unwrap_or(false), + llvm_clang: llvm_clang_.unwrap_or(false), + llvm_enable_warnings: llvm_enable_warnings_.unwrap_or(false), + llvm_build_config: llvm_build_config_.clone().unwrap_or(Default::default()), + llvm_tools_enabled: rust_llvm_tools.unwrap_or(true), + llvm_bitcode_linker_enabled: rust_llvm_bitcode_linker.unwrap_or(false), + llvm_cflags: llvm_cflags_, + llvm_cxxflags: llvm_cxxflags_, + llvm_ldflags: llvm_ldflags_, + llvm_use_libcxx: llvm_use_libcxx_.unwrap_or(false), + gcc_ci_mode: match gcc_download_ci_gcc { + Some(value) => match value { + true => GccCiMode::DownloadFromCi, + false => GccCiMode::BuildLocally, + }, + None => GccCiMode::default(), + }, + rust_optimize: rust_optimize_.unwrap_or(RustOptimize::Bool(true)), + rust_codegen_units: rust_codegen_units_.map(threads_from_config), + rust_codegen_units_std: rust_codegen_units_std_.map(threads_from_config), + std_debug_assertions: rust_std_debug_assertions + .or(rust_rustc_debug_assertions) + .unwrap_or(rust_debug == Some(true)), + tools_debug_assertions: rust_tools_debug_assertions + .or(rust_rustc_debug_assertions) + .unwrap_or(rust_debug == Some(true)), + rust_overflow_checks_std: rust_overflow_checks_std_ + .or(rust_overflow_checks_) + .unwrap_or(rust_debug == Some(true)), + rust_overflow_checks: rust_overflow_checks_.unwrap_or(rust_debug == Some(true)), + rust_debug_logging: rust_debug_logging_ + .or(rust_rustc_debug_assertions) + .unwrap_or(rust_debug == Some(true)), + rust_debuginfo_level_rustc: with_defaults(rust_debuginfo_level_rustc_), + rust_debuginfo_level_std: with_defaults(rust_debuginfo_level_std_), + rust_debuginfo_level_tools: with_defaults(rust_debuginfo_level_tools_), + rust_debuginfo_level_tests: rust_debuginfo_level_tests_.unwrap_or(DebuginfoLevel::None), + rust_rpath: rust_rpath_.unwrap_or(true), + rust_strip: rust_strip_.unwrap_or(false), + rust_frame_pointers: rust_frame_pointers_.unwrap_or(false), + rust_stack_protector: rust_stack_protector_, + rustc_default_linker: rust_default_linker, + rust_optimize_tests: rust_optimize_tests_.unwrap_or(true), + rust_dist_src: dist_src_tarball_.unwrap_or_else(|| rust_dist_src_.unwrap_or(true)), + rust_codegen_backends: rust_codegen_backends_ + .map(|backends| parse_codegen_backends(backends, "rust")) + .unwrap_or(vec![CodegenBackendKind::Llvm]), + rust_verify_llvm_ir: rust_verify_llvm_ir_.unwrap_or(false), + rust_thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit_, + rust_randomize_layout: rust_randomize_layout_.unwrap_or_default(), + rust_remap_debuginfo: rust_remap_debuginfo_.unwrap_or(false), + rust_new_symbol_mangling: rust_new_symbol_mangling_, + rust_profile_use: flags_rust_profile_use.or(rust_profile_use_), + rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate_), + rust_lto: rust_lto_ + .as_deref() + .map(|value| RustcLto::from_str(value).unwrap()) + .unwrap_or_default(), + rust_validate_mir_opts: rust_validate_mir_opts_, + rust_std_features: rust_std_features_ + .unwrap_or(BTreeSet::from([String::from("panic-unwind")])), + llvm_profile_use: flags_llvm_profile_use, + llvm_profile_generate: flags_llvm_profile_generate, + llvm_libunwind_default: rust_llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")), + enable_bolt_settings: flags_enable_bolt_settings, + reproducible_artifacts: flags_reproducible_artifact, + local_rebuild: build_local_rebuild.unwrap_or(false), + jemalloc: rust_jemalloc.unwrap_or(false), + control_flow_guard: rust_control_flow_guard.unwrap_or(false), + ehcont_guard: rust_ehcont_guard.unwrap_or(false), + dist_sign_folder: dist_sign_folder_.map(PathBuf::from), + dist_upload_addr: dist_upload_addr_, + dist_compression_formats: dist_compression_formats_, + dist_compression_profile: dist_compression_profile_.unwrap_or("fast".into()), + dist_include_mingw_linker: dist_include_mingw_linker_.unwrap_or(true), + backtrace: rust_backtrace.unwrap_or(true), + low_priority: build_low_priority.unwrap_or(false), + description: build_description, + verbose_tests: rust_verbose_tests.unwrap_or(exec_ctx.is_verbose()), + save_toolstates: rust_save_toolstates.map(PathBuf::from), + print_step_timings: build_print_step_timings.unwrap_or(false), + print_step_rusage: build_print_step_rusage.unwrap_or(false), + musl_root: rust_musl_root.map(PathBuf::from), + prefix: install_prefix.map(PathBuf::from), + sysconfdir: install_sysconfdir.map(PathBuf::from), + datadir: install_datadir.map(PathBuf::from), + docdir: install_docdir.map(PathBuf::from), + bindir: install_bindir.map(PathBuf::from).unwrap_or("bin".into()), + libdir: install_libdir.map(PathBuf::from), + mandir: install_mandir.map(PathBuf::from), + codegen_tests: rust_codegen_tests.unwrap_or(true), + nodejs: build_nodejs.map(PathBuf::from), + npm: build_npm.map(PathBuf::from), + gdb: build_gdb.map(PathBuf::from), + lldb: build_lldb.map(PathBuf::from), + python: build_python.map(PathBuf::from), + reuse: build_reuse.map(PathBuf::from), + cargo_native_static: build_cargo_native_static.unwrap_or(false), + configure_args: build_configure_args.unwrap_or_default(), + compiletest_diff_tool: build_compiletest_diff_tool, + compiletest_allow_stage0: build_compiletest_allow_stage0.unwrap_or(false), + compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest.unwrap_or(true), + tidy_extra_checks: build_tidy_extra_checks, + skip_std_check_if_no_download_rustc: flags_skip_std_check_if_no_download_rustc, + cargo_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/cargo")), + rust_analyzer_info: git_info( + &exec_ctx, + omit_git_hash, + &src.join("src/tools/rust-analyzer"), + ), + clippy_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/clippy")), + miri_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/miri")), + rustfmt_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/rustfmt")), + enzyme_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/enzyme")), + in_tree_llvm_info: git_info(&exec_ctx, false, &src.join("src/llvm-project")), + in_tree_gcc_info: git_info(&exec_ctx, false, &src.join("src/gcc")), + dist_vendor: dist_vendor_.unwrap_or_else(|| { + // If we're building from git or tarball sources, enable it by default. + rust_info.is_managed_git_subrepository() || rust_info.is_from_tarball() + }), + targets: flags_target + .map(|TargetSelectionList(targets)| targets) + .or_else(|| { + build_target.map(|t| t.iter().map(|t| TargetSelection::from_user(t)).collect()) + }) + .unwrap_or_else(|| hosts.clone()), + #[allow(clippy::map_identity)] + skip: flags_skip + .into_iter() + .chain(flags_exclude) + .chain(build_exclude.unwrap_or_default()) + .map(|p| { + // Never return top-level path here as it would break `--skip` + // logic on rustc's internal test framework which is utilized by compiletest. + #[cfg(windows)] + { + PathBuf::from(p.to_string_lossy().replace('/', "\\")) + } + #[cfg(not(windows))] + { + p + } + }) + .collect(), + paths: flags_paths, + config: toml_path, + llvm_thin_lto: llvm_thin_lto_.unwrap_or(false), + rustc_debug_assertions: rust_rustc_debug_assertions.unwrap_or(rust_debug == Some(true)), + lld_mode: rust_lld_mode.unwrap_or_default(), + initial_cargo_clippy: build_cargo_clippy, + vendor: build_vendor.unwrap_or( + rust_info.is_from_tarball() + && src.join("vendor").exists() + && src.join(".cargo/config.toml").exists(), + ), + cmd: flags_cmd, + exec_ctx, + out, + rust_info, + initial_cargo, + initial_rustc, + initial_sysroot, + initial_rustfmt, + submodules, + target_config, + omit_git_hash, + stage, + src, + llvm_from_ci, + llvm_assertions, + lld_enabled, + host_target, + hosts, + channel, + is_running_on_ci, + path_modification_cache, + patch_binaries_for_nix, + stage0_metadata, + download_rustc_commit, + llvm_link_shared, + } } pub fn dry_run(&self) -> bool { @@ -2292,7 +2240,7 @@ pub fn has_changes_from_upstream<'a>( )] pub(crate) fn update_submodule<'a>(dwn_ctx: impl AsRef>, relative_path: &str) { let dwn_ctx = dwn_ctx.as_ref(); - if dwn_ctx.rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, dwn_ctx.rust_info) { + if dwn_ctx.rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, &dwn_ctx.rust_info) { return; } diff --git a/src/bootstrap/src/core/config/mod.rs b/src/bootstrap/src/core/config/mod.rs index 285d20917e7da..02f44d41e9e15 100644 --- a/src/bootstrap/src/core/config/mod.rs +++ b/src/bootstrap/src/core/config/mod.rs @@ -402,12 +402,6 @@ pub enum GccCiMode { DownloadFromCi, } -pub fn set(field: &mut T, val: Option) { - if let Some(v) = val { - *field = v; - } -} - pub fn threads_from_config(v: u32) -> u32 { match v { 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32, diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 5ded44cef1447..29a244a6c4087 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -403,13 +403,13 @@ impl Config { pub(crate) struct DownloadContext<'a> { pub path_modification_cache: Arc, PathFreshness>>>, pub src: &'a Path, - pub rust_info: &'a channel::GitInfo, + pub rust_info: channel::GitInfo, pub submodules: &'a Option, - pub download_rustc_commit: &'a Option, + pub download_rustc_commit: Option, pub host_target: TargetSelection, pub llvm_from_ci: bool, - pub target_config: &'a HashMap, - pub out: &'a Path, + pub target_config: HashMap, + pub out: PathBuf, pub patch_binaries_for_nix: Option, pub exec_ctx: &'a ExecutionContext, pub stage0_metadata: &'a build_helper::stage0_parser::Stage0, @@ -418,6 +418,45 @@ pub(crate) struct DownloadContext<'a> { pub is_running_on_ci: bool, } +impl<'a> DownloadContext<'a> { + #[allow(clippy::too_many_arguments)] + pub fn new( + path_modification_cache: Arc, PathFreshness>>>, + src: &'a Path, + rust_info: channel::GitInfo, + submodules: &'a Option, + download_rustc_commit: Option, + host_target: TargetSelection, + llvm_from_ci: bool, + target_config: HashMap, + out: PathBuf, + patch_binaries_for_nix: Option, + exec_ctx: &'a ExecutionContext, + stage0_metadata: &'a build_helper::stage0_parser::Stage0, + llvm_assertions: bool, + bootstrap_cache_path: &'a Option, + is_running_on_ci: bool, + ) -> Self { + Self { + path_modification_cache, + src, + rust_info, + submodules, + download_rustc_commit, + host_target, + llvm_from_ci, + target_config, + out, + patch_binaries_for_nix, + exec_ctx, + stage0_metadata, + llvm_assertions, + bootstrap_cache_path, + is_running_on_ci, + } + } +} + impl<'a> AsRef> for DownloadContext<'a> { fn as_ref(&self) -> &DownloadContext<'a> { self @@ -430,12 +469,12 @@ impl<'a> From<&'a Config> for DownloadContext<'a> { path_modification_cache: value.path_modification_cache.clone(), src: &value.src, host_target: value.host_target, - rust_info: &value.rust_info, - download_rustc_commit: &value.download_rustc_commit, + rust_info: value.rust_info.clone(), + download_rustc_commit: value.download_rustc_commit.clone(), submodules: &value.submodules, llvm_from_ci: value.llvm_from_ci, - target_config: &value.target_config, - out: &value.out, + target_config: value.target_config.clone(), + out: value.out.clone(), patch_binaries_for_nix: value.patch_binaries_for_nix, exec_ctx: &value.exec_ctx, stage0_metadata: &value.stage0_metadata, @@ -543,13 +582,13 @@ pub(crate) fn maybe_download_rustfmt<'a>( ); if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) { - fix_bin_or_dylib(dwn_ctx.out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx); - fix_bin_or_dylib(dwn_ctx.out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx); let lib_dir = bin_root.join("lib"); for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib); if path_is_dylib(&lib.path()) { - fix_bin_or_dylib(dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); } } } @@ -615,10 +654,10 @@ fn download_toolchain<'a>( } if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) { - fix_bin_or_dylib(dwn_ctx.out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx); - fix_bin_or_dylib(dwn_ctx.out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx); fix_bin_or_dylib( - dwn_ctx.out, + &dwn_ctx.out, &bin_root.join("libexec").join("rust-analyzer-proc-macro-srv"), dwn_ctx.exec_ctx, ); @@ -626,7 +665,7 @@ fn download_toolchain<'a>( for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib); if path_is_dylib(&lib.path()) { - fix_bin_or_dylib(dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); + fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); } } } @@ -963,7 +1002,7 @@ fn download_file<'a>( println!("download {url}"); }); // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. - let tempfile = tempdir(dwn_ctx.out).join(dest_path.file_name().unwrap()); + let tempfile = tempdir(&dwn_ctx.out).join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might // need to download components from other protocols. The match allows them adding more // protocols without worrying about merge conflicts if we change the HTTP implementation. From a0aaa1275a83b51089442127571f1eb62e993a23 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 18 Aug 2025 10:56:58 +0530 Subject: [PATCH 02/10] clippy'ed --- src/bootstrap/src/core/config/config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 692c05456f69e..e6d5171eaf95c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -937,7 +937,7 @@ impl Config { && hosts == [host_target] { let no_llvm_config = - target_config.get(&host_target).map_or(true, |config| config.llvm_config.is_none()); + target_config.get(&host_target).is_none_or(|config| config.llvm_config.is_none()); rust_lld_enabled.unwrap_or(llvm_from_ci || no_llvm_config) } else { rust_lld_enabled.unwrap_or(false) From f960e368a91714d38e3bd3c72c0eb530ee4784c8 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Mon, 18 Aug 2025 23:49:01 +0530 Subject: [PATCH 03/10] remove downstream new method --- src/bootstrap/src/core/config/config.rs | 24 +++++++-------- src/bootstrap/src/core/download.rs | 39 ------------------------- 2 files changed, 12 insertions(+), 51 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index e6d5171eaf95c..9028c7aec364d 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -735,23 +735,23 @@ impl Config { ); } - let mut dwn_ctx = DownloadContext::new( - path_modification_cache.clone(), - &src, - rust_info.clone(), - &submodules, - download_rustc_commit.clone(), + let mut dwn_ctx = DownloadContext { + path_modification_cache: path_modification_cache.clone(), + src: &src, + rust_info: rust_info.clone(), + submodules: &submodules, + download_rustc_commit: download_rustc_commit.clone(), host_target, llvm_from_ci, - target_config.clone(), - out.clone(), + target_config: target_config.clone(), + out: out.clone(), patch_binaries_for_nix, - &exec_ctx, - &stage0_metadata, + exec_ctx: &exec_ctx, + stage0_metadata: &stage0_metadata, llvm_assertions, - &bootstrap_cache_path, + bootstrap_cache_path: &bootstrap_cache_path, is_running_on_ci, - ); + }; let initial_rustc = build_rustc.unwrap_or_else(|| { download_beta_toolchain(&dwn_ctx); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 29a244a6c4087..402d6019dabbb 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -418,45 +418,6 @@ pub(crate) struct DownloadContext<'a> { pub is_running_on_ci: bool, } -impl<'a> DownloadContext<'a> { - #[allow(clippy::too_many_arguments)] - pub fn new( - path_modification_cache: Arc, PathFreshness>>>, - src: &'a Path, - rust_info: channel::GitInfo, - submodules: &'a Option, - download_rustc_commit: Option, - host_target: TargetSelection, - llvm_from_ci: bool, - target_config: HashMap, - out: PathBuf, - patch_binaries_for_nix: Option, - exec_ctx: &'a ExecutionContext, - stage0_metadata: &'a build_helper::stage0_parser::Stage0, - llvm_assertions: bool, - bootstrap_cache_path: &'a Option, - is_running_on_ci: bool, - ) -> Self { - Self { - path_modification_cache, - src, - rust_info, - submodules, - download_rustc_commit, - host_target, - llvm_from_ci, - target_config, - out, - patch_binaries_for_nix, - exec_ctx, - stage0_metadata, - llvm_assertions, - bootstrap_cache_path, - is_running_on_ci, - } - } -} - impl<'a> AsRef> for DownloadContext<'a> { fn as_ref(&self) -> &DownloadContext<'a> { self From 46c4d5cf15dbe2955f0ad102ae89ec54a8e0a15e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 17:42:04 +0530 Subject: [PATCH 04/10] remove now not required _ --- src/bootstrap/src/core/config/config.rs | 230 ++++++++++++------------ 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 9028c7aec364d..b3fca61709e1c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -554,105 +554,105 @@ impl Config { } = toml.install.unwrap_or_default(); let Rust { - optimize: rust_optimize_, + optimize: rust_optimize, debug: rust_debug, - codegen_units: rust_codegen_units_, - codegen_units_std: rust_codegen_units_std_, + codegen_units: rust_codegen_units, + codegen_units_std: rust_codegen_units_std, rustc_debug_assertions: rust_rustc_debug_assertions, std_debug_assertions: rust_std_debug_assertions, tools_debug_assertions: rust_tools_debug_assertions, - overflow_checks: rust_overflow_checks_, - overflow_checks_std: rust_overflow_checks_std_, - debug_logging: rust_debug_logging_, + overflow_checks: rust_overflow_checks, + overflow_checks_std: rust_overflow_checks_std, + debug_logging: rust_debug_logging, debuginfo_level: rust_debuginfo_level, - debuginfo_level_rustc: rust_debuginfo_level_rustc_, - debuginfo_level_std: rust_debuginfo_level_std_, - debuginfo_level_tools: rust_debuginfo_level_tools_, - debuginfo_level_tests: rust_debuginfo_level_tests_, + debuginfo_level_rustc: rust_debuginfo_level_rustc, + debuginfo_level_std: rust_debuginfo_level_std, + debuginfo_level_tools: rust_debuginfo_level_tools, + debuginfo_level_tests: rust_debuginfo_level_tests, backtrace: rust_backtrace, incremental: rust_incremental, - randomize_layout: rust_randomize_layout_, + randomize_layout: rust_randomize_layout, default_linker: rust_default_linker, channel: rust_channel, musl_root: rust_musl_root, - rpath: rust_rpath_, + rpath: rust_rpath, verbose_tests: rust_verbose_tests, - optimize_tests: rust_optimize_tests_, + optimize_tests: rust_optimize_tests, codegen_tests: rust_codegen_tests, omit_git_hash: rust_omit_git_hash, - dist_src: rust_dist_src_, + dist_src: rust_dist_src, save_toolstates: rust_save_toolstates, - codegen_backends: rust_codegen_backends_, + codegen_backends: rust_codegen_backends, lld: rust_lld_enabled, llvm_tools: rust_llvm_tools, llvm_bitcode_linker: rust_llvm_bitcode_linker, deny_warnings: rust_deny_warnings, backtrace_on_ice: rust_backtrace_on_ice, - verify_llvm_ir: rust_verify_llvm_ir_, - thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit_, - remap_debuginfo: rust_remap_debuginfo_, + verify_llvm_ir: rust_verify_llvm_ir, + thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit, + remap_debuginfo: rust_remap_debuginfo, jemalloc: rust_jemalloc, test_compare_mode: rust_test_compare_mode, llvm_libunwind: rust_llvm_libunwind, control_flow_guard: rust_control_flow_guard, ehcont_guard: rust_ehcont_guard, - new_symbol_mangling: rust_new_symbol_mangling_, - profile_generate: rust_profile_generate_, - profile_use: rust_profile_use_, + new_symbol_mangling: rust_new_symbol_mangling, + profile_generate: rust_profile_generate, + profile_use: rust_profile_use, download_rustc: rust_download_rustc, - lto: rust_lto_, - validate_mir_opts: rust_validate_mir_opts_, - frame_pointers: rust_frame_pointers_, - stack_protector: rust_stack_protector_, - strip: rust_strip_, + lto: rust_lto, + validate_mir_opts: rust_validate_mir_opts, + frame_pointers: rust_frame_pointers, + stack_protector: rust_stack_protector, + strip: rust_strip, lld_mode: rust_lld_mode, - std_features: rust_std_features_, + std_features: rust_std_features, } = toml.rust.unwrap_or_default(); let Llvm { - optimize: llvm_optimize_, - thin_lto: llvm_thin_lto_, - release_debuginfo: llvm_release_debuginfo_, + optimize: llvm_optimize, + thin_lto: llvm_thin_lto, + release_debuginfo: llvm_release_debuginfo, assertions: llvm_assertions_, - tests: llvm_tests_, - enzyme: llvm_enzyme_, + tests: llvm_tests, + enzyme: llvm_enzyme, plugins: llvm_plugin, static_libstdcpp: llvm_static_libstdcpp, - libzstd: llvm_libzstd_, + libzstd: llvm_libzstd, ninja: llvm_ninja, - targets: llvm_targets_, - experimental_targets: llvm_experimental_targets_, - link_jobs: llvm_link_jobs_, + targets: llvm_targets, + experimental_targets: llvm_experimental_targets, + link_jobs: llvm_link_jobs, link_shared: llvm_link_shared_, - version_suffix: llvm_version_suffix_, - clang_cl: llvm_clang_cl_, - cflags: llvm_cflags_, - cxxflags: llvm_cxxflags_, - ldflags: llvm_ldflags_, - use_libcxx: llvm_use_libcxx_, - use_linker: llvm_use_linker_, - allow_old_toolchain: llvm_allow_old_toolchain_, - offload: llvm_offload_, - polly: llvm_polly_, - clang: llvm_clang_, - enable_warnings: llvm_enable_warnings_, + version_suffix: llvm_version_suffix, + clang_cl: llvm_clang_cl, + cflags: llvm_cflags, + cxxflags: llvm_cxxflags, + ldflags: llvm_ldflags, + use_libcxx: llvm_use_libcxx, + use_linker: llvm_use_linker, + allow_old_toolchain: llvm_allow_old_toolchain, + offload: llvm_offload, + polly: llvm_polly, + clang: llvm_clang, + enable_warnings: llvm_enable_warnings, download_ci_llvm: llvm_download_ci_llvm, - build_config: llvm_build_config_, + build_config: llvm_build_config, } = toml.llvm.unwrap_or_default(); let Dist { - sign_folder: dist_sign_folder_, - upload_addr: dist_upload_addr_, - src_tarball: dist_src_tarball_, - compression_formats: dist_compression_formats_, - compression_profile: dist_compression_profile_, - include_mingw_linker: dist_include_mingw_linker_, - vendor: dist_vendor_, + sign_folder: dist_sign_folder, + upload_addr: dist_upload_addr, + src_tarball: dist_src_tarball, + compression_formats: dist_compression_formats, + compression_profile: dist_compression_profile, + include_mingw_linker: dist_include_mingw_linker, + vendor: dist_vendor, } = toml.dist.unwrap_or_default(); let Gcc { download_ci_gcc: gcc_download_ci_gcc } = toml.gcc.unwrap_or_default(); - if rust_optimize_.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) { + if rust_optimize.as_ref().is_some_and(|v| matches!(v, RustOptimize::Bool(false))) { eprintln!( "WARNING: setting `optimize` to `false` is known to cause errors and \ should be considered unsupported. Refer to `bootstrap.example.toml` \ @@ -973,7 +973,7 @@ impl Config { // config to the ones used to build the LLVM artifacts on CI, and only notify users // if they've chosen a different value. - if llvm_libzstd_.is_some() { + if llvm_libzstd.is_some() { println!( "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \ like almost all `llvm.*` options, will be ignored and set by the LLVM CI \ @@ -985,7 +985,7 @@ impl Config { } } - if !llvm_from_ci && llvm_thin_lto_.unwrap_or(false) && llvm_link_shared_.is_none() { + if !llvm_from_ci && llvm_thin_lto.unwrap_or(false) && llvm_link_shared_.is_none() { // If we're building with ThinLTO on, by default we want to link // to LLVM shared, to avoid re-doing ThinLTO (which happens in // the link step) with each stage. @@ -1170,31 +1170,31 @@ impl Config { Warnings::Default => rust_deny_warnings.unwrap_or(true), }, backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), - llvm_tests: llvm_tests_.unwrap_or_default(), - llvm_enzyme: llvm_enzyme_.unwrap_or_default(), - llvm_offload: llvm_offload_.unwrap_or(false), + llvm_tests: llvm_tests.unwrap_or_default(), + llvm_enzyme: llvm_enzyme.unwrap_or_default(), + llvm_offload: llvm_offload.unwrap_or(false), llvm_plugins: llvm_plugin.unwrap_or_default(), - llvm_optimize: llvm_optimize_.unwrap_or(true), - llvm_release_debuginfo: llvm_release_debuginfo_.unwrap_or(false), + llvm_optimize: llvm_optimize.unwrap_or(true), + llvm_release_debuginfo: llvm_release_debuginfo.unwrap_or(false), llvm_static_stdcpp: llvm_static_libstdcpp.unwrap_or(false), - llvm_libzstd: llvm_libzstd_.unwrap_or(false), - llvm_clang_cl: llvm_clang_cl_, - llvm_targets: llvm_targets_, - llvm_experimental_targets: llvm_experimental_targets_, - llvm_link_jobs: llvm_link_jobs_, - llvm_version_suffix: llvm_version_suffix_, - llvm_use_linker: llvm_use_linker_, - llvm_allow_old_toolchain: llvm_allow_old_toolchain_.unwrap_or(false), - llvm_polly: llvm_polly_.unwrap_or(false), - llvm_clang: llvm_clang_.unwrap_or(false), - llvm_enable_warnings: llvm_enable_warnings_.unwrap_or(false), - llvm_build_config: llvm_build_config_.clone().unwrap_or(Default::default()), + llvm_libzstd: llvm_libzstd.unwrap_or(false), + llvm_clang_cl, + llvm_targets, + llvm_experimental_targets, + llvm_link_jobs, + llvm_version_suffix, + llvm_use_linker, + llvm_allow_old_toolchain: llvm_allow_old_toolchain.unwrap_or(false), + llvm_polly: llvm_polly.unwrap_or(false), + llvm_clang: llvm_clang.unwrap_or(false), + llvm_enable_warnings: llvm_enable_warnings.unwrap_or(false), + llvm_build_config: llvm_build_config.clone().unwrap_or(Default::default()), llvm_tools_enabled: rust_llvm_tools.unwrap_or(true), llvm_bitcode_linker_enabled: rust_llvm_bitcode_linker.unwrap_or(false), - llvm_cflags: llvm_cflags_, - llvm_cxxflags: llvm_cxxflags_, - llvm_ldflags: llvm_ldflags_, - llvm_use_libcxx: llvm_use_libcxx_.unwrap_or(false), + llvm_cflags, + llvm_cxxflags, + llvm_ldflags, + llvm_use_libcxx: llvm_use_libcxx.unwrap_or(false), gcc_ci_mode: match gcc_download_ci_gcc { Some(value) => match value { true => GccCiMode::DownloadFromCi, @@ -1202,49 +1202,49 @@ impl Config { }, None => GccCiMode::default(), }, - rust_optimize: rust_optimize_.unwrap_or(RustOptimize::Bool(true)), - rust_codegen_units: rust_codegen_units_.map(threads_from_config), - rust_codegen_units_std: rust_codegen_units_std_.map(threads_from_config), + rust_optimize: rust_optimize.unwrap_or(RustOptimize::Bool(true)), + rust_codegen_units: rust_codegen_units.map(threads_from_config), + rust_codegen_units_std: rust_codegen_units_std.map(threads_from_config), std_debug_assertions: rust_std_debug_assertions .or(rust_rustc_debug_assertions) .unwrap_or(rust_debug == Some(true)), tools_debug_assertions: rust_tools_debug_assertions .or(rust_rustc_debug_assertions) .unwrap_or(rust_debug == Some(true)), - rust_overflow_checks_std: rust_overflow_checks_std_ - .or(rust_overflow_checks_) + rust_overflow_checks_std: rust_overflow_checks_std + .or(rust_overflow_checks) .unwrap_or(rust_debug == Some(true)), - rust_overflow_checks: rust_overflow_checks_.unwrap_or(rust_debug == Some(true)), - rust_debug_logging: rust_debug_logging_ + rust_overflow_checks: rust_overflow_checks.unwrap_or(rust_debug == Some(true)), + rust_debug_logging: rust_debug_logging .or(rust_rustc_debug_assertions) .unwrap_or(rust_debug == Some(true)), - rust_debuginfo_level_rustc: with_defaults(rust_debuginfo_level_rustc_), - rust_debuginfo_level_std: with_defaults(rust_debuginfo_level_std_), - rust_debuginfo_level_tools: with_defaults(rust_debuginfo_level_tools_), - rust_debuginfo_level_tests: rust_debuginfo_level_tests_.unwrap_or(DebuginfoLevel::None), - rust_rpath: rust_rpath_.unwrap_or(true), - rust_strip: rust_strip_.unwrap_or(false), - rust_frame_pointers: rust_frame_pointers_.unwrap_or(false), - rust_stack_protector: rust_stack_protector_, + rust_debuginfo_level_rustc: with_defaults(rust_debuginfo_level_rustc), + rust_debuginfo_level_std: with_defaults(rust_debuginfo_level_std), + rust_debuginfo_level_tools: with_defaults(rust_debuginfo_level_tools), + rust_debuginfo_level_tests: rust_debuginfo_level_tests.unwrap_or(DebuginfoLevel::None), + rust_rpath: rust_rpath.unwrap_or(true), + rust_strip: rust_strip.unwrap_or(false), + rust_frame_pointers: rust_frame_pointers.unwrap_or(false), + rust_stack_protector, rustc_default_linker: rust_default_linker, - rust_optimize_tests: rust_optimize_tests_.unwrap_or(true), - rust_dist_src: dist_src_tarball_.unwrap_or_else(|| rust_dist_src_.unwrap_or(true)), - rust_codegen_backends: rust_codegen_backends_ + rust_optimize_tests: rust_optimize_tests.unwrap_or(true), + rust_dist_src: dist_src_tarball.unwrap_or_else(|| rust_dist_src.unwrap_or(true)), + rust_codegen_backends: rust_codegen_backends .map(|backends| parse_codegen_backends(backends, "rust")) .unwrap_or(vec![CodegenBackendKind::Llvm]), - rust_verify_llvm_ir: rust_verify_llvm_ir_.unwrap_or(false), - rust_thin_lto_import_instr_limit: rust_thin_lto_import_instr_limit_, - rust_randomize_layout: rust_randomize_layout_.unwrap_or_default(), - rust_remap_debuginfo: rust_remap_debuginfo_.unwrap_or(false), - rust_new_symbol_mangling: rust_new_symbol_mangling_, - rust_profile_use: flags_rust_profile_use.or(rust_profile_use_), - rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate_), - rust_lto: rust_lto_ + rust_verify_llvm_ir: rust_verify_llvm_ir.unwrap_or(false), + rust_thin_lto_import_instr_limit, + rust_randomize_layout: rust_randomize_layout.unwrap_or_default(), + rust_remap_debuginfo: rust_remap_debuginfo.unwrap_or(false), + rust_new_symbol_mangling, + rust_profile_use: flags_rust_profile_use.or(rust_profile_use), + rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate), + rust_lto: rust_lto .as_deref() .map(|value| RustcLto::from_str(value).unwrap()) .unwrap_or_default(), - rust_validate_mir_opts: rust_validate_mir_opts_, - rust_std_features: rust_std_features_ + rust_validate_mir_opts, + rust_std_features: rust_std_features .unwrap_or(BTreeSet::from([String::from("panic-unwind")])), llvm_profile_use: flags_llvm_profile_use, llvm_profile_generate: flags_llvm_profile_generate, @@ -1256,11 +1256,11 @@ impl Config { jemalloc: rust_jemalloc.unwrap_or(false), control_flow_guard: rust_control_flow_guard.unwrap_or(false), ehcont_guard: rust_ehcont_guard.unwrap_or(false), - dist_sign_folder: dist_sign_folder_.map(PathBuf::from), - dist_upload_addr: dist_upload_addr_, - dist_compression_formats: dist_compression_formats_, - dist_compression_profile: dist_compression_profile_.unwrap_or("fast".into()), - dist_include_mingw_linker: dist_include_mingw_linker_.unwrap_or(true), + dist_sign_folder: dist_sign_folder.map(PathBuf::from), + dist_upload_addr, + dist_compression_formats, + dist_compression_profile: dist_compression_profile.unwrap_or("fast".into()), + dist_include_mingw_linker: dist_include_mingw_linker.unwrap_or(true), backtrace: rust_backtrace.unwrap_or(true), low_priority: build_low_priority.unwrap_or(false), description: build_description, @@ -1302,7 +1302,7 @@ impl Config { enzyme_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/enzyme")), in_tree_llvm_info: git_info(&exec_ctx, false, &src.join("src/llvm-project")), in_tree_gcc_info: git_info(&exec_ctx, false, &src.join("src/gcc")), - dist_vendor: dist_vendor_.unwrap_or_else(|| { + dist_vendor: dist_vendor.unwrap_or_else(|| { // If we're building from git or tarball sources, enable it by default. rust_info.is_managed_git_subrepository() || rust_info.is_from_tarball() }), @@ -1332,7 +1332,7 @@ impl Config { .collect(), paths: flags_paths, config: toml_path, - llvm_thin_lto: llvm_thin_lto_.unwrap_or(false), + llvm_thin_lto: llvm_thin_lto.unwrap_or(false), rustc_debug_assertions: rust_rustc_debug_assertions.unwrap_or(rust_debug == Some(true)), lld_mode: rust_lld_mode.unwrap_or_default(), initial_cargo_clippy: build_cargo_clippy, From fce2464c8d4de263910e1360f1b2dc6f17663632 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 17:47:23 +0530 Subject: [PATCH 05/10] use local variables coming from toml, directly from toml --- src/bootstrap/src/core/config/config.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index b3fca61709e1c..0be2e33966945 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -665,9 +665,6 @@ impl Config { exec_ctx.set_verbosity(cmp::max(build_verbose.unwrap_or_default() as u8, flags_verbose)); let stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); - let bootstrap_cache_path = build_bootstrap_cache_path; - let patch_binaries_for_nix = build_patch_binaries_for_nix; - let path_modification_cache = Arc::new(Mutex::new(HashMap::new())); let host_target = flags_build @@ -681,7 +678,6 @@ impl Config { }) .unwrap_or_else(|| vec![host_target]); - let submodules = build_submodules; let llvm_assertions = llvm_assertions_.unwrap_or(false); let mut target_config = HashMap::new(); @@ -739,17 +735,17 @@ impl Config { path_modification_cache: path_modification_cache.clone(), src: &src, rust_info: rust_info.clone(), - submodules: &submodules, + submodules: &build_submodules, download_rustc_commit: download_rustc_commit.clone(), host_target, llvm_from_ci, target_config: target_config.clone(), out: out.clone(), - patch_binaries_for_nix, + patch_binaries_for_nix: build_patch_binaries_for_nix, exec_ctx: &exec_ctx, stage0_metadata: &stage0_metadata, llvm_assertions, - bootstrap_cache_path: &bootstrap_cache_path, + bootstrap_cache_path: &build_bootstrap_cache_path, is_running_on_ci, }; @@ -873,7 +869,7 @@ impl Config { } if let Some(patches) = cfg.llvm_has_rust_patches { assert!( - submodules == Some(false) || cfg.llvm_config.is_some(), + build_submodules == Some(false) || cfg.llvm_config.is_some(), "use of `llvm-has-rust-patches` is restricted to cases where either submodules are disabled or llvm-config been provided" ); target.llvm_has_rust_patches = Some(patches); @@ -1131,7 +1127,7 @@ impl Config { docs: build_docs.unwrap_or(true), locked_deps: build_locked_deps.unwrap_or(false), full_bootstrap: build_full_bootstrap.unwrap_or(false), - bootstrap_cache_path, + bootstrap_cache_path: build_bootstrap_cache_path, extended: build_extended.unwrap_or(false), tools: build_tools, tool: build_tool.unwrap_or_default(), @@ -1341,7 +1337,9 @@ impl Config { && src.join("vendor").exists() && src.join(".cargo/config.toml").exists(), ), + patch_binaries_for_nix: build_patch_binaries_for_nix, cmd: flags_cmd, + submodules: build_submodules, exec_ctx, out, rust_info, @@ -1349,7 +1347,6 @@ impl Config { initial_rustc, initial_sysroot, initial_rustfmt, - submodules, target_config, omit_git_hash, stage, @@ -1362,7 +1359,6 @@ impl Config { channel, is_running_on_ci, path_modification_cache, - patch_binaries_for_nix, stage0_metadata, download_rustc_commit, llvm_link_shared, From b91b31061cdd228a8685f8bfeb0aeac9c9d29265 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 18:07:01 +0530 Subject: [PATCH 06/10] add explicit defaults --- src/bootstrap/src/core/config/config.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 0be2e33966945..11373e3e41104 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1166,10 +1166,10 @@ impl Config { Warnings::Default => rust_deny_warnings.unwrap_or(true), }, backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), - llvm_tests: llvm_tests.unwrap_or_default(), - llvm_enzyme: llvm_enzyme.unwrap_or_default(), + llvm_tests: llvm_tests.unwrap_or(false), + llvm_enzyme: llvm_enzyme.unwrap_or(false), llvm_offload: llvm_offload.unwrap_or(false), - llvm_plugins: llvm_plugin.unwrap_or_default(), + llvm_plugins: llvm_plugin.unwrap_or(false), llvm_optimize: llvm_optimize.unwrap_or(true), llvm_release_debuginfo: llvm_release_debuginfo.unwrap_or(false), llvm_static_stdcpp: llvm_static_libstdcpp.unwrap_or(false), @@ -1230,7 +1230,7 @@ impl Config { .unwrap_or(vec![CodegenBackendKind::Llvm]), rust_verify_llvm_ir: rust_verify_llvm_ir.unwrap_or(false), rust_thin_lto_import_instr_limit, - rust_randomize_layout: rust_randomize_layout.unwrap_or_default(), + rust_randomize_layout: rust_randomize_layout.unwrap_or(false), rust_remap_debuginfo: rust_remap_debuginfo.unwrap_or(false), rust_new_symbol_mangling, rust_profile_use: flags_rust_profile_use.or(rust_profile_use), From 5ae81c984f35ed0e4334c57287ac1fbf2467dd5f Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 18:59:34 +0530 Subject: [PATCH 07/10] remove unwanted references, and make more initialization inline --- src/bootstrap/src/core/config/config.rs | 36 ++++++++++--------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 11373e3e41104..9d8f97196b61c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -623,7 +623,7 @@ impl Config { targets: llvm_targets, experimental_targets: llvm_experimental_targets, link_jobs: llvm_link_jobs, - link_shared: llvm_link_shared_, + link_shared: llvm_link_shared, version_suffix: llvm_version_suffix, clang_cl: llvm_clang_cl, cflags: llvm_cflags, @@ -682,7 +682,6 @@ impl Config { let mut target_config = HashMap::new(); let mut download_rustc_commit = None; - let llvm_link_shared = Cell::default(); let mut llvm_from_ci = false; let mut channel = "dev".to_string(); let mut out = flags_build_dir @@ -764,7 +763,7 @@ impl Config { )); let initial_cargo = build_cargo.unwrap_or_else(|| { - download_beta_toolchain(&mut dwn_ctx); + download_beta_toolchain(&dwn_ctx); initial_sysroot.join("bin").join(exe("cargo", host_target)) }); @@ -848,11 +847,9 @@ impl Config { "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); - let channel_ = read_file_by_commit(&dwn_ctx, Path::new("src/ci/channel"), commit) + channel = read_file_by_commit(&dwn_ctx, Path::new("src/ci/channel"), commit) .trim() .to_owned(); - - channel = channel_; } if let Some(t) = toml.target { @@ -917,6 +914,9 @@ impl Config { dwn_ctx.target_config = target_config.clone(); } + llvm_from_ci = parse_download_ci_llvm(&dwn_ctx, llvm_download_ci_llvm, llvm_assertions); + dwn_ctx.llvm_from_ci = llvm_from_ci; + // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will // build our internal lld and use it as the default linker, by setting the `rust.lld` config // to true by default: @@ -939,13 +939,6 @@ impl Config { rust_lld_enabled.unwrap_or(false) }; - if let Some(v) = llvm_link_shared_ { - llvm_link_shared.set(Some(v)); - } - - llvm_from_ci = parse_download_ci_llvm(&dwn_ctx, llvm_download_ci_llvm, llvm_assertions); - dwn_ctx.llvm_from_ci = llvm_from_ci; - if llvm_from_ci { let warn = |option: &str| { println!( @@ -960,7 +953,7 @@ impl Config { warn("static-libstdcpp"); } - if llvm_link_shared_.is_some() { + if llvm_link_shared.is_some() { warn("link-shared"); } @@ -981,13 +974,6 @@ impl Config { } } - if !llvm_from_ci && llvm_thin_lto.unwrap_or(false) && llvm_link_shared_.is_none() { - // If we're building with ThinLTO on, by default we want to link - // to LLVM shared, to avoid re-doing ThinLTO (which happens in - // the link step) with each stage. - llvm_link_shared.set(Some(true)); - } - if llvm_from_ci { let triple = &host_target.triple; let ci_llvm_bin = ci_llvm_root(&dwn_ctx).join("bin"); @@ -1340,6 +1326,13 @@ impl Config { patch_binaries_for_nix: build_patch_binaries_for_nix, cmd: flags_cmd, submodules: build_submodules, + // If we're building with ThinLTO on, by default we want to link + // to LLVM shared, to avoid re-doing ThinLTO (which happens in + // the link step) with each stage. + llvm_link_shared: Cell::new( + llvm_link_shared + .or((!llvm_from_ci && llvm_thin_lto.unwrap_or(false)).then_some(true)), + ), exec_ctx, out, rust_info, @@ -1361,7 +1354,6 @@ impl Config { path_modification_cache, stage0_metadata, download_rustc_commit, - llvm_link_shared, } } From 433dc2be446c1532f764f410e868a7d7d3b0b07c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 23:24:53 +0530 Subject: [PATCH 08/10] make download context lean and remove mutable types --- src/bootstrap/src/core/config/config.rs | 98 +++++++++++++------------ src/bootstrap/src/core/download.rs | 70 ++++++++++-------- 2 files changed, 89 insertions(+), 79 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 9d8f97196b61c..5913c871d83d7 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -679,15 +679,11 @@ impl Config { .unwrap_or_else(|| vec![host_target]); let llvm_assertions = llvm_assertions_.unwrap_or(false); - let mut target_config = HashMap::new(); - let mut download_rustc_commit = None; - let mut llvm_from_ci = false; let mut channel = "dev".to_string(); let mut out = flags_build_dir .or(build_build_dir.map(PathBuf::from)) .unwrap_or_else(|| PathBuf::from("build")); - let mut rust_info = GitInfo::Absent; if cfg!(test) { // Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly. @@ -730,16 +726,11 @@ impl Config { ); } - let mut dwn_ctx = DownloadContext { + let dwn_ctx = DownloadContext { path_modification_cache: path_modification_cache.clone(), src: &src, - rust_info: rust_info.clone(), submodules: &build_submodules, - download_rustc_commit: download_rustc_commit.clone(), host_target, - llvm_from_ci, - target_config: target_config.clone(), - out: out.clone(), patch_binaries_for_nix: build_patch_binaries_for_nix, exec_ctx: &exec_ctx, stage0_metadata: &stage0_metadata, @@ -749,7 +740,7 @@ impl Config { }; let initial_rustc = build_rustc.unwrap_or_else(|| { - download_beta_toolchain(&dwn_ctx); + download_beta_toolchain(&dwn_ctx, &out); out.join(host_target).join("stage0").join("bin").join(exe("rustc", host_target)) }); @@ -763,7 +754,7 @@ impl Config { )); let initial_cargo = build_cargo.unwrap_or_else(|| { - download_beta_toolchain(&dwn_ctx); + download_beta_toolchain(&dwn_ctx, &out); initial_sysroot.join("bin").join(exe("cargo", host_target)) }); @@ -771,7 +762,6 @@ impl Config { if exec_ctx.dry_run() { out = out.join("tmp-dry-run"); fs::create_dir_all(&out).expect("Failed to create dry-run directory"); - dwn_ctx.out = out.clone(); } let file_content = t!(fs::read_to_string(src.join("src/ci/channel"))); @@ -791,8 +781,7 @@ impl Config { let omit_git_hash = rust_omit_git_hash.unwrap_or(channel == "dev"); - rust_info = git_info(&exec_ctx, omit_git_hash, &src); - dwn_ctx.rust_info = rust_info.clone(); + let rust_info = git_info(&exec_ctx, omit_git_hash, &src); if !is_user_configured_rust_channel && rust_info.is_from_tarball() { channel = ci_channel.into(); @@ -823,9 +812,8 @@ impl Config { ); } - download_rustc_commit = - download_ci_rustc_commit(&dwn_ctx, rust_download_rustc, llvm_assertions); - dwn_ctx.download_rustc_commit = download_rustc_commit.clone(); + let mut download_rustc_commit = + download_ci_rustc_commit(&dwn_ctx, &rust_info, rust_download_rustc, llvm_assertions); if debug_assertions_requested && download_rustc_commit.is_some() { eprintln!( @@ -834,7 +822,6 @@ impl Config { ); // We need to put this later down_ci_rustc_commit. download_rustc_commit = None; - dwn_ctx.download_rustc_commit = None; } // We need to override `rust.channel` if it's manually specified when using the CI rustc. @@ -847,9 +834,10 @@ impl Config { "WARNING: `rust.download-rustc` is enabled. The `rust.channel` option will be overridden by the CI rustc's channel." ); - channel = read_file_by_commit(&dwn_ctx, Path::new("src/ci/channel"), commit) - .trim() - .to_owned(); + channel = + read_file_by_commit(&dwn_ctx, &rust_info, Path::new("src/ci/channel"), commit) + .trim() + .to_owned(); } if let Some(t) = toml.target { @@ -911,11 +899,15 @@ impl Config { target_config.insert(TargetSelection::from_user(&triple), target); } - dwn_ctx.target_config = target_config.clone(); } - llvm_from_ci = parse_download_ci_llvm(&dwn_ctx, llvm_download_ci_llvm, llvm_assertions); - dwn_ctx.llvm_from_ci = llvm_from_ci; + let llvm_from_ci = parse_download_ci_llvm( + &dwn_ctx, + &rust_info, + &download_rustc_commit, + llvm_download_ci_llvm, + llvm_assertions, + ); // We make `x86_64-unknown-linux-gnu` use the self-contained linker by default, so we will // build our internal lld and use it as the default linker, by setting the `rust.lld` config @@ -976,18 +968,16 @@ impl Config { if llvm_from_ci { let triple = &host_target.triple; - let ci_llvm_bin = ci_llvm_root(&dwn_ctx).join("bin"); + let ci_llvm_bin = ci_llvm_root(&dwn_ctx, llvm_from_ci, &out).join("bin"); let build_target = target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple)); - dwn_ctx.target_config.entry(host_target).or_insert_with(|| Target::from_triple(triple)); - check_ci_llvm!(build_target.llvm_config); check_ci_llvm!(build_target.llvm_filecheck); build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", host_target))); build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", host_target))); } - let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx)); + let initial_rustfmt = build_rustfmt.or_else(|| maybe_download_rustfmt(&dwn_ctx, &out)); if matches!(rust_lld_mode.unwrap_or_default(), LldMode::SelfContained) && !lld_enabled @@ -998,7 +988,7 @@ impl Config { ); } - if lld_enabled && is_system_llvm(&dwn_ctx, host_target) { + if lld_enabled && is_system_llvm(&dwn_ctx, &target_config, llvm_from_ci, host_target) { panic!("Cannot enable LLD with `rust.lld = true` when using external llvm-config."); } @@ -1392,7 +1382,7 @@ impl Config { /// Returns the content of the given file at a specific commit. pub(crate) fn read_file_by_commit(&self, file: &Path, commit: &str) -> String { let dwn_ctx = DownloadContext::from(self); - read_file_by_commit(dwn_ctx, file, commit) + read_file_by_commit(dwn_ctx, &self.rust_info, file, commit) } /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. @@ -1464,7 +1454,7 @@ impl Config { /// The absolute path to the downloaded LLVM artifacts. pub(crate) fn ci_llvm_root(&self) -> PathBuf { let dwn_ctx = DownloadContext::from(self); - ci_llvm_root(dwn_ctx) + ci_llvm_root(dwn_ctx, self.llvm_from_ci, &self.out) } /// Directory where the extracted `rustc-dev` component is stored. @@ -1628,7 +1618,7 @@ impl Config { )] pub(crate) fn update_submodule(&self, relative_path: &str) { let dwn_ctx = DownloadContext::from(self); - update_submodule(dwn_ctx, relative_path); + update_submodule(dwn_ctx, &self.rust_info, relative_path); } /// Returns true if any of the `paths` have been modified locally. @@ -1744,7 +1734,7 @@ impl Config { /// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. pub fn is_system_llvm(&self, target: TargetSelection) -> bool { let dwn_ctx = DownloadContext::from(self); - is_system_llvm(dwn_ctx, target) + is_system_llvm(dwn_ctx, &self.target_config, self.llvm_from_ci, target) } /// Returns `true` if this is our custom, patched, version of LLVM. @@ -2038,6 +2028,7 @@ pub fn check_stage0_version( pub fn download_ci_rustc_commit<'a>( dwn_ctx: impl AsRef>, + rust_info: &channel::GitInfo, download_rustc: Option, llvm_assertions: bool, ) -> Option { @@ -2057,7 +2048,7 @@ pub fn download_ci_rustc_commit<'a>( None | Some(StringOrBool::Bool(false)) => return None, Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => { - if !dwn_ctx.rust_info.is_managed_git_subrepository() { + if !rust_info.is_managed_git_subrepository() { println!( "ERROR: `download-rustc=if-unchanged` is only compatible with Git managed sources." ); @@ -2071,7 +2062,7 @@ pub fn download_ci_rustc_commit<'a>( } }; - let commit = if dwn_ctx.rust_info.is_managed_git_subrepository() { + let commit = if rust_info.is_managed_git_subrepository() { // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. let freshness = check_path_modifications_(dwn_ctx, RUSTC_IF_UNCHANGED_ALLOWED_PATHS); @@ -2145,6 +2136,8 @@ pub fn git_config(stage0_metadata: &build_helper::stage0_parser::Stage0) -> GitC pub fn parse_download_ci_llvm<'a>( dwn_ctx: impl AsRef>, + rust_info: &channel::GitInfo, + download_rustc_commit: &Option, download_ci_llvm: Option, asserts: bool, ) -> bool { @@ -2160,7 +2153,7 @@ pub fn parse_download_ci_llvm<'a>( let download_ci_llvm = download_ci_llvm.unwrap_or(default); let if_unchanged = || { - if dwn_ctx.rust_info.is_from_tarball() { + if rust_info.is_from_tarball() { // Git is needed for running "if-unchanged" logic. println!("ERROR: 'if-unchanged' is only compatible with Git managed sources."); crate::exit!(1); @@ -2168,7 +2161,7 @@ pub fn parse_download_ci_llvm<'a>( // Fetching the LLVM submodule is unnecessary for self-tests. #[cfg(not(test))] - update_submodule(dwn_ctx, "src/llvm-project"); + update_submodule(dwn_ctx, rust_info, "src/llvm-project"); // Check for untracked changes in `src/llvm-project` and other important places. let has_changes = has_changes_from_upstream(dwn_ctx, LLVM_INVALIDATION_PATHS); @@ -2183,7 +2176,7 @@ pub fn parse_download_ci_llvm<'a>( match download_ci_llvm { StringOrBool::Bool(b) => { - if !b && dwn_ctx.download_rustc_commit.is_some() { + if !b && download_rustc_commit.is_some() { panic!( "`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`." ); @@ -2226,9 +2219,13 @@ pub fn has_changes_from_upstream<'a>( fields(relative_path = ?relative_path), ), )] -pub(crate) fn update_submodule<'a>(dwn_ctx: impl AsRef>, relative_path: &str) { +pub(crate) fn update_submodule<'a>( + dwn_ctx: impl AsRef>, + rust_info: &channel::GitInfo, + relative_path: &str, +) { let dwn_ctx = dwn_ctx.as_ref(); - if dwn_ctx.rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, &dwn_ctx.rust_info) { + if rust_info.is_from_tarball() || !submodules_(dwn_ctx.submodules, rust_info) { return; } @@ -2357,12 +2354,14 @@ pub fn submodules_(submodules: &Option, rust_info: &channel::GitInfo) -> b /// NOTE: this is not the same as `!is_rust_llvm` when `llvm_has_patches` is set. pub fn is_system_llvm<'a>( dwn_ctx: impl AsRef>, + target_config: &HashMap, + llvm_from_ci: bool, target: TargetSelection, ) -> bool { let dwn_ctx = dwn_ctx.as_ref(); - match dwn_ctx.target_config.get(&target) { + match target_config.get(&target) { Some(Target { llvm_config: Some(_), .. }) => { - let ci_llvm = dwn_ctx.llvm_from_ci && is_host_target(&dwn_ctx.host_target, &target); + let ci_llvm = llvm_from_ci && is_host_target(&dwn_ctx.host_target, &target); !ci_llvm } // We're building from the in-tree src/llvm-project sources. @@ -2375,21 +2374,26 @@ pub fn is_host_target(host_target: &TargetSelection, target: &TargetSelection) - host_target == target } -pub(crate) fn ci_llvm_root<'a>(dwn_ctx: impl AsRef>) -> PathBuf { +pub(crate) fn ci_llvm_root<'a>( + dwn_ctx: impl AsRef>, + llvm_from_ci: bool, + out: &Path, +) -> PathBuf { let dwn_ctx = dwn_ctx.as_ref(); - assert!(dwn_ctx.llvm_from_ci); - dwn_ctx.out.join(dwn_ctx.host_target).join("ci-llvm") + assert!(llvm_from_ci); + out.join(dwn_ctx.host_target).join("ci-llvm") } /// Returns the content of the given file at a specific commit. pub(crate) fn read_file_by_commit<'a>( dwn_ctx: impl AsRef>, + rust_info: &channel::GitInfo, file: &Path, commit: &str, ) -> String { let dwn_ctx = dwn_ctx.as_ref(); assert!( - dwn_ctx.rust_info.is_managed_git_subrepository(), + rust_info.is_managed_git_subrepository(), "`Config::read_file_by_commit` is not supported in non-git sources." ); diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 402d6019dabbb..2f3c80559c0ef 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -9,9 +9,8 @@ use std::sync::{Arc, Mutex, OnceLock}; use build_helper::git::PathFreshness; use xz2::bufread::XzDecoder; -use crate::core::config::{BUILDER_CONFIG_FILENAME, Target, TargetSelection}; +use crate::core::config::{BUILDER_CONFIG_FILENAME, TargetSelection}; use crate::utils::build_stamp::BuildStamp; -use crate::utils::channel; use crate::utils::exec::{ExecutionContext, command}; use crate::utils::helpers::{exe, hex_encode, move_file}; use crate::{Config, t}; @@ -73,7 +72,7 @@ impl Config { fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { let dwn_ctx: DownloadContext<'_> = self.into(); - download_file(dwn_ctx, url, dest_path, help_on_error); + download_file(dwn_ctx, &self.out, url, dest_path, help_on_error); } fn unpack(&self, tarball: &Path, dst: &Path, pattern: &str) { @@ -238,7 +237,7 @@ impl Config { destination: &str, ) { let dwn_ctx: DownloadContext<'_> = self.into(); - download_component(dwn_ctx, mode, filename, prefix, key, destination); + download_component(dwn_ctx, &self.out, mode, filename, prefix, key, destination); } #[cfg(test)] @@ -403,13 +402,8 @@ impl Config { pub(crate) struct DownloadContext<'a> { pub path_modification_cache: Arc, PathFreshness>>>, pub src: &'a Path, - pub rust_info: channel::GitInfo, pub submodules: &'a Option, - pub download_rustc_commit: Option, pub host_target: TargetSelection, - pub llvm_from_ci: bool, - pub target_config: HashMap, - pub out: PathBuf, pub patch_binaries_for_nix: Option, pub exec_ctx: &'a ExecutionContext, pub stage0_metadata: &'a build_helper::stage0_parser::Stage0, @@ -430,12 +424,7 @@ impl<'a> From<&'a Config> for DownloadContext<'a> { path_modification_cache: value.path_modification_cache.clone(), src: &value.src, host_target: value.host_target, - rust_info: value.rust_info.clone(), - download_rustc_commit: value.download_rustc_commit.clone(), submodules: &value.submodules, - llvm_from_ci: value.llvm_from_ci, - target_config: value.target_config.clone(), - out: value.out.clone(), patch_binaries_for_nix: value.patch_binaries_for_nix, exec_ctx: &value.exec_ctx, stage0_metadata: &value.stage0_metadata, @@ -495,6 +484,7 @@ pub(crate) fn is_download_ci_available(target_triple: &str, llvm_assertions: boo #[cfg(test)] pub(crate) fn maybe_download_rustfmt<'a>( dwn_ctx: impl AsRef>, + out: &Path, ) -> Option { Some(PathBuf::new()) } @@ -504,6 +494,7 @@ pub(crate) fn maybe_download_rustfmt<'a>( #[cfg(not(test))] pub(crate) fn maybe_download_rustfmt<'a>( dwn_ctx: impl AsRef>, + out: &Path, ) -> Option { use build_helper::stage0_parser::VersionMetadata; @@ -517,7 +508,7 @@ pub(crate) fn maybe_download_rustfmt<'a>( let channel = format!("{version}-{date}"); let host = dwn_ctx.host_target; - let bin_root = dwn_ctx.out.join(host).join("rustfmt"); + let bin_root = out.join(host).join("rustfmt"); let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host)); let rustfmt_stamp = BuildStamp::new(&bin_root).with_prefix("rustfmt").add_stamp(channel); if rustfmt_path.exists() && rustfmt_stamp.is_up_to_date() { @@ -526,6 +517,7 @@ pub(crate) fn maybe_download_rustfmt<'a>( download_component( dwn_ctx, + out, DownloadSource::Dist, format!("rustfmt-{version}-{build}.tar.xz", build = host.triple), "rustfmt-preview", @@ -535,6 +527,7 @@ pub(crate) fn maybe_download_rustfmt<'a>( download_component( dwn_ctx, + out, DownloadSource::Dist, format!("rustc-{version}-{build}.tar.xz", build = host.triple), "rustc", @@ -543,13 +536,13 @@ pub(crate) fn maybe_download_rustfmt<'a>( ); if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) { - fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx); - fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &bin_root.join("bin").join("rustfmt"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &bin_root.join("bin").join("cargo-fmt"), dwn_ctx.exec_ctx); let lib_dir = bin_root.join("lib"); for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib); if path_is_dylib(&lib.path()) { - fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &lib.path(), dwn_ctx.exec_ctx); } } } @@ -559,10 +552,10 @@ pub(crate) fn maybe_download_rustfmt<'a>( } #[cfg(test)] -pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef>) {} +pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef>, out: &Path) {} #[cfg(not(test))] -pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef>) { +pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef>, out: &Path) { let dwn_ctx = dwn_ctx.as_ref(); dwn_ctx.exec_ctx.verbose(|| { println!("downloading stage0 beta artifacts"); @@ -574,6 +567,7 @@ pub(crate) fn download_beta_toolchain<'a>(dwn_ctx: impl AsRef(dwn_ctx: impl AsRef( dwn_ctx: impl AsRef>, + out: &Path, version: &str, sysroot: &str, stamp_key: &str, @@ -594,7 +590,7 @@ fn download_toolchain<'a>( ) { let dwn_ctx = dwn_ctx.as_ref(); let host = dwn_ctx.host_target.triple; - let bin_root = dwn_ctx.out.join(host).join(sysroot); + let bin_root = out.join(host).join(sysroot); let rustc_stamp = BuildStamp::new(&bin_root).with_prefix("rustc").add_stamp(stamp_key); if !bin_root.join("bin").join(exe("rustc", dwn_ctx.host_target)).exists() @@ -605,20 +601,28 @@ fn download_toolchain<'a>( } let filename = format!("rust-std-{version}-{host}.tar.xz"); let pattern = format!("rust-std-{host}"); - download_component(dwn_ctx, mode.clone(), filename, &pattern, stamp_key, destination); + download_component(dwn_ctx, out, mode.clone(), filename, &pattern, stamp_key, destination); let filename = format!("rustc-{version}-{host}.tar.xz"); - download_component(dwn_ctx, mode.clone(), filename, "rustc", stamp_key, destination); + download_component(dwn_ctx, out, mode.clone(), filename, "rustc", stamp_key, destination); for component in extra_components { let filename = format!("{component}-{version}-{host}.tar.xz"); - download_component(dwn_ctx, mode.clone(), filename, component, stamp_key, destination); + download_component( + dwn_ctx, + out, + mode.clone(), + filename, + component, + stamp_key, + destination, + ); } if should_fix_bins_and_dylibs(dwn_ctx.patch_binaries_for_nix, dwn_ctx.exec_ctx) { - fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx); - fix_bin_or_dylib(&dwn_ctx.out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &bin_root.join("bin").join("rustc"), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &bin_root.join("bin").join("rustdoc"), dwn_ctx.exec_ctx); fix_bin_or_dylib( - &dwn_ctx.out, + out, &bin_root.join("libexec").join("rust-analyzer-proc-macro-srv"), dwn_ctx.exec_ctx, ); @@ -626,7 +630,7 @@ fn download_toolchain<'a>( for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib); if path_is_dylib(&lib.path()) { - fix_bin_or_dylib(&dwn_ctx.out, &lib.path(), dwn_ctx.exec_ctx); + fix_bin_or_dylib(out, &lib.path(), dwn_ctx.exec_ctx); } } } @@ -750,6 +754,7 @@ fn should_fix_bins_and_dylibs( fn download_component<'a>( dwn_ctx: impl AsRef>, + out: &Path, mode: DownloadSource, filename: String, prefix: &str, @@ -763,14 +768,14 @@ fn download_component<'a>( } let cache_dst = - dwn_ctx.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| dwn_ctx.out.join("cache")); + dwn_ctx.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| out.join("cache")); let cache_dir = cache_dst.join(key); if !cache_dir.exists() { t!(fs::create_dir_all(&cache_dir)); } - let bin_root = dwn_ctx.out.join(dwn_ctx.host_target).join(destination); + let bin_root = out.join(dwn_ctx.host_target).join(destination); let tarball = cache_dir.join(&filename); let (base_url, url, should_verify) = match mode { DownloadSource::CI => { @@ -835,7 +840,7 @@ HELP: if trying to compile an old commit of rustc, disable `download-rustc` in b download-rustc = false "; } - download_file(dwn_ctx, &format!("{base_url}/{url}"), &tarball, help_on_error); + download_file(dwn_ctx, out, &format!("{base_url}/{url}"), &tarball, help_on_error); if let Some(sha256) = checksum && !verify(dwn_ctx.exec_ctx, &tarball, sha256) { @@ -953,6 +958,7 @@ fn unpack(exec_ctx: &ExecutionContext, tarball: &Path, dst: &Path, pattern: &str fn download_file<'a>( dwn_ctx: impl AsRef>, + out: &Path, url: &str, dest_path: &Path, help_on_error: &str, @@ -963,7 +969,7 @@ fn download_file<'a>( println!("download {url}"); }); // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. - let tempfile = tempdir(&dwn_ctx.out).join(dest_path.file_name().unwrap()); + let tempfile = tempdir(out).join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might // need to download components from other protocols. The match allows them adding more // protocols without worrying about merge conflicts if we change the HTTP implementation. From e261e25c9973a71f9d6cf5ee32640de9e28c6369 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 20 Aug 2025 23:40:59 +0530 Subject: [PATCH 09/10] move few complex initialization from config to parse-inner --- src/bootstrap/src/core/config/config.rs | 110 +++++++++++++----------- 1 file changed, 61 insertions(+), 49 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 5913c871d83d7..efc76a0df648c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -687,7 +687,7 @@ impl Config { if cfg!(test) { // Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly. - if out == PathBuf::from("build") { + if out == Path::new("build") { out = Path::new( &env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"), ) @@ -1088,14 +1088,64 @@ impl Config { ) }; + let ccache = match build_ccache { + Some(StringOrBool::String(s)) => Some(s), + Some(StringOrBool::Bool(true)) => Some("ccache".to_string()), + _ => None, + }; + + let explicit_stage_from_config = build_test_stage.is_some() + || build_build_stage.is_some() + || build_doc_stage.is_some() + || build_dist_stage.is_some() + || build_install_stage.is_some() + || build_check_stage.is_some() + || build_bench_stage.is_some(); + + let deny_warnings = match flags_warnings { + Warnings::Deny => true, + Warnings::Warn => false, + Warnings::Default => rust_deny_warnings.unwrap_or(true), + }; + + let gcc_ci_mode = match gcc_download_ci_gcc { + Some(value) => match value { + true => GccCiMode::DownloadFromCi, + false => GccCiMode::BuildLocally, + }, + None => GccCiMode::default(), + }; + + let targets = flags_target + .map(|TargetSelectionList(targets)| targets) + .or_else(|| { + build_target.map(|t| t.iter().map(|t| TargetSelection::from_user(t)).collect()) + }) + .unwrap_or_else(|| hosts.clone()); + + #[allow(clippy::map_identity)] + let skip = flags_skip + .into_iter() + .chain(flags_exclude) + .chain(build_exclude.unwrap_or_default()) + .map(|p| { + // Never return top-level path here as it would break `--skip` + // logic on rustc's internal test framework which is utilized by compiletest. + #[cfg(windows)] + { + PathBuf::from(p.to_string_lossy().replace('/', "\\")) + } + #[cfg(not(windows))] + { + p + } + }) + .collect(); + Config { change_id: toml.change_id.inner, bypass_bootstrap_lock: flags_bypass_bootstrap_lock, - ccache: match build_ccache { - Some(StringOrBool::String(s)) => Some(s), - Some(StringOrBool::Bool(true)) => Some("ccache".to_string()), - _ => None, - }, + ccache, ninja_in_file: llvm_ninja.unwrap_or(true), compiler_docs: build_compiler_docs.unwrap_or(false), library_docs_private_items: build_library_docs_private_items.unwrap_or(false), @@ -1122,13 +1172,7 @@ impl Config { stderr_is_tty: std::io::stderr().is_terminal(), on_fail: flags_on_fail, explicit_stage_from_cli: flags_stage.is_some(), - explicit_stage_from_config: build_test_stage.is_some() - || build_build_stage.is_some() - || build_doc_stage.is_some() - || build_dist_stage.is_some() - || build_install_stage.is_some() - || build_check_stage.is_some() - || build_bench_stage.is_some(), + explicit_stage_from_config, keep_stage: flags_keep_stage, keep_stage_std: flags_keep_stage_std, @@ -1136,11 +1180,7 @@ impl Config { incremental: flags_incremental || rust_incremental == Some(true), dump_bootstrap_shims: flags_dump_bootstrap_shims, free_args: flags_free_args, - deny_warnings: match flags_warnings { - Warnings::Deny => true, - Warnings::Warn => false, - Warnings::Default => rust_deny_warnings.unwrap_or(true), - }, + deny_warnings, backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), llvm_tests: llvm_tests.unwrap_or(false), llvm_enzyme: llvm_enzyme.unwrap_or(false), @@ -1167,13 +1207,7 @@ impl Config { llvm_cxxflags, llvm_ldflags, llvm_use_libcxx: llvm_use_libcxx.unwrap_or(false), - gcc_ci_mode: match gcc_download_ci_gcc { - Some(value) => match value { - true => GccCiMode::DownloadFromCi, - false => GccCiMode::BuildLocally, - }, - None => GccCiMode::default(), - }, + gcc_ci_mode, rust_optimize: rust_optimize.unwrap_or(RustOptimize::Bool(true)), rust_codegen_units: rust_codegen_units.map(threads_from_config), rust_codegen_units_std: rust_codegen_units_std.map(threads_from_config), @@ -1278,30 +1312,8 @@ impl Config { // If we're building from git or tarball sources, enable it by default. rust_info.is_managed_git_subrepository() || rust_info.is_from_tarball() }), - targets: flags_target - .map(|TargetSelectionList(targets)| targets) - .or_else(|| { - build_target.map(|t| t.iter().map(|t| TargetSelection::from_user(t)).collect()) - }) - .unwrap_or_else(|| hosts.clone()), - #[allow(clippy::map_identity)] - skip: flags_skip - .into_iter() - .chain(flags_exclude) - .chain(build_exclude.unwrap_or_default()) - .map(|p| { - // Never return top-level path here as it would break `--skip` - // logic on rustc's internal test framework which is utilized by compiletest. - #[cfg(windows)] - { - PathBuf::from(p.to_string_lossy().replace('/', "\\")) - } - #[cfg(not(windows))] - { - p - } - }) - .collect(), + targets, + skip, paths: flags_paths, config: toml_path, llvm_thin_lto: llvm_thin_lto.unwrap_or(false), From c058ce594bb6b899af6402bb6b894448f36ca3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 22 Aug 2025 12:08:58 +0200 Subject: [PATCH 10/10] Sort Config fields and remove some `mut`s from bindings --- src/bootstrap/src/core/config/config.rs | 408 ++++++++++++------------ 1 file changed, 210 insertions(+), 198 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index efc76a0df648c..51e7012d1c40f 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -463,7 +463,6 @@ impl Config { ); // Set config values based on flags. - let mut exec_ctx = ExecutionContext::new(flags_verbose, flags_cmd.fail_fast()); exec_ctx.set_dry_run(if flags_dry_run { DryRun::UserSelected } else { DryRun::Disabled }); let mut src = { @@ -479,8 +478,6 @@ impl Config { // Now load the TOML config, as soon as possible let (mut toml, toml_path) = load_toml_config(&src, flags_config, &get_toml); - let is_running_on_ci = flags_ci.unwrap_or(CiEnv::is_ci()); - postprocess_toml(&mut toml, &src, toml_path.clone(), &exec_ctx, &flags_set, &get_toml); // Now override TOML values with flags, to make sure that we won't later override flags with @@ -613,7 +610,7 @@ impl Config { optimize: llvm_optimize, thin_lto: llvm_thin_lto, release_debuginfo: llvm_release_debuginfo, - assertions: llvm_assertions_, + assertions: llvm_assertions, tests: llvm_tests, enzyme: llvm_enzyme, plugins: llvm_plugin, @@ -678,23 +675,33 @@ impl Config { }) .unwrap_or_else(|| vec![host_target]); - let llvm_assertions = llvm_assertions_.unwrap_or(false); + let llvm_assertions = llvm_assertions.unwrap_or(false); let mut target_config = HashMap::new(); let mut channel = "dev".to_string(); - let mut out = flags_build_dir - .or(build_build_dir.map(PathBuf::from)) - .unwrap_or_else(|| PathBuf::from("build")); - - if cfg!(test) { - // Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly. - if out == Path::new("build") { - out = Path::new( + let out = flags_build_dir.or(build_build_dir.map(PathBuf::from)).unwrap_or_else(|| { + if cfg!(test) { + // Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly. + Path::new( &env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"), ) .parent() .unwrap() - .to_path_buf(); + .to_path_buf() + } else { + PathBuf::from("build") } + }); + + // NOTE: Bootstrap spawns various commands with different working directories. + // To avoid writing to random places on the file system, `config.out` needs to be an absolute path. + let mut out = if !out.is_absolute() { + // `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead. + absolute(&out).expect("can't make empty path absolute") + } else { + out + }; + + if cfg!(test) { // When configuring bootstrap for tests, make sure to set the rustc and Cargo to the // same ones used to call the tests (if custom ones are not defined in the toml). If we // don't do that, bootstrap will use its own detection logic to find a suitable rustc @@ -704,13 +711,6 @@ impl Config { build_cargo = build_cargo.take().or(std::env::var_os("CARGO").map(|p| p.into())); } - // NOTE: Bootstrap spawns various commands with different working directories. - // To avoid writing to random places on the file system, `config.out` needs to be an absolute path. - if !out.is_absolute() { - // `canonicalize` requires the path to already exist. Use our vendored copy of `absolute` instead. - out = absolute(&out).expect("can't make empty path absolute"); - } - if !flags_skip_stage0_validation { if let Some(rustc) = &build_rustc { check_stage0_version(rustc, "rustc", &src, &exec_ctx); @@ -726,6 +726,7 @@ impl Config { ); } + let is_running_on_ci = flags_ci.unwrap_or(CiEnv::is_ci()); let dwn_ctx = DownloadContext { path_modification_cache: path_modification_cache.clone(), src: &src, @@ -1142,220 +1143,231 @@ impl Config { }) .collect(); + let cargo_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/cargo")); + let clippy_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/clippy")); + let in_tree_gcc_info = git_info(&exec_ctx, false, &src.join("src/gcc")); + let in_tree_llvm_info = git_info(&exec_ctx, false, &src.join("src/llvm-project")); + let enzyme_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/enzyme")); + let miri_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/miri")); + let rust_analyzer_info = + git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/rust-analyzer")); + let rustfmt_info = git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/rustfmt")); + + let optimized_compiler_builtins = + build_optimized_compiler_builtins.unwrap_or(channel != "dev"); + let vendor = build_vendor.unwrap_or( + rust_info.is_from_tarball() + && src.join("vendor").exists() + && src.join(".cargo/config.toml").exists(), + ); + let verbose_tests = rust_verbose_tests.unwrap_or(exec_ctx.is_verbose()); + Config { - change_id: toml.change_id.inner, + // tidy-alphabetical-start + android_ndk: build_android_ndk, + backtrace: rust_backtrace.unwrap_or(true), + backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), + bindir: install_bindir.map(PathBuf::from).unwrap_or("bin".into()), + bootstrap_cache_path: build_bootstrap_cache_path, bypass_bootstrap_lock: flags_bypass_bootstrap_lock, + cargo_info, + cargo_native_static: build_cargo_native_static.unwrap_or(false), ccache, - ninja_in_file: llvm_ninja.unwrap_or(true), + change_id: toml.change_id.inner, + channel, + clippy_info, + cmd: flags_cmd, + codegen_tests: rust_codegen_tests.unwrap_or(true), + color: flags_color, + compile_time_deps: flags_compile_time_deps, compiler_docs: build_compiler_docs.unwrap_or(false), - library_docs_private_items: build_library_docs_private_items.unwrap_or(false), - docs_minification: build_docs_minification.unwrap_or(true), + compiletest_allow_stage0: build_compiletest_allow_stage0.unwrap_or(false), + compiletest_diff_tool: build_compiletest_diff_tool, + compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest.unwrap_or(true), + config: toml_path, + configure_args: build_configure_args.unwrap_or_default(), + control_flow_guard: rust_control_flow_guard.unwrap_or(false), + datadir: install_datadir.map(PathBuf::from), + deny_warnings, + description: build_description, + dist_compression_formats, + dist_compression_profile: dist_compression_profile.unwrap_or("fast".into()), + dist_include_mingw_linker: dist_include_mingw_linker.unwrap_or(true), + dist_sign_folder: dist_sign_folder.map(PathBuf::from), + dist_upload_addr, + dist_vendor: dist_vendor.unwrap_or_else(|| { + // If we're building from git or tarball sources, enable it by default. + rust_info.is_managed_git_subrepository() || rust_info.is_from_tarball() + }), + docdir: install_docdir.map(PathBuf::from), docs: build_docs.unwrap_or(true), - locked_deps: build_locked_deps.unwrap_or(false), - full_bootstrap: build_full_bootstrap.unwrap_or(false), - bootstrap_cache_path: build_bootstrap_cache_path, + docs_minification: build_docs_minification.unwrap_or(true), + download_rustc_commit, + dump_bootstrap_shims: flags_dump_bootstrap_shims, + ehcont_guard: rust_ehcont_guard.unwrap_or(false), + enable_bolt_settings: flags_enable_bolt_settings, + enzyme_info, + exec_ctx, + explicit_stage_from_cli: flags_stage.is_some(), + explicit_stage_from_config, extended: build_extended.unwrap_or(false), - tools: build_tools, - tool: build_tool.unwrap_or_default(), - sanitizers: build_sanitizers.unwrap_or(false), - profiler: build_profiler.unwrap_or(false), + free_args: flags_free_args, + full_bootstrap: build_full_bootstrap.unwrap_or(false), + gcc_ci_mode, + gdb: build_gdb.map(PathBuf::from), + host_target, + hosts, + in_tree_gcc_info, + in_tree_llvm_info, include_default_paths: flags_include_default_paths, - rustc_error_format: flags_rustc_error_format, + incremental: flags_incremental || rust_incremental == Some(true), + initial_cargo, + initial_cargo_clippy: build_cargo_clippy, + initial_rustc, + initial_rustfmt, + initial_sysroot, + is_running_on_ci, + jemalloc: rust_jemalloc.unwrap_or(false), + jobs: Some(threads_from_config(flags_jobs.or(build_jobs).unwrap_or(0))), json_output: flags_json_output, - compile_time_deps: flags_compile_time_deps, - test_compare_mode: rust_test_compare_mode.unwrap_or(false), - color: flags_color, - android_ndk: build_android_ndk, - optimized_compiler_builtins: build_optimized_compiler_builtins - .unwrap_or(channel != "dev"), - stdout_is_tty: std::io::stdout().is_terminal(), - stderr_is_tty: std::io::stderr().is_terminal(), - on_fail: flags_on_fail, - explicit_stage_from_cli: flags_stage.is_some(), - explicit_stage_from_config, - keep_stage: flags_keep_stage, keep_stage_std: flags_keep_stage_std, - jobs: Some(threads_from_config(flags_jobs.or(build_jobs).unwrap_or(0))), - incremental: flags_incremental || rust_incremental == Some(true), - dump_bootstrap_shims: flags_dump_bootstrap_shims, - free_args: flags_free_args, - deny_warnings, - backtrace_on_ice: rust_backtrace_on_ice.unwrap_or(false), - llvm_tests: llvm_tests.unwrap_or(false), + libdir: install_libdir.map(PathBuf::from), + library_docs_private_items: build_library_docs_private_items.unwrap_or(false), + lld_enabled, + lld_mode: rust_lld_mode.unwrap_or_default(), + lldb: build_lldb.map(PathBuf::from), + llvm_allow_old_toolchain: llvm_allow_old_toolchain.unwrap_or(false), + llvm_assertions, + llvm_bitcode_linker_enabled: rust_llvm_bitcode_linker.unwrap_or(false), + llvm_build_config: llvm_build_config.clone().unwrap_or(Default::default()), + llvm_cflags, + llvm_clang: llvm_clang.unwrap_or(false), + llvm_clang_cl, + llvm_cxxflags, + llvm_enable_warnings: llvm_enable_warnings.unwrap_or(false), llvm_enzyme: llvm_enzyme.unwrap_or(false), + llvm_experimental_targets, + llvm_from_ci, + llvm_ldflags, + llvm_libunwind_default: rust_llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")), + llvm_libzstd: llvm_libzstd.unwrap_or(false), + llvm_link_jobs, + // If we're building with ThinLTO on, by default we want to link + // to LLVM shared, to avoid re-doing ThinLTO (which happens in + // the link step) with each stage. + llvm_link_shared: Cell::new( + llvm_link_shared + .or((!llvm_from_ci && llvm_thin_lto.unwrap_or(false)).then_some(true)), + ), llvm_offload: llvm_offload.unwrap_or(false), - llvm_plugins: llvm_plugin.unwrap_or(false), llvm_optimize: llvm_optimize.unwrap_or(true), + llvm_plugins: llvm_plugin.unwrap_or(false), + llvm_polly: llvm_polly.unwrap_or(false), + llvm_profile_generate: flags_llvm_profile_generate, + llvm_profile_use: flags_llvm_profile_use, llvm_release_debuginfo: llvm_release_debuginfo.unwrap_or(false), llvm_static_stdcpp: llvm_static_libstdcpp.unwrap_or(false), - llvm_libzstd: llvm_libzstd.unwrap_or(false), - llvm_clang_cl, llvm_targets, - llvm_experimental_targets, - llvm_link_jobs, - llvm_version_suffix, - llvm_use_linker, - llvm_allow_old_toolchain: llvm_allow_old_toolchain.unwrap_or(false), - llvm_polly: llvm_polly.unwrap_or(false), - llvm_clang: llvm_clang.unwrap_or(false), - llvm_enable_warnings: llvm_enable_warnings.unwrap_or(false), - llvm_build_config: llvm_build_config.clone().unwrap_or(Default::default()), + llvm_tests: llvm_tests.unwrap_or(false), + llvm_thin_lto: llvm_thin_lto.unwrap_or(false), llvm_tools_enabled: rust_llvm_tools.unwrap_or(true), - llvm_bitcode_linker_enabled: rust_llvm_bitcode_linker.unwrap_or(false), - llvm_cflags, - llvm_cxxflags, - llvm_ldflags, llvm_use_libcxx: llvm_use_libcxx.unwrap_or(false), - gcc_ci_mode, - rust_optimize: rust_optimize.unwrap_or(RustOptimize::Bool(true)), + llvm_use_linker, + llvm_version_suffix, + local_rebuild: build_local_rebuild.unwrap_or(false), + locked_deps: build_locked_deps.unwrap_or(false), + low_priority: build_low_priority.unwrap_or(false), + mandir: install_mandir.map(PathBuf::from), + miri_info, + musl_root: rust_musl_root.map(PathBuf::from), + ninja_in_file: llvm_ninja.unwrap_or(true), + nodejs: build_nodejs.map(PathBuf::from), + npm: build_npm.map(PathBuf::from), + omit_git_hash, + on_fail: flags_on_fail, + optimized_compiler_builtins, + out, + patch_binaries_for_nix: build_patch_binaries_for_nix, + path_modification_cache, + paths: flags_paths, + prefix: install_prefix.map(PathBuf::from), + print_step_rusage: build_print_step_rusage.unwrap_or(false), + print_step_timings: build_print_step_timings.unwrap_or(false), + profiler: build_profiler.unwrap_or(false), + python: build_python.map(PathBuf::from), + reproducible_artifacts: flags_reproducible_artifact, + reuse: build_reuse.map(PathBuf::from), + rust_analyzer_info, + rust_codegen_backends: rust_codegen_backends + .map(|backends| parse_codegen_backends(backends, "rust")) + .unwrap_or(vec![CodegenBackendKind::Llvm]), rust_codegen_units: rust_codegen_units.map(threads_from_config), rust_codegen_units_std: rust_codegen_units_std.map(threads_from_config), - std_debug_assertions: rust_std_debug_assertions - .or(rust_rustc_debug_assertions) - .unwrap_or(rust_debug == Some(true)), - tools_debug_assertions: rust_tools_debug_assertions - .or(rust_rustc_debug_assertions) - .unwrap_or(rust_debug == Some(true)), - rust_overflow_checks_std: rust_overflow_checks_std - .or(rust_overflow_checks) - .unwrap_or(rust_debug == Some(true)), - rust_overflow_checks: rust_overflow_checks.unwrap_or(rust_debug == Some(true)), rust_debug_logging: rust_debug_logging .or(rust_rustc_debug_assertions) .unwrap_or(rust_debug == Some(true)), rust_debuginfo_level_rustc: with_defaults(rust_debuginfo_level_rustc), rust_debuginfo_level_std: with_defaults(rust_debuginfo_level_std), - rust_debuginfo_level_tools: with_defaults(rust_debuginfo_level_tools), rust_debuginfo_level_tests: rust_debuginfo_level_tests.unwrap_or(DebuginfoLevel::None), - rust_rpath: rust_rpath.unwrap_or(true), - rust_strip: rust_strip.unwrap_or(false), - rust_frame_pointers: rust_frame_pointers.unwrap_or(false), - rust_stack_protector, - rustc_default_linker: rust_default_linker, - rust_optimize_tests: rust_optimize_tests.unwrap_or(true), + rust_debuginfo_level_tools: with_defaults(rust_debuginfo_level_tools), rust_dist_src: dist_src_tarball.unwrap_or_else(|| rust_dist_src.unwrap_or(true)), - rust_codegen_backends: rust_codegen_backends - .map(|backends| parse_codegen_backends(backends, "rust")) - .unwrap_or(vec![CodegenBackendKind::Llvm]), - rust_verify_llvm_ir: rust_verify_llvm_ir.unwrap_or(false), - rust_thin_lto_import_instr_limit, - rust_randomize_layout: rust_randomize_layout.unwrap_or(false), - rust_remap_debuginfo: rust_remap_debuginfo.unwrap_or(false), - rust_new_symbol_mangling, - rust_profile_use: flags_rust_profile_use.or(rust_profile_use), - rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate), + rust_frame_pointers: rust_frame_pointers.unwrap_or(false), + rust_info, rust_lto: rust_lto .as_deref() .map(|value| RustcLto::from_str(value).unwrap()) .unwrap_or_default(), - rust_validate_mir_opts, + rust_new_symbol_mangling, + rust_optimize: rust_optimize.unwrap_or(RustOptimize::Bool(true)), + rust_optimize_tests: rust_optimize_tests.unwrap_or(true), + rust_overflow_checks: rust_overflow_checks.unwrap_or(rust_debug == Some(true)), + rust_overflow_checks_std: rust_overflow_checks_std + .or(rust_overflow_checks) + .unwrap_or(rust_debug == Some(true)), + rust_profile_generate: flags_rust_profile_generate.or(rust_profile_generate), + rust_profile_use: flags_rust_profile_use.or(rust_profile_use), + rust_randomize_layout: rust_randomize_layout.unwrap_or(false), + rust_remap_debuginfo: rust_remap_debuginfo.unwrap_or(false), + rust_rpath: rust_rpath.unwrap_or(true), + rust_stack_protector, rust_std_features: rust_std_features .unwrap_or(BTreeSet::from([String::from("panic-unwind")])), - llvm_profile_use: flags_llvm_profile_use, - llvm_profile_generate: flags_llvm_profile_generate, - llvm_libunwind_default: rust_llvm_libunwind - .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")), - enable_bolt_settings: flags_enable_bolt_settings, - reproducible_artifacts: flags_reproducible_artifact, - local_rebuild: build_local_rebuild.unwrap_or(false), - jemalloc: rust_jemalloc.unwrap_or(false), - control_flow_guard: rust_control_flow_guard.unwrap_or(false), - ehcont_guard: rust_ehcont_guard.unwrap_or(false), - dist_sign_folder: dist_sign_folder.map(PathBuf::from), - dist_upload_addr, - dist_compression_formats, - dist_compression_profile: dist_compression_profile.unwrap_or("fast".into()), - dist_include_mingw_linker: dist_include_mingw_linker.unwrap_or(true), - backtrace: rust_backtrace.unwrap_or(true), - low_priority: build_low_priority.unwrap_or(false), - description: build_description, - verbose_tests: rust_verbose_tests.unwrap_or(exec_ctx.is_verbose()), + rust_strip: rust_strip.unwrap_or(false), + rust_thin_lto_import_instr_limit, + rust_validate_mir_opts, + rust_verify_llvm_ir: rust_verify_llvm_ir.unwrap_or(false), + rustc_debug_assertions: rust_rustc_debug_assertions.unwrap_or(rust_debug == Some(true)), + rustc_default_linker: rust_default_linker, + rustc_error_format: flags_rustc_error_format, + rustfmt_info, + sanitizers: build_sanitizers.unwrap_or(false), save_toolstates: rust_save_toolstates.map(PathBuf::from), - print_step_timings: build_print_step_timings.unwrap_or(false), - print_step_rusage: build_print_step_rusage.unwrap_or(false), - musl_root: rust_musl_root.map(PathBuf::from), - prefix: install_prefix.map(PathBuf::from), - sysconfdir: install_sysconfdir.map(PathBuf::from), - datadir: install_datadir.map(PathBuf::from), - docdir: install_docdir.map(PathBuf::from), - bindir: install_bindir.map(PathBuf::from).unwrap_or("bin".into()), - libdir: install_libdir.map(PathBuf::from), - mandir: install_mandir.map(PathBuf::from), - codegen_tests: rust_codegen_tests.unwrap_or(true), - nodejs: build_nodejs.map(PathBuf::from), - npm: build_npm.map(PathBuf::from), - gdb: build_gdb.map(PathBuf::from), - lldb: build_lldb.map(PathBuf::from), - python: build_python.map(PathBuf::from), - reuse: build_reuse.map(PathBuf::from), - cargo_native_static: build_cargo_native_static.unwrap_or(false), - configure_args: build_configure_args.unwrap_or_default(), - compiletest_diff_tool: build_compiletest_diff_tool, - compiletest_allow_stage0: build_compiletest_allow_stage0.unwrap_or(false), - compiletest_use_stage0_libtest: build_compiletest_use_stage0_libtest.unwrap_or(true), - tidy_extra_checks: build_tidy_extra_checks, - skip_std_check_if_no_download_rustc: flags_skip_std_check_if_no_download_rustc, - cargo_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/cargo")), - rust_analyzer_info: git_info( - &exec_ctx, - omit_git_hash, - &src.join("src/tools/rust-analyzer"), - ), - clippy_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/clippy")), - miri_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/miri")), - rustfmt_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/rustfmt")), - enzyme_info: git_info(&exec_ctx, omit_git_hash, &src.join("src/tools/enzyme")), - in_tree_llvm_info: git_info(&exec_ctx, false, &src.join("src/llvm-project")), - in_tree_gcc_info: git_info(&exec_ctx, false, &src.join("src/gcc")), - dist_vendor: dist_vendor.unwrap_or_else(|| { - // If we're building from git or tarball sources, enable it by default. - rust_info.is_managed_git_subrepository() || rust_info.is_from_tarball() - }), - targets, skip, - paths: flags_paths, - config: toml_path, - llvm_thin_lto: llvm_thin_lto.unwrap_or(false), - rustc_debug_assertions: rust_rustc_debug_assertions.unwrap_or(rust_debug == Some(true)), - lld_mode: rust_lld_mode.unwrap_or_default(), - initial_cargo_clippy: build_cargo_clippy, - vendor: build_vendor.unwrap_or( - rust_info.is_from_tarball() - && src.join("vendor").exists() - && src.join(".cargo/config.toml").exists(), - ), - patch_binaries_for_nix: build_patch_binaries_for_nix, - cmd: flags_cmd, - submodules: build_submodules, - // If we're building with ThinLTO on, by default we want to link - // to LLVM shared, to avoid re-doing ThinLTO (which happens in - // the link step) with each stage. - llvm_link_shared: Cell::new( - llvm_link_shared - .or((!llvm_from_ci && llvm_thin_lto.unwrap_or(false)).then_some(true)), - ), - exec_ctx, - out, - rust_info, - initial_cargo, - initial_rustc, - initial_sysroot, - initial_rustfmt, - target_config, - omit_git_hash, - stage, + skip_std_check_if_no_download_rustc: flags_skip_std_check_if_no_download_rustc, src, - llvm_from_ci, - llvm_assertions, - lld_enabled, - host_target, - hosts, - channel, - is_running_on_ci, - path_modification_cache, + stage, stage0_metadata, - download_rustc_commit, + std_debug_assertions: rust_std_debug_assertions + .or(rust_rustc_debug_assertions) + .unwrap_or(rust_debug == Some(true)), + stderr_is_tty: std::io::stderr().is_terminal(), + stdout_is_tty: std::io::stdout().is_terminal(), + submodules: build_submodules, + sysconfdir: install_sysconfdir.map(PathBuf::from), + target_config, + targets, + test_compare_mode: rust_test_compare_mode.unwrap_or(false), + tidy_extra_checks: build_tidy_extra_checks, + tool: build_tool.unwrap_or_default(), + tools: build_tools, + tools_debug_assertions: rust_tools_debug_assertions + .or(rust_rustc_debug_assertions) + .unwrap_or(rust_debug == Some(true)), + vendor, + verbose_tests, + // tidy-alphabetical-end } }