bootstrap/core/config/toml/
llvm.rs1use serde::{Deserialize, Deserializer};
5
6use crate::core::config::toml::{Merge, ReplaceOpt, TomlConfig};
7use crate::core::config::{StringOrBool, set};
8use crate::{Config, HashMap, HashSet, PathBuf, define_config, exit};
9
10define_config! {
11 struct Llvm {
13 optimize: Option<bool> = "optimize",
14 thin_lto: Option<bool> = "thin-lto",
15 release_debuginfo: Option<bool> = "release-debuginfo",
16 assertions: Option<bool> = "assertions",
17 tests: Option<bool> = "tests",
18 enzyme: Option<bool> = "enzyme",
19 plugins: Option<bool> = "plugins",
20 static_libstdcpp: Option<bool> = "static-libstdcpp",
21 libzstd: Option<bool> = "libzstd",
22 ninja: Option<bool> = "ninja",
23 targets: Option<String> = "targets",
24 experimental_targets: Option<String> = "experimental-targets",
25 link_jobs: Option<u32> = "link-jobs",
26 link_shared: Option<bool> = "link-shared",
27 version_suffix: Option<String> = "version-suffix",
28 clang_cl: Option<String> = "clang-cl",
29 cflags: Option<String> = "cflags",
30 cxxflags: Option<String> = "cxxflags",
31 ldflags: Option<String> = "ldflags",
32 use_libcxx: Option<bool> = "use-libcxx",
33 use_linker: Option<String> = "use-linker",
34 allow_old_toolchain: Option<bool> = "allow-old-toolchain",
35 offload: Option<bool> = "offload",
36 polly: Option<bool> = "polly",
37 clang: Option<bool> = "clang",
38 enable_warnings: Option<bool> = "enable-warnings",
39 download_ci_llvm: Option<StringOrBool> = "download-ci-llvm",
40 build_config: Option<HashMap<String, String>> = "build-config",
41 }
42}
43
44#[cfg(not(test))]
47pub fn check_incompatible_options_for_ci_llvm(
48 current_config_toml: TomlConfig,
49 ci_config_toml: TomlConfig,
50) -> Result<(), String> {
51 macro_rules! err {
52 ($current:expr, $expected:expr) => {
53 if let Some(current) = &$current {
54 if Some(current) != $expected.as_ref() {
55 return Err(format!(
56 "ERROR: Setting `llvm.{}` is incompatible with `llvm.download-ci-llvm`. \
57 Current value: {:?}, Expected value(s): {}{:?}",
58 stringify!($expected).replace("_", "-"),
59 $current,
60 if $expected.is_some() { "None/" } else { "" },
61 $expected,
62 ));
63 };
64 };
65 };
66 }
67
68 macro_rules! warn {
69 ($current:expr, $expected:expr) => {
70 if let Some(current) = &$current {
71 if Some(current) != $expected.as_ref() {
72 println!(
73 "WARNING: `llvm.{}` has no effect with `llvm.download-ci-llvm`. \
74 Current value: {:?}, Expected value(s): {}{:?}",
75 stringify!($expected).replace("_", "-"),
76 $current,
77 if $expected.is_some() { "None/" } else { "" },
78 $expected,
79 );
80 };
81 };
82 };
83 }
84
85 let (Some(current_llvm_config), Some(ci_llvm_config)) =
86 (current_config_toml.llvm, ci_config_toml.llvm)
87 else {
88 return Ok(());
89 };
90
91 let Llvm {
92 optimize,
93 thin_lto,
94 release_debuginfo,
95 assertions: _,
96 tests: _,
97 plugins,
98 static_libstdcpp: _,
99 libzstd,
100 ninja: _,
101 targets,
102 experimental_targets,
103 link_jobs: _,
104 link_shared: _,
105 version_suffix,
106 clang_cl,
107 cflags,
108 cxxflags,
109 ldflags,
110 use_libcxx,
111 use_linker,
112 allow_old_toolchain,
113 offload,
114 polly,
115 clang,
116 enable_warnings,
117 download_ci_llvm: _,
118 build_config,
119 enzyme,
120 } = ci_llvm_config;
121
122 err!(current_llvm_config.optimize, optimize);
123 err!(current_llvm_config.thin_lto, thin_lto);
124 err!(current_llvm_config.release_debuginfo, release_debuginfo);
125 err!(current_llvm_config.libzstd, libzstd);
126 err!(current_llvm_config.targets, targets);
127 err!(current_llvm_config.experimental_targets, experimental_targets);
128 err!(current_llvm_config.clang_cl, clang_cl);
129 err!(current_llvm_config.version_suffix, version_suffix);
130 err!(current_llvm_config.cflags, cflags);
131 err!(current_llvm_config.cxxflags, cxxflags);
132 err!(current_llvm_config.ldflags, ldflags);
133 err!(current_llvm_config.use_libcxx, use_libcxx);
134 err!(current_llvm_config.use_linker, use_linker);
135 err!(current_llvm_config.allow_old_toolchain, allow_old_toolchain);
136 err!(current_llvm_config.offload, offload);
137 err!(current_llvm_config.polly, polly);
138 err!(current_llvm_config.clang, clang);
139 err!(current_llvm_config.build_config, build_config);
140 err!(current_llvm_config.plugins, plugins);
141 err!(current_llvm_config.enzyme, enzyme);
142
143 warn!(current_llvm_config.enable_warnings, enable_warnings);
144
145 Ok(())
146}
147
148impl Config {
149 pub fn apply_llvm_config(&mut self, toml_llvm: Option<Llvm>) {
150 let mut llvm_tests = None;
151 let mut llvm_enzyme = None;
152 let mut llvm_offload = None;
153 let mut llvm_plugins = None;
154
155 if let Some(llvm) = toml_llvm {
156 let Llvm {
157 optimize: optimize_toml,
158 thin_lto,
159 release_debuginfo,
160 assertions: _,
161 tests,
162 enzyme,
163 plugins,
164 static_libstdcpp,
165 libzstd,
166 ninja,
167 targets,
168 experimental_targets,
169 link_jobs,
170 link_shared,
171 version_suffix,
172 clang_cl,
173 cflags,
174 cxxflags,
175 ldflags,
176 use_libcxx,
177 use_linker,
178 allow_old_toolchain,
179 offload,
180 polly,
181 clang,
182 enable_warnings,
183 download_ci_llvm,
184 build_config,
185 } = llvm;
186
187 set(&mut self.ninja_in_file, ninja);
188 llvm_tests = tests;
189 llvm_enzyme = enzyme;
190 llvm_offload = offload;
191 llvm_plugins = plugins;
192 set(&mut self.llvm_optimize, optimize_toml);
193 set(&mut self.llvm_thin_lto, thin_lto);
194 set(&mut self.llvm_release_debuginfo, release_debuginfo);
195 set(&mut self.llvm_static_stdcpp, static_libstdcpp);
196 set(&mut self.llvm_libzstd, libzstd);
197 if let Some(v) = link_shared {
198 self.llvm_link_shared.set(Some(v));
199 }
200 self.llvm_targets.clone_from(&targets);
201 self.llvm_experimental_targets.clone_from(&experimental_targets);
202 self.llvm_link_jobs = link_jobs;
203 self.llvm_version_suffix.clone_from(&version_suffix);
204 self.llvm_clang_cl.clone_from(&clang_cl);
205
206 self.llvm_cflags.clone_from(&cflags);
207 self.llvm_cxxflags.clone_from(&cxxflags);
208 self.llvm_ldflags.clone_from(&ldflags);
209 set(&mut self.llvm_use_libcxx, use_libcxx);
210 self.llvm_use_linker.clone_from(&use_linker);
211 self.llvm_allow_old_toolchain = allow_old_toolchain.unwrap_or(false);
212 self.llvm_offload = offload.unwrap_or(false);
213 self.llvm_polly = polly.unwrap_or(false);
214 self.llvm_clang = clang.unwrap_or(false);
215 self.llvm_enable_warnings = enable_warnings.unwrap_or(false);
216 self.llvm_build_config = build_config.clone().unwrap_or(Default::default());
217
218 self.llvm_from_ci = self.parse_download_ci_llvm(download_ci_llvm, self.llvm_assertions);
219
220 if self.llvm_from_ci {
221 let warn = |option: &str| {
222 println!(
223 "WARNING: `{option}` will only be used on `compiler/rustc_llvm` build, not for the LLVM build."
224 );
225 println!(
226 "HELP: To use `{option}` for LLVM builds, set `download-ci-llvm` option to false."
227 );
228 };
229
230 if static_libstdcpp.is_some() {
231 warn("static-libstdcpp");
232 }
233
234 if link_shared.is_some() {
235 warn("link-shared");
236 }
237
238 if libzstd.is_some() {
244 println!(
245 "WARNING: when using `download-ci-llvm`, the local `llvm.libzstd` option, \
246 like almost all `llvm.*` options, will be ignored and set by the LLVM CI \
247 artifacts builder config."
248 );
249 println!(
250 "HELP: To use `llvm.libzstd` for LLVM/LLD builds, set `download-ci-llvm` option to false."
251 );
252 }
253 }
254
255 if !self.llvm_from_ci && self.llvm_thin_lto && link_shared.is_none() {
256 self.llvm_link_shared.set(Some(true));
260 }
261 } else {
262 self.llvm_from_ci = self.parse_download_ci_llvm(None, false);
263 }
264
265 self.llvm_tests = llvm_tests.unwrap_or(false);
266 self.llvm_enzyme = llvm_enzyme.unwrap_or(false);
267 self.llvm_offload = llvm_offload.unwrap_or(false);
268 self.llvm_plugins = llvm_plugins.unwrap_or(false);
269 }
270}