diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 766c187e8e834..6292afdd11af2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -827,6 +827,7 @@ impl<'a> Builder<'a> { dist::Miri, dist::LlvmTools, dist::RustDev, + dist::RustDevConfig, dist::Bootstrap, dist::Extended, // It seems that PlainSourceTarball somehow changes how some of the tools @@ -1872,7 +1873,7 @@ impl<'a> Builder<'a> { // // FIXME: the guard against msvc shouldn't need to be here if target.contains("msvc") { - if let Some(ref cl) = self.config.llvm_clang_cl { + if let Some(ref cl) = self.config.llvm.clang_cl { cargo.env("CC", cl).env("CXX", cl); } } else { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index f3d95b57a76d7..7f3e52f283ec4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -809,7 +809,7 @@ impl Step for Rustc { // is already on by default in MSVC optimized builds, which is interpreted as --icf=all: // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746 // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827 - if builder.config.use_lld && !compiler.host.contains("msvc") { + if builder.config.llvm.use_lld && !compiler.host.contains("msvc") { cargo.rustflag("-Clink-args=-Wl,--icf=all"); } @@ -1002,7 +1002,7 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect // `__llvm_profile_instrument_memop` when linking `rustc_driver`. let mut llvm_linker_flags = String::new(); if builder.config.llvm_profile_generate && target.contains("msvc") { - if let Some(ref clang_cl_path) = builder.config.llvm_clang_cl { + if let Some(ref clang_cl_path) = builder.config.llvm.clang_cl { // Add clang's runtime library directory to the search path let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path); llvm_linker_flags.push_str(&format!("-L{}", clang_rt_dir.display())); @@ -1010,7 +1010,7 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect } // The config can also specify its own llvm linker flags. - if let Some(ref s) = builder.config.llvm_ldflags { + if let Some(ref s) = builder.config.llvm.ldflags { if !llvm_linker_flags.is_empty() { llvm_linker_flags.push_str(" "); } @@ -1024,7 +1024,7 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect // Building with a static libstdc++ is only supported on linux right now, // not for MSVC or macOS - if builder.config.llvm_static_stdcpp + if builder.config.llvm.static_stdcpp && !target.contains("freebsd") && !target.contains("msvc") && !target.contains("apple") @@ -1042,10 +1042,10 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect if builder.llvm_link_shared() { cargo.env("LLVM_LINK_SHARED", "1"); } - if builder.config.llvm_use_libcxx { + if builder.config.llvm.use_libcxx { cargo.env("LLVM_USE_LIBCXX", "1"); } - if builder.config.llvm_optimize && !builder.config.llvm_release_debuginfo { + if builder.config.llvm.optimize && !builder.config.llvm.release_debuginfo { cargo.env("LLVM_NDEBUG", "1"); } } @@ -1564,7 +1564,7 @@ impl Step for Assemble { }); } - let lld_install = if builder.config.lld_enabled { + let lld_install = if builder.config.llvm.lld_enabled { Some(builder.ensure(llvm::Lld { target: target_compiler.host })) } else { None diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 856a73a22b5bf..9fe2d4e1a037b 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -101,6 +101,39 @@ impl Display for DebuginfoLevel { } } +#[derive(Default, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)] +pub struct LLVMConfig { + pub assertions: bool, + pub tests: bool, + pub plugins: bool, + pub optimize: bool, + pub thin_lto: bool, + pub release_debuginfo: bool, + pub static_stdcpp: bool, + /// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm. + pub link_shared: Cell>, + pub clang_cl: Option, + pub targets: Option, + pub experimental_targets: Option, + pub link_jobs: Option, + pub version_suffix: Option, + pub use_linker: Option, + pub allow_old_toolchain: bool, + pub polly: bool, + pub clang: bool, + pub enable_warnings: bool, + pub build_config: HashMap, + + pub use_lld: bool, + pub lld_enabled: bool, + pub tools_enabled: bool, + + pub cflags: Option, + pub cxxflags: Option, + pub ldflags: Option, + pub use_libcxx: bool, +} + /// Global configuration for the entire build and/or bootstrap. /// /// This structure is parsed from `config.toml`, and some of the fields are inferred from `git` or build-time parameters. @@ -167,39 +200,8 @@ pub struct Config { pub backtrace_on_ice: bool, // llvm codegen options - pub llvm_assertions: bool, - pub llvm_tests: bool, - pub llvm_plugins: bool, - pub llvm_optimize: bool, - pub llvm_thin_lto: bool, - pub llvm_release_debuginfo: bool, - pub llvm_static_stdcpp: bool, - /// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm. - #[cfg(not(test))] - llvm_link_shared: Cell>, - #[cfg(test)] - pub llvm_link_shared: Cell>, - pub llvm_clang_cl: Option, - pub llvm_targets: Option, - pub llvm_experimental_targets: Option, - pub llvm_link_jobs: Option, - pub llvm_version_suffix: Option, - pub llvm_use_linker: Option, - pub llvm_allow_old_toolchain: bool, - pub llvm_polly: bool, - pub llvm_clang: bool, - pub llvm_enable_warnings: bool, pub llvm_from_ci: bool, - pub llvm_build_config: HashMap, - - pub use_lld: bool, - pub lld_enabled: bool, - pub llvm_tools_enabled: bool, - - pub llvm_cflags: Option, - pub llvm_cxxflags: Option, - pub llvm_ldflags: Option, - pub llvm_use_libcxx: bool, + pub llvm: LLVMConfig, // rust codegen options pub rust_optimize: RustOptimize, @@ -1052,9 +1054,9 @@ define_config! { impl Config { pub fn default_opts() -> Config { let mut config = Config::default(); - config.llvm_optimize = true; + config.llvm.optimize = true; config.ninja_in_file = true; - config.llvm_static_stdcpp = false; + config.llvm.static_stdcpp = false; config.backtrace = true; config.rust_optimize = RustOptimize::Bool(true); config.rust_optimize_tests = true; @@ -1428,9 +1430,9 @@ impl Config { if let Some(true) = rust.incremental { config.incremental = true; } - set(&mut config.use_lld, rust.use_lld); - set(&mut config.lld_enabled, rust.lld); - set(&mut config.llvm_tools_enabled, rust.llvm_tools); + set(&mut config.llvm.use_lld, rust.use_lld); + set(&mut config.llvm.lld_enabled, rust.lld); + set(&mut config.llvm.tools_enabled, rust.llvm_tools); config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); config.rustc_default_linker = rust.default_linker; config.musl_root = rust.musl_root.map(PathBuf::from); @@ -1489,43 +1491,51 @@ impl Config { llvm_assertions = llvm.assertions; llvm_tests = llvm.tests; llvm_plugins = llvm.plugins; - 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.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); if let Some(v) = llvm.link_shared { - config.llvm_link_shared.set(Some(v)); + config.llvm.link_shared.set(Some(v)); } - config.llvm_targets = llvm.targets.clone(); - config.llvm_experimental_targets = llvm.experimental_targets.clone(); - config.llvm_link_jobs = llvm.link_jobs; - config.llvm_version_suffix = llvm.version_suffix.clone(); - config.llvm_clang_cl = llvm.clang_cl.clone(); - - config.llvm_cflags = llvm.cflags.clone(); - config.llvm_cxxflags = llvm.cxxflags.clone(); - config.llvm_ldflags = llvm.ldflags.clone(); - set(&mut config.llvm_use_libcxx, llvm.use_libcxx); - config.llvm_use_linker = llvm.use_linker.clone(); - config.llvm_allow_old_toolchain = llvm.allow_old_toolchain.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()); + config.llvm.targets = llvm.targets.clone(); + config.llvm.experimental_targets = llvm.experimental_targets.clone(); + config.llvm.link_jobs = llvm.link_jobs; + config.llvm.version_suffix = llvm.version_suffix.clone(); + config.llvm.clang_cl = llvm.clang_cl.clone(); + + config.llvm.cflags = llvm.cflags.clone(); + config.llvm.cxxflags = llvm.cxxflags.clone(); + config.llvm.ldflags = llvm.ldflags.clone(); + set(&mut config.llvm.use_libcxx, llvm.use_libcxx); + config.llvm.use_linker = llvm.use_linker.clone(); + config.llvm.allow_old_toolchain = llvm.allow_old_toolchain.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 asserts = llvm_assertions.unwrap_or(false); + let mut downloaded_config = false; config.llvm_from_ci = match llvm.download_ci_llvm { - Some(StringOrBool::String(s)) => { - assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); - crate::llvm::is_ci_llvm_available(&config, asserts) - } + Some(StringOrBool::String(s)) => match s.as_str() { + "if-available" => crate::llvm::is_ci_llvm_available(&config, asserts), + "if-identical" => match crate::llvm::get_llvm_opts_from_ci(&config) { + Some(config_ci) => { + downloaded_config = true; + is_llvm_config_identical(&config_ci, &config.llvm) + } + None => false, + }, + _ => panic!("unknown option `{s}` for download-ci-llvm"), + }, Some(StringOrBool::Bool(b)) => b, None => { config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, asserts) } }; - if config.llvm_from_ci { + if config.llvm_from_ci && !downloaded_config { // None of the LLVM options, except assertions, are supported // when using downloaded LLVM. We could just ignore these but // that's potentially confusing, so force them to not be @@ -1556,11 +1566,11 @@ impl Config { } // NOTE: can never be hit when downloading from CI, since we call `check_ci_llvm!(thin_lto)` above. - if config.llvm_thin_lto && llvm.link_shared.is_none() { + if !downloaded_config && config.llvm.thin_lto && 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.llvm.link_shared.set(Some(true)); } } else { config.llvm_from_ci = @@ -1650,9 +1660,9 @@ impl Config { // Now that we've reached the end of our configuration, infer the // default values for all options that we haven't otherwise stored yet. - config.llvm_assertions = llvm_assertions.unwrap_or(false); - config.llvm_tests = llvm_tests.unwrap_or(false); - config.llvm_plugins = llvm_plugins.unwrap_or(false); + config.llvm.assertions = llvm_assertions.unwrap_or(false); + config.llvm.tests = llvm_tests.unwrap_or(false); + config.llvm.plugins = llvm_plugins.unwrap_or(false); config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true)); let default = debug == Some(true); @@ -1859,6 +1869,10 @@ impl Config { self.out.join(&*self.build.triple).join("ci-llvm") } + pub(crate) fn ci_llvm_root_opts(&self) -> PathBuf { + self.out.join(&*self.build.triple).join("ci-llvm-opts") + } + /// Directory where the extracted `rustc-dev` component is stored. pub(crate) fn ci_rustc_dir(&self) -> PathBuf { assert!(self.download_rustc()); @@ -1870,7 +1884,7 @@ impl Config { /// If `false`, llvm should be linked statically. /// This is computed on demand since LLVM might have to first be downloaded from CI. pub(crate) fn llvm_link_shared(&self) -> bool { - let mut opt = self.llvm_link_shared.get(); + let mut opt = self.llvm.link_shared.get(); if opt.is_none() && self.dry_run() { // just assume static for now - dynamic linking isn't supported on all platforms return false; @@ -1891,7 +1905,7 @@ impl Config { false } }); - self.llvm_link_shared.set(opt); + self.llvm.link_shared.set(opt); llvm_link_shared } @@ -2084,6 +2098,10 @@ impl Config { } } +fn is_llvm_config_identical(from_ci: &LLVMConfig, current: &LLVMConfig) -> bool { + from_ci == current +} + fn set(field: &mut T, val: Option) { if let Some(v) = val { *field = v; diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 8c71b7f7fc22f..43a6fd65070e7 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -469,7 +469,7 @@ impl Step for Rustc { t!(fs::create_dir_all(&dst_dir)); // Copy over lld if it's there - if builder.config.lld_enabled { + if builder.config.llvm.lld_enabled { let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin"); let rust_lld = exe("rust-lld", compiler.host); builder.copy(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld)); @@ -2297,6 +2297,48 @@ impl Step for RustDev { } } +// Tarball intended for internal consumption to ease rustc/std development. +// +// Should not be considered stable by end users. +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct RustDevConfig { + pub target: TargetSelection, +} + +impl Step for RustDevConfig { + type Output = Option; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("rust-dev-config") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(RustDevConfig { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Option { + let target = self.target; + + /* run only if llvm-config isn't used */ + if let Some(config) = builder.config.target_config.get(&target) { + if let Some(ref _s) = config.llvm_config { + builder.info(&format!("Skipping RustDevConfig ({}): external LLVM", target)); + return None; + } + } + + let mut tarball = Tarball::new(builder, "rust-dev-config", &target.triple); + tarball.set_overlay(OverlayKind::LLVM); + + let config = t!(serde_json::to_string_pretty(&builder.build.config.llvm)); + t!(std::fs::write(tarball.image_dir().join("llvm-opts.json"), config)); + + Some(tarball.generate()) + } +} + // Tarball intended for internal consumption to ease rustc/std development. // // Should not be considered stable by end users. diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index 1316461fde0ef..a4ba272fe93ab 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -425,7 +425,7 @@ impl Config { self.download_toolchain( &version, "ci-rustc", - &format!("{commit}-{}", self.llvm_assertions), + &format!("{commit}-{}", self.llvm.assertions), &extra_components, Self::download_ci_component, ); @@ -530,14 +530,14 @@ impl Config { let tarball = cache_dir.join(&filename); let (base_url, url, should_verify) = match mode { DownloadSource::CI => { - let dist_server = if self.llvm_assertions { + let dist_server = if self.llvm.assertions { self.stage0_metadata.config.artifacts_with_llvm_assertions_server.clone() } else { self.stage0_metadata.config.artifacts_server.clone() }; let url = format!( "{}/{filename}", - key.strip_suffix(&format!("-{}", self.llvm_assertions)).unwrap() + key.strip_suffix(&format!("-{}", self.llvm.assertions)).unwrap() ); (dist_server, url, false) } @@ -608,7 +608,7 @@ download-rustc = false let llvm_root = self.ci_llvm_root(); let llvm_stamp = llvm_root.join(".llvm-stamp"); let llvm_sha = detect_llvm_sha(&self, self.rust_info.is_managed_git_subrepository()); - let key = format!("{}{}", llvm_sha, self.llvm_assertions); + let key = format!("{}{}", llvm_sha, self.llvm.assertions); if program_out_of_date(&llvm_stamp, &key) && !self.dry_run() { self.download_ci_llvm(&llvm_sha); if self.should_fix_bins_and_dylibs() { @@ -644,7 +644,7 @@ download-rustc = false } fn download_ci_llvm(&self, llvm_sha: &str) { - let llvm_assertions = self.llvm_assertions; + let llvm_assertions = self.llvm.assertions; let cache_prefix = format!("llvm-{}-{}", llvm_sha, llvm_assertions); let cache_dst = self.out.join("cache"); @@ -674,4 +674,33 @@ download-rustc = false let llvm_root = self.ci_llvm_root(); self.unpack(&tarball, &llvm_root, "rust-dev"); } + + pub(crate) fn download_ci_llvm_opts(&self, llvm_sha: &str) { + let cache_prefix = format!("llvm-opts-{llvm_sha}"); + let cache_dst = self.out.join("cache"); + let rustc_cache = cache_dst.join(cache_prefix); + t!(fs::create_dir_all(&rustc_cache)); + let base = if self.llvm.assertions { + &self.stage0_metadata.config.artifacts_with_llvm_assertions_server + } else { + &self.stage0_metadata.config.artifacts_server + }; + let version = self.artifact_version_part(llvm_sha); + let filename = format!("rust-dev-config-{}-{}.tar.xz", version, self.build.triple); + let tarball = rustc_cache.join(&filename); + if !tarball.exists() { + let help_on_error = "error: failed to download llvm config from ci + + help: old builds get deleted after a certain time + help: if trying to compile an old commit of rustc, disable `download-ci-llvm` in config.toml: + + [llvm] + download-ci-llvm = false + "; + self.download_file(&format!("{base}/{llvm_sha}/{filename}"), &tarball, help_on_error); + } + + let llvm_root = self.ci_llvm_root_opts(); + self.unpack(&tarball, &llvm_root, "rust-dev-config"); + } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index de43a4019262d..ddfb278bf3388 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -902,8 +902,8 @@ impl Build { } else { let base = self.llvm_out(target).join("build"); let base = if !self.ninja() && target.contains("msvc") { - if self.config.llvm_optimize { - if self.config.llvm_release_debuginfo { + if self.config.llvm.optimize { + if self.config.llvm.release_debuginfo { base.join("RelWithDebInfo") } else { base.join("Release") @@ -1252,7 +1252,7 @@ impl Build { && !target.contains("msvc") { Some(self.cc(target)) - } else if self.config.use_lld && !self.is_fuse_ld_lld(target) && self.build == target { + } else if self.config.llvm.use_lld && !self.is_fuse_ld_lld(target) && self.build == target { Some(self.initial_lld.clone()) } else { None @@ -1262,13 +1262,13 @@ impl Build { // LLD is used through `-fuse-ld=lld` rather than directly. // Only MSVC targets use LLD directly at the moment. fn is_fuse_ld_lld(&self, target: TargetSelection) -> bool { - self.config.use_lld && !target.contains("msvc") + self.config.llvm.use_lld && !target.contains("msvc") } fn lld_flags(&self, target: TargetSelection) -> impl Iterator { let mut options = [None, None]; - if self.config.use_lld { + if self.config.llvm.use_lld { if self.is_fuse_ld_lld(target) { options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string()); } diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 7e27960f3e906..5f66e55350540 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -18,7 +18,7 @@ use std::process::Command; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::channel; -use crate::config::{Config, TargetSelection}; +use crate::config::{Config, LLVMConfig, TargetSelection}; use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; use crate::{CLang, GitRepo, Kind}; @@ -215,6 +215,23 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { true } +pub(crate) fn get_llvm_opts_from_ci(config: &Config) -> Option { + if config.dry_run() || is_ci_llvm_modified(config) { + return None; + } + + let llvm_sha = detect_llvm_sha(config, config.rust_info.is_managed_git_subrepository()); + config.download_ci_llvm_opts(&llvm_sha); + + let config_path = config.ci_llvm_root_opts().join("llvm-opts.json"); + let Ok(config) = serde_json::from_slice::(&t!(std::fs::read(config_path))) else { + // The LLVM config has changed its format or is corrupted in some way + eprintln!("Cannot deserialize LLVM config from llvm-opts.json"); + return None; + }; + Some(config) +} + /// Returns true if we're running in CI with modified LLVM (and thus can't download it) pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool { CiEnv::is_ci() && config.rust_info.is_managed_git_subrepository() && { @@ -281,7 +298,7 @@ impl Step for Llvm { let mut cfg = cmake::Config::new(builder.src.join(root)); let mut ldflags = LdFlags::default(); - let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { + let profile = match (builder.config.llvm.optimize, builder.config.llvm.release_debuginfo) { (false, _) => "Debug", (true, false) => "Release", (true, true) => "RelWithDebInfo", @@ -289,7 +306,7 @@ impl Step for Llvm { // NOTE: remember to also update `config.example.toml` when changing the // defaults! - let llvm_targets = match &builder.config.llvm_targets { + let llvm_targets = match &builder.config.llvm.targets { Some(s) => s, None => { "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\ @@ -297,15 +314,15 @@ impl Step for Llvm { } }; - let llvm_exp_targets = match builder.config.llvm_experimental_targets { + let llvm_exp_targets = match builder.config.llvm.experimental_targets { Some(ref s) => s, None => "AVR;M68k", }; - let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" }; - let plugins = if builder.config.llvm_plugins { "ON" } else { "OFF" }; - let enable_tests = if builder.config.llvm_tests { "ON" } else { "OFF" }; - let enable_warnings = if builder.config.llvm_enable_warnings { "ON" } else { "OFF" }; + let assertions = if builder.config.llvm.assertions { "ON" } else { "OFF" }; + let plugins = if builder.config.llvm.plugins { "ON" } else { "OFF" }; + let enable_tests = if builder.config.llvm.tests { "ON" } else { "OFF" }; + let enable_warnings = if builder.config.llvm.enable_warnings { "ON" } else { "OFF" }; cfg.out_dir(&out_dir) .profile(profile) @@ -414,11 +431,11 @@ impl Step for Llvm { enabled_llvm_projects.push("compiler-rt"); } - if builder.config.llvm_polly { + if builder.config.llvm.polly { enabled_llvm_projects.push("polly"); } - if builder.config.llvm_clang { + if builder.config.llvm.clang { enabled_llvm_projects.push("clang"); } @@ -432,7 +449,7 @@ impl Step for Llvm { cfg.define("LLVM_ENABLE_PROJECTS", enabled_llvm_projects.join(";")); } - if let Some(num_linkers) = builder.config.llvm_link_jobs { + if let Some(num_linkers) = builder.config.llvm.link_jobs { if num_linkers > 0 { cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string()); } @@ -453,7 +470,7 @@ impl Step for Llvm { cfg.define("LLVM_NM", host_bin.join("llvm-nm").with_extension(EXE_EXTENSION)); } cfg.define("LLVM_CONFIG_PATH", llvm_config); - if builder.config.llvm_clang { + if builder.config.llvm.clang { let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin"); let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION); if !builder.config.dry_run() && !clang_tblgen.exists() { @@ -463,7 +480,7 @@ impl Step for Llvm { } } - let llvm_version_suffix = if let Some(ref suffix) = builder.config.llvm_version_suffix { + let llvm_version_suffix = if let Some(ref suffix) = builder.config.llvm.version_suffix { // Allow version-suffix="" to not define a version suffix at all. if !suffix.is_empty() { Some(suffix.to_string()) } else { None } } else if builder.config.channel == "dev" { @@ -481,7 +498,7 @@ impl Step for Llvm { configure_cmake(builder, target, &mut cfg, true, ldflags, &[]); configure_llvm(builder, target, &mut cfg); - for (key, val) in &builder.config.llvm_build_config { + for (key, val) in &builder.config.llvm.build_config { cfg.define(key, val); } @@ -607,7 +624,7 @@ fn configure_cmake( return; } - let (cc, cxx) = match builder.config.llvm_clang_cl { + let (cc, cxx) = match builder.config.llvm.clang_cl { Some(ref cl) => (cl.into(), cl.into()), None => (builder.cc(target), builder.cxx(target).unwrap()), }; @@ -647,7 +664,7 @@ fn configure_cmake( // unconditionally passed in the sccache shim. This'll get CMake to // correctly diagnose it's doing a 32-bit compilation and LLVM will // internally configure itself appropriately. - if builder.config.llvm_clang_cl.is_some() && target.contains("i686") { + if builder.config.llvm.clang_cl.is_some() && target.contains("i686") { cfg.env("SCCACHE_EXTRA_ARGS", "-m32"); } } else { @@ -666,7 +683,7 @@ fn configure_cmake( cfg.build_arg("-j").build_arg(builder.jobs().to_string()); let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::C).join(" ").into(); - if let Some(ref s) = builder.config.llvm_cflags { + if let Some(ref s) = builder.config.llvm.cflags { cflags.push(" "); cflags.push(s); } @@ -678,7 +695,7 @@ fn configure_cmake( cflags.push(" -miphoneos-version-min=10.0"); } } - if builder.config.llvm_clang_cl.is_some() { + if builder.config.llvm.clang_cl.is_some() { cflags.push(&format!(" --target={}", target)); } for flag in extra_compiler_flags { @@ -686,11 +703,11 @@ fn configure_cmake( } cfg.define("CMAKE_C_FLAGS", cflags); let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::Cxx).join(" ").into(); - if let Some(ref s) = builder.config.llvm_cxxflags { + if let Some(ref s) = builder.config.llvm.cxxflags { cxxflags.push(" "); cxxflags.push(s); } - if builder.config.llvm_clang_cl.is_some() { + if builder.config.llvm.clang_cl.is_some() { cxxflags.push(&format!(" --target={}", target)); } for flag in extra_compiler_flags { @@ -713,7 +730,7 @@ fn configure_cmake( } } - if let Some(ref flags) = builder.config.llvm_ldflags { + if let Some(ref flags) = builder.config.llvm.ldflags { ldflags.push_all(flags); } @@ -723,7 +740,7 @@ fn configure_cmake( // For distribution we want the LLVM tools to be *statically* linked to libstdc++. // We also do this if the user explicitly requested static libstdc++. - if builder.config.llvm_static_stdcpp { + if builder.config.llvm.static_stdcpp { if !target.contains("msvc") && !target.contains("netbsd") && !target.contains("solaris") { if target.contains("apple") || target.contains("windows") { ldflags.push_all("-static-libstdc++"); @@ -745,18 +762,18 @@ fn configure_cmake( fn configure_llvm(builder: &Builder<'_>, target: TargetSelection, cfg: &mut cmake::Config) { // ThinLTO is only available when building with LLVM, enabling LLD is required. // Apple's linker ld64 supports ThinLTO out of the box though, so don't use LLD on Darwin. - if builder.config.llvm_thin_lto { + if builder.config.llvm.thin_lto { cfg.define("LLVM_ENABLE_LTO", "Thin"); if !target.contains("apple") { cfg.define("LLVM_ENABLE_LLD", "ON"); } } - if let Some(ref linker) = builder.config.llvm_use_linker { + if let Some(ref linker) = builder.config.llvm.use_linker { cfg.define("LLVM_USE_LINKER", linker); } - if builder.config.llvm_allow_old_toolchain { + if builder.config.llvm.allow_old_toolchain { cfg.define("LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN", "YES"); } } @@ -829,7 +846,7 @@ impl Step for Lld { // profiler runtime in. In that case, we need to manually ask cmake to do it, to avoid // linking errors, much like LLVM's cmake setup does in that situation. if builder.config.llvm_profile_generate && target.contains("msvc") { - if let Some(clang_cl_path) = builder.config.llvm_clang_cl.as_ref() { + if let Some(clang_cl_path) = builder.config.llvm.clang_cl.as_ref() { // Find clang's runtime library directory and push that as a search path to the // cmake linker flags. let clang_rt_dir = get_clang_cl_resource_dir(clang_cl_path); @@ -867,7 +884,7 @@ impl Step for Lld { // Re-use the same flags as llvm to control the level of debug information // generated for lld. - let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) { + let profile = match (builder.config.llvm.optimize, builder.config.llvm.release_debuginfo) { (false, _) => "Debug", (true, false) => "Release", (true, true) => "RelWithDebInfo", diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 44b8c2d8c013b..4a4282de7a398 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1738,7 +1738,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { // If LLD is available, add it to the PATH - if builder.config.lld_enabled { + if builder.config.llvm.lld_enabled { let lld_install_root = builder.ensure(llvm::Lld { target: builder.config.build });