]>
Commit | Line | Data |
---|---|---|
a7813a04 XL |
1 | //! Serialized configuration of a build. |
2 | //! | |
ea8adc8c XL |
3 | //! This module implements parsing `config.toml` configuration files to tweak |
4 | //! how the build runs. | |
a7813a04 | 5 | |
dfeec247 | 6 | use std::cmp; |
2c00a5a8 | 7 | use std::collections::{HashMap, HashSet}; |
7453a54e | 8 | use std::env; |
dfeec247 | 9 | use std::ffi::OsString; |
0731742a | 10 | use std::fs; |
2c00a5a8 | 11 | use std::path::{Path, PathBuf}; |
7453a54e SL |
12 | use std::process; |
13 | ||
dfeec247 | 14 | use crate::cache::{Interned, INTERNER}; |
0731742a XL |
15 | use crate::flags::Flags; |
16 | pub use crate::flags::Subcommand; | |
dfeec247 XL |
17 | use build_helper::t; |
18 | use serde::Deserialize; | |
7453a54e SL |
19 | |
20 | /// Global configuration for the entire build and/or bootstrap. | |
21 | /// | |
22 | /// This structure is derived from a combination of both `config.toml` and | |
23 | /// `config.mk`. As of the time of this writing it's unlikely that `config.toml` | |
24 | /// is used all that much, so this is primarily filled out by `config.mk` which | |
25 | /// is generated from `./configure`. | |
26 | /// | |
27 | /// Note that this structure is not decoded directly into, but rather it is | |
a7813a04 XL |
28 | /// filled out from the decoded forms of the structs below. For documentation |
29 | /// each field, see the corresponding fields in | |
3b2f2976 | 30 | /// `config.toml.example`. |
7453a54e SL |
31 | #[derive(Default)] |
32 | pub struct Config { | |
476ff2be | 33 | pub ccache: Option<String>, |
a7813a04 | 34 | pub ninja: bool, |
32a655c1 | 35 | pub verbose: usize, |
7453a54e | 36 | pub submodules: bool, |
0531ce1d | 37 | pub fast_submodules: bool, |
7453a54e SL |
38 | pub compiler_docs: bool, |
39 | pub docs: bool, | |
8bb4bdeb | 40 | pub locked_deps: bool, |
476ff2be | 41 | pub vendor: bool, |
3b2f2976 | 42 | pub target_config: HashMap<Interned<String>, Target>, |
32a655c1 SL |
43 | pub full_bootstrap: bool, |
44 | pub extended: bool, | |
2c00a5a8 | 45 | pub tools: Option<HashSet<String>>, |
8bb4bdeb | 46 | pub sanitizers: bool, |
041b39d2 | 47 | pub profiler: bool, |
3b2f2976 | 48 | pub ignore_git: bool, |
2c00a5a8 | 49 | pub exclude: Vec<PathBuf>, |
0531ce1d | 50 | pub rustc_error_format: Option<String>, |
ba9703b0 | 51 | pub json_output: bool, |
a1dfa0c6 | 52 | pub test_compare_mode: bool, |
532ac7d7 | 53 | pub llvm_libunwind: bool, |
3b2f2976 | 54 | |
dc9dc135 | 55 | pub skip_only_host_steps: bool, |
3b2f2976 XL |
56 | |
57 | pub on_fail: Option<String>, | |
58 | pub stage: Option<u32>, | |
8faf50e0 | 59 | pub keep_stage: Vec<u32>, |
3b2f2976 XL |
60 | pub src: PathBuf, |
61 | pub jobs: Option<u32>, | |
62 | pub cmd: Subcommand, | |
63 | pub incremental: bool, | |
83c7162d XL |
64 | pub dry_run: bool, |
65 | ||
66 | pub deny_warnings: bool, | |
67 | pub backtrace_on_ice: bool, | |
7453a54e SL |
68 | |
69 | // llvm codegen options | |
dfeec247 | 70 | pub llvm_skip_rebuild: bool, |
7453a54e SL |
71 | pub llvm_assertions: bool, |
72 | pub llvm_optimize: bool, | |
b7449926 | 73 | pub llvm_thin_lto: bool, |
476ff2be | 74 | pub llvm_release_debuginfo: bool, |
7453a54e SL |
75 | pub llvm_version_check: bool, |
76 | pub llvm_static_stdcpp: bool, | |
476ff2be | 77 | pub llvm_link_shared: bool, |
94b46f34 | 78 | pub llvm_clang_cl: Option<String>, |
32a655c1 | 79 | pub llvm_targets: Option<String>, |
416331ca | 80 | pub llvm_experimental_targets: Option<String>, |
8bb4bdeb | 81 | pub llvm_link_jobs: Option<u32>, |
b7449926 | 82 | pub llvm_version_suffix: Option<String>, |
9fa01778 | 83 | pub llvm_use_linker: Option<String>, |
532ac7d7 | 84 | pub llvm_allow_old_toolchain: Option<bool>, |
7453a54e | 85 | |
74b04a01 | 86 | pub use_lld: bool, |
0531ce1d | 87 | pub lld_enabled: bool, |
b7449926 | 88 | pub lldb_enabled: bool, |
8faf50e0 | 89 | pub llvm_tools_enabled: bool, |
0531ce1d | 90 | |
9fa01778 XL |
91 | pub llvm_cflags: Option<String>, |
92 | pub llvm_cxxflags: Option<String>, | |
93 | pub llvm_ldflags: Option<String>, | |
0731742a XL |
94 | pub llvm_use_libcxx: bool, |
95 | ||
7453a54e SL |
96 | // rust codegen options |
97 | pub rust_optimize: bool, | |
abe05a73 | 98 | pub rust_codegen_units: Option<u32>, |
a1dfa0c6 | 99 | pub rust_codegen_units_std: Option<u32>, |
7453a54e | 100 | pub rust_debug_assertions: bool, |
dc9dc135 XL |
101 | pub rust_debuginfo_level_rustc: u32, |
102 | pub rust_debuginfo_level_std: u32, | |
103 | pub rust_debuginfo_level_tools: u32, | |
104 | pub rust_debuginfo_level_tests: u32, | |
7453a54e | 105 | pub rust_rpath: bool, |
9fa01778 | 106 | pub rustc_parallel: bool, |
7453a54e | 107 | pub rustc_default_linker: Option<String>, |
a7813a04 | 108 | pub rust_optimize_tests: bool, |
8bb4bdeb | 109 | pub rust_dist_src: bool, |
2c00a5a8 | 110 | pub rust_codegen_backends: Vec<Interned<String>>, |
8faf50e0 | 111 | pub rust_verify_llvm_ir: bool, |
dfeec247 | 112 | pub rust_thin_lto_import_instr_limit: Option<u32>, |
b7449926 | 113 | pub rust_remap_debuginfo: bool, |
7453a54e | 114 | |
3b2f2976 XL |
115 | pub build: Interned<String>, |
116 | pub hosts: Vec<Interned<String>>, | |
117 | pub targets: Vec<Interned<String>>, | |
3157f602 | 118 | pub local_rebuild: bool, |
a1dfa0c6 | 119 | pub jemalloc: bool, |
74b04a01 | 120 | pub control_flow_guard: bool, |
7453a54e | 121 | |
32a655c1 SL |
122 | // dist misc |
123 | pub dist_sign_folder: Option<PathBuf>, | |
124 | pub dist_upload_addr: Option<String>, | |
125 | pub dist_gpg_password_file: Option<PathBuf>, | |
126 | ||
7453a54e | 127 | // libstd features |
5bcae85e | 128 | pub backtrace: bool, // support for RUST_BACKTRACE |
7453a54e SL |
129 | |
130 | // misc | |
7cac9316 | 131 | pub low_priority: bool, |
7453a54e | 132 | pub channel: String, |
94b46f34 | 133 | pub verbose_tests: bool, |
ff7c6d11 | 134 | pub save_toolstates: Option<PathBuf>, |
0531ce1d | 135 | pub print_step_timings: bool, |
0bf4aa26 | 136 | pub missing_tools: bool, |
ff7c6d11 | 137 | |
9e0c209e | 138 | // Fallback musl-root for all targets |
7453a54e | 139 | pub musl_root: Option<PathBuf>, |
32a655c1 | 140 | pub prefix: Option<PathBuf>, |
7cac9316 | 141 | pub sysconfdir: Option<PathBuf>, |
2c00a5a8 | 142 | pub datadir: Option<PathBuf>, |
32a655c1 | 143 | pub docdir: Option<PathBuf>, |
e1599b0c | 144 | pub bindir: PathBuf, |
32a655c1 | 145 | pub libdir: Option<PathBuf>, |
32a655c1 | 146 | pub mandir: Option<PathBuf>, |
9e0c209e SL |
147 | pub codegen_tests: bool, |
148 | pub nodejs: Option<PathBuf>, | |
c30ab7b3 | 149 | pub gdb: Option<PathBuf>, |
476ff2be | 150 | pub python: Option<PathBuf>, |
0bf4aa26 | 151 | pub cargo_native_static: bool, |
ea8adc8c | 152 | pub configure_args: Vec<String>, |
041b39d2 XL |
153 | |
154 | // These are either the stage0 downloaded binaries or the locally installed ones. | |
155 | pub initial_cargo: PathBuf, | |
156 | pub initial_rustc: PathBuf, | |
dfeec247 | 157 | pub initial_rustfmt: Option<PathBuf>, |
83c7162d | 158 | pub out: PathBuf, |
7453a54e SL |
159 | } |
160 | ||
161 | /// Per-target configuration stored in the global configuration structure. | |
162 | #[derive(Default)] | |
163 | pub struct Target { | |
041b39d2 | 164 | /// Some(path to llvm-config) if using an external LLVM. |
7453a54e | 165 | pub llvm_config: Option<PathBuf>, |
0bf4aa26 XL |
166 | /// Some(path to FileCheck) if one was specified. |
167 | pub llvm_filecheck: Option<PathBuf>, | |
7453a54e SL |
168 | pub cc: Option<PathBuf>, |
169 | pub cxx: Option<PathBuf>, | |
abe05a73 | 170 | pub ar: Option<PathBuf>, |
b7449926 | 171 | pub ranlib: Option<PathBuf>, |
abe05a73 | 172 | pub linker: Option<PathBuf>, |
7453a54e | 173 | pub ndk: Option<PathBuf>, |
3b2f2976 | 174 | pub crt_static: Option<bool>, |
9e0c209e | 175 | pub musl_root: Option<PathBuf>, |
532ac7d7 | 176 | pub wasi_root: Option<PathBuf>, |
8bb4bdeb | 177 | pub qemu_rootfs: Option<PathBuf>, |
83c7162d | 178 | pub no_std: bool, |
7453a54e SL |
179 | } |
180 | ||
74b04a01 XL |
181 | impl Target { |
182 | pub fn from_triple(triple: &str) -> Self { | |
183 | let mut target: Self = Default::default(); | |
184 | if triple.contains("-none") || triple.contains("nvptx") { | |
185 | target.no_std = true; | |
186 | } | |
187 | target | |
188 | } | |
189 | } | |
7453a54e SL |
190 | /// Structure of the `config.toml` file that configuration is read from. |
191 | /// | |
192 | /// This structure uses `Decodable` to automatically decode a TOML configuration | |
193 | /// file into this format, and then this is traversed and written into the above | |
194 | /// `Config` structure. | |
3b2f2976 XL |
195 | #[derive(Deserialize, Default)] |
196 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
7453a54e SL |
197 | struct TomlConfig { |
198 | build: Option<Build>, | |
32a655c1 | 199 | install: Option<Install>, |
7453a54e SL |
200 | llvm: Option<Llvm>, |
201 | rust: Option<Rust>, | |
202 | target: Option<HashMap<String, TomlTarget>>, | |
32a655c1 | 203 | dist: Option<Dist>, |
7453a54e SL |
204 | } |
205 | ||
206 | /// TOML representation of various global build decisions. | |
3b2f2976 XL |
207 | #[derive(Deserialize, Default, Clone)] |
208 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
7453a54e SL |
209 | struct Build { |
210 | build: Option<String>, | |
3b2f2976 | 211 | #[serde(default)] |
7453a54e | 212 | host: Vec<String>, |
3b2f2976 | 213 | #[serde(default)] |
7453a54e SL |
214 | target: Vec<String>, |
215 | cargo: Option<String>, | |
216 | rustc: Option<String>, | |
dfeec247 | 217 | rustfmt: Option<String>, /* allow bootstrap.py to use rustfmt key */ |
7453a54e | 218 | docs: Option<bool>, |
e74abb32 | 219 | compiler_docs: Option<bool>, |
c30ab7b3 | 220 | submodules: Option<bool>, |
0531ce1d | 221 | fast_submodules: Option<bool>, |
c30ab7b3 | 222 | gdb: Option<String>, |
476ff2be SL |
223 | nodejs: Option<String>, |
224 | python: Option<String>, | |
e74abb32 XL |
225 | locked_deps: Option<bool>, |
226 | vendor: Option<bool>, | |
32a655c1 SL |
227 | full_bootstrap: Option<bool>, |
228 | extended: Option<bool>, | |
2c00a5a8 | 229 | tools: Option<HashSet<String>>, |
8bb4bdeb XL |
230 | verbose: Option<usize>, |
231 | sanitizers: Option<bool>, | |
041b39d2 | 232 | profiler: Option<bool>, |
0bf4aa26 | 233 | cargo_native_static: Option<bool>, |
e74abb32 | 234 | low_priority: Option<bool>, |
ea8adc8c XL |
235 | configure_args: Option<Vec<String>>, |
236 | local_rebuild: Option<bool>, | |
0531ce1d | 237 | print_step_timings: Option<bool>, |
32a655c1 SL |
238 | } |
239 | ||
240 | /// TOML representation of various global install decisions. | |
3b2f2976 XL |
241 | #[derive(Deserialize, Default, Clone)] |
242 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
32a655c1 SL |
243 | struct Install { |
244 | prefix: Option<String>, | |
7cac9316 | 245 | sysconfdir: Option<String>, |
32a655c1 | 246 | docdir: Option<String>, |
7cac9316 | 247 | bindir: Option<String>, |
32a655c1 | 248 | libdir: Option<String>, |
7cac9316 | 249 | mandir: Option<String>, |
e74abb32 | 250 | datadir: Option<String>, |
abe05a73 XL |
251 | |
252 | // standard paths, currently unused | |
abe05a73 XL |
253 | infodir: Option<String>, |
254 | localstatedir: Option<String>, | |
7453a54e SL |
255 | } |
256 | ||
257 | /// TOML representation of how the LLVM build is configured. | |
3b2f2976 XL |
258 | #[derive(Deserialize, Default)] |
259 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
7453a54e | 260 | struct Llvm { |
dfeec247 | 261 | skip_rebuild: Option<bool>, |
7453a54e | 262 | optimize: Option<bool>, |
b7449926 | 263 | thin_lto: Option<bool>, |
476ff2be | 264 | release_debuginfo: Option<bool>, |
e74abb32 XL |
265 | assertions: Option<bool>, |
266 | ccache: Option<StringOrBool>, | |
7453a54e SL |
267 | version_check: Option<bool>, |
268 | static_libstdcpp: Option<bool>, | |
e74abb32 | 269 | ninja: Option<bool>, |
32a655c1 | 270 | targets: Option<String>, |
041b39d2 | 271 | experimental_targets: Option<String>, |
8bb4bdeb | 272 | link_jobs: Option<u32>, |
ea8adc8c | 273 | link_shared: Option<bool>, |
b7449926 | 274 | version_suffix: Option<String>, |
a1dfa0c6 | 275 | clang_cl: Option<String>, |
9fa01778 XL |
276 | cflags: Option<String>, |
277 | cxxflags: Option<String>, | |
278 | ldflags: Option<String>, | |
0731742a | 279 | use_libcxx: Option<bool>, |
9fa01778 | 280 | use_linker: Option<String>, |
532ac7d7 | 281 | allow_old_toolchain: Option<bool>, |
32a655c1 SL |
282 | } |
283 | ||
3b2f2976 XL |
284 | #[derive(Deserialize, Default, Clone)] |
285 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
32a655c1 SL |
286 | struct Dist { |
287 | sign_folder: Option<String>, | |
288 | gpg_password_file: Option<String>, | |
289 | upload_addr: Option<String>, | |
8bb4bdeb | 290 | src_tarball: Option<bool>, |
0bf4aa26 | 291 | missing_tools: Option<bool>, |
7453a54e SL |
292 | } |
293 | ||
3b2f2976 XL |
294 | #[derive(Deserialize)] |
295 | #[serde(untagged)] | |
476ff2be SL |
296 | enum StringOrBool { |
297 | String(String), | |
298 | Bool(bool), | |
299 | } | |
300 | ||
301 | impl Default for StringOrBool { | |
302 | fn default() -> StringOrBool { | |
303 | StringOrBool::Bool(false) | |
304 | } | |
305 | } | |
306 | ||
7453a54e | 307 | /// TOML representation of how the Rust build is configured. |
3b2f2976 XL |
308 | #[derive(Deserialize, Default)] |
309 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
7453a54e SL |
310 | struct Rust { |
311 | optimize: Option<bool>, | |
e74abb32 | 312 | debug: Option<bool>, |
7453a54e | 313 | codegen_units: Option<u32>, |
a1dfa0c6 | 314 | codegen_units_std: Option<u32>, |
7453a54e | 315 | debug_assertions: Option<bool>, |
dc9dc135 XL |
316 | debuginfo_level: Option<u32>, |
317 | debuginfo_level_rustc: Option<u32>, | |
318 | debuginfo_level_std: Option<u32>, | |
319 | debuginfo_level_tools: Option<u32>, | |
320 | debuginfo_level_tests: Option<u32>, | |
5bcae85e | 321 | backtrace: Option<bool>, |
e74abb32 XL |
322 | incremental: Option<bool>, |
323 | parallel_compiler: Option<bool>, | |
7453a54e | 324 | default_linker: Option<String>, |
7453a54e SL |
325 | channel: Option<String>, |
326 | musl_root: Option<String>, | |
327 | rpath: Option<bool>, | |
e74abb32 | 328 | verbose_tests: Option<bool>, |
a7813a04 | 329 | optimize_tests: Option<bool>, |
9e0c209e | 330 | codegen_tests: Option<bool>, |
3b2f2976 | 331 | ignore_git: Option<bool>, |
ea8adc8c | 332 | dist_src: Option<bool>, |
ff7c6d11 | 333 | save_toolstates: Option<String>, |
2c00a5a8 | 334 | codegen_backends: Option<Vec<String>>, |
0531ce1d | 335 | lld: Option<bool>, |
74b04a01 | 336 | use_lld: Option<bool>, |
8faf50e0 | 337 | llvm_tools: Option<bool>, |
e74abb32 | 338 | lldb: Option<bool>, |
83c7162d XL |
339 | deny_warnings: Option<bool>, |
340 | backtrace_on_ice: Option<bool>, | |
8faf50e0 | 341 | verify_llvm_ir: Option<bool>, |
dfeec247 | 342 | thin_lto_import_instr_limit: Option<u32>, |
b7449926 | 343 | remap_debuginfo: Option<bool>, |
a1dfa0c6 XL |
344 | jemalloc: Option<bool>, |
345 | test_compare_mode: Option<bool>, | |
532ac7d7 | 346 | llvm_libunwind: Option<bool>, |
74b04a01 | 347 | control_flow_guard: Option<bool>, |
7453a54e SL |
348 | } |
349 | ||
350 | /// TOML representation of how each build target is configured. | |
3b2f2976 XL |
351 | #[derive(Deserialize, Default)] |
352 | #[serde(deny_unknown_fields, rename_all = "kebab-case")] | |
7453a54e | 353 | struct TomlTarget { |
7453a54e SL |
354 | cc: Option<String>, |
355 | cxx: Option<String>, | |
abe05a73 | 356 | ar: Option<String>, |
b7449926 | 357 | ranlib: Option<String>, |
abe05a73 | 358 | linker: Option<String>, |
e74abb32 XL |
359 | llvm_config: Option<String>, |
360 | llvm_filecheck: Option<String>, | |
7453a54e | 361 | android_ndk: Option<String>, |
3b2f2976 | 362 | crt_static: Option<bool>, |
c30ab7b3 | 363 | musl_root: Option<String>, |
532ac7d7 | 364 | wasi_root: Option<String>, |
8bb4bdeb | 365 | qemu_rootfs: Option<String>, |
74b04a01 | 366 | no_std: Option<bool>, |
7453a54e SL |
367 | } |
368 | ||
369 | impl Config { | |
83c7162d XL |
370 | fn path_from_python(var_key: &str) -> PathBuf { |
371 | match env::var_os(var_key) { | |
dfeec247 | 372 | Some(var_val) => Self::normalize_python_path(var_val), |
83c7162d XL |
373 | _ => panic!("expected '{}' to be set", var_key), |
374 | } | |
375 | } | |
376 | ||
dfeec247 XL |
377 | /// Normalizes paths from Python slightly. We don't trust paths from Python (#49785). |
378 | fn normalize_python_path(path: OsString) -> PathBuf { | |
379 | Path::new(&path).components().collect() | |
380 | } | |
381 | ||
83c7162d | 382 | pub fn default_opts() -> Config { |
7453a54e SL |
383 | let mut config = Config::default(); |
384 | config.llvm_optimize = true; | |
abe05a73 | 385 | config.llvm_version_check = true; |
5bcae85e | 386 | config.backtrace = true; |
7453a54e | 387 | config.rust_optimize = true; |
a7813a04 | 388 | config.rust_optimize_tests = true; |
7453a54e | 389 | config.submodules = true; |
0531ce1d | 390 | config.fast_submodules = true; |
7453a54e SL |
391 | config.docs = true; |
392 | config.rust_rpath = true; | |
7453a54e | 393 | config.channel = "dev".to_string(); |
9e0c209e | 394 | config.codegen_tests = true; |
3b2f2976 | 395 | config.ignore_git = false; |
8bb4bdeb | 396 | config.rust_dist_src = true; |
2c00a5a8 | 397 | config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")]; |
83c7162d | 398 | config.deny_warnings = true; |
0bf4aa26 | 399 | config.missing_tools = false; |
83c7162d XL |
400 | |
401 | // set by bootstrap.py | |
402 | config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set")); | |
403 | config.src = Config::path_from_python("SRC"); | |
404 | config.out = Config::path_from_python("BUILD_DIR"); | |
405 | ||
8faf50e0 XL |
406 | config.initial_rustc = Config::path_from_python("RUSTC"); |
407 | config.initial_cargo = Config::path_from_python("CARGO"); | |
dfeec247 | 408 | config.initial_rustfmt = env::var_os("RUSTFMT").map(Config::normalize_python_path); |
7453a54e | 409 | |
83c7162d XL |
410 | config |
411 | } | |
412 | ||
413 | pub fn parse(args: &[String]) -> Config { | |
414 | let flags = Flags::parse(&args); | |
415 | let file = flags.config.clone(); | |
416 | let mut config = Config::default_opts(); | |
417 | config.exclude = flags.exclude; | |
0531ce1d | 418 | config.rustc_error_format = flags.rustc_error_format; |
ba9703b0 | 419 | config.json_output = flags.json_output; |
3b2f2976 XL |
420 | config.on_fail = flags.on_fail; |
421 | config.stage = flags.stage; | |
dc9dc135 | 422 | config.jobs = flags.jobs.map(threads_from_config); |
3b2f2976 XL |
423 | config.cmd = flags.cmd; |
424 | config.incremental = flags.incremental; | |
83c7162d | 425 | config.dry_run = flags.dry_run; |
3b2f2976 | 426 | config.keep_stage = flags.keep_stage; |
e1599b0c | 427 | config.bindir = "bin".into(); // default |
416331ca | 428 | if let Some(value) = flags.deny_warnings { |
83c7162d XL |
429 | config.deny_warnings = value; |
430 | } | |
431 | ||
432 | if config.dry_run { | |
433 | let dir = config.out.join("tmp-dry-run"); | |
434 | t!(fs::create_dir_all(&dir)); | |
435 | config.out = dir; | |
436 | } | |
3b2f2976 XL |
437 | |
438 | // If --target was specified but --host wasn't specified, don't run any host-only tests. | |
dc9dc135 XL |
439 | let has_hosts = !flags.host.is_empty(); |
440 | let has_targets = !flags.target.is_empty(); | |
441 | config.skip_only_host_steps = !has_hosts && has_targets; | |
3b2f2976 | 442 | |
dfeec247 XL |
443 | let toml = file |
444 | .map(|file| { | |
445 | let contents = t!(fs::read_to_string(&file)); | |
446 | match toml::from_str(&contents) { | |
447 | Ok(table) => table, | |
448 | Err(err) => { | |
449 | println!( | |
450 | "failed to parse TOML configuration '{}': {}", | |
451 | file.display(), | |
452 | err | |
453 | ); | |
454 | process::exit(2); | |
455 | } | |
7453a54e | 456 | } |
dfeec247 | 457 | }) |
74b04a01 | 458 | .unwrap_or_else(TomlConfig::default); |
7453a54e | 459 | |
0bf4aa26 | 460 | let build = toml.build.clone().unwrap_or_default(); |
83c7162d | 461 | // set by bootstrap.py |
3b2f2976 | 462 | config.hosts.push(config.build.clone()); |
7453a54e | 463 | for host in build.host.iter() { |
3b2f2976 XL |
464 | let host = INTERNER.intern_str(host); |
465 | if !config.hosts.contains(&host) { | |
466 | config.hosts.push(host); | |
7453a54e SL |
467 | } |
468 | } | |
dfeec247 XL |
469 | for target in |
470 | config.hosts.iter().cloned().chain(build.target.iter().map(|s| INTERNER.intern_str(s))) | |
3b2f2976 XL |
471 | { |
472 | if !config.targets.contains(&target) { | |
473 | config.targets.push(target); | |
7453a54e SL |
474 | } |
475 | } | |
dfeec247 XL |
476 | config.hosts = if !flags.host.is_empty() { flags.host } else { config.hosts }; |
477 | config.targets = if !flags.target.is_empty() { flags.target } else { config.targets }; | |
3b2f2976 | 478 | |
476ff2be | 479 | config.nodejs = build.nodejs.map(PathBuf::from); |
c30ab7b3 | 480 | config.gdb = build.gdb.map(PathBuf::from); |
476ff2be | 481 | config.python = build.python.map(PathBuf::from); |
7cac9316 | 482 | set(&mut config.low_priority, build.low_priority); |
7453a54e SL |
483 | set(&mut config.compiler_docs, build.compiler_docs); |
484 | set(&mut config.docs, build.docs); | |
c30ab7b3 | 485 | set(&mut config.submodules, build.submodules); |
0531ce1d | 486 | set(&mut config.fast_submodules, build.fast_submodules); |
8bb4bdeb | 487 | set(&mut config.locked_deps, build.locked_deps); |
476ff2be | 488 | set(&mut config.vendor, build.vendor); |
32a655c1 SL |
489 | set(&mut config.full_bootstrap, build.full_bootstrap); |
490 | set(&mut config.extended, build.extended); | |
2c00a5a8 | 491 | config.tools = build.tools; |
8bb4bdeb XL |
492 | set(&mut config.verbose, build.verbose); |
493 | set(&mut config.sanitizers, build.sanitizers); | |
041b39d2 | 494 | set(&mut config.profiler, build.profiler); |
0bf4aa26 | 495 | set(&mut config.cargo_native_static, build.cargo_native_static); |
ea8adc8c XL |
496 | set(&mut config.configure_args, build.configure_args); |
497 | set(&mut config.local_rebuild, build.local_rebuild); | |
0531ce1d | 498 | set(&mut config.print_step_timings, build.print_step_timings); |
3b2f2976 | 499 | config.verbose = cmp::max(config.verbose, flags.verbose); |
32a655c1 SL |
500 | |
501 | if let Some(ref install) = toml.install { | |
502 | config.prefix = install.prefix.clone().map(PathBuf::from); | |
7cac9316 | 503 | config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from); |
2c00a5a8 | 504 | config.datadir = install.datadir.clone().map(PathBuf::from); |
32a655c1 | 505 | config.docdir = install.docdir.clone().map(PathBuf::from); |
e1599b0c | 506 | set(&mut config.bindir, install.bindir.clone().map(PathBuf::from)); |
32a655c1 | 507 | config.libdir = install.libdir.clone().map(PathBuf::from); |
7cac9316 | 508 | config.mandir = install.mandir.clone().map(PathBuf::from); |
32a655c1 | 509 | } |
7453a54e | 510 | |
dfeec247 XL |
511 | // We want the llvm-skip-rebuild flag to take precedence over the |
512 | // skip-rebuild config.toml option so we store it separately | |
513 | // so that we can infer the right value | |
514 | let mut llvm_skip_rebuild = flags.llvm_skip_rebuild; | |
515 | ||
ea8adc8c XL |
516 | // Store off these values as options because if they're not provided |
517 | // we'll infer default values for them later | |
518 | let mut llvm_assertions = None; | |
ea8adc8c | 519 | let mut debug = None; |
ea8adc8c | 520 | let mut debug_assertions = None; |
dc9dc135 XL |
521 | let mut debuginfo_level = None; |
522 | let mut debuginfo_level_rustc = None; | |
523 | let mut debuginfo_level_std = None; | |
524 | let mut debuginfo_level_tools = None; | |
525 | let mut debuginfo_level_tests = None; | |
ea8adc8c XL |
526 | let mut optimize = None; |
527 | let mut ignore_git = None; | |
528 | ||
7453a54e | 529 | if let Some(ref llvm) = toml.llvm { |
476ff2be | 530 | match llvm.ccache { |
dfeec247 | 531 | Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()), |
476ff2be SL |
532 | Some(StringOrBool::Bool(true)) => { |
533 | config.ccache = Some("ccache".to_string()); | |
534 | } | |
535 | Some(StringOrBool::Bool(false)) | None => {} | |
536 | } | |
a7813a04 | 537 | set(&mut config.ninja, llvm.ninja); |
ea8adc8c | 538 | llvm_assertions = llvm.assertions; |
dfeec247 | 539 | llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild); |
7453a54e | 540 | set(&mut config.llvm_optimize, llvm.optimize); |
b7449926 | 541 | set(&mut config.llvm_thin_lto, llvm.thin_lto); |
476ff2be | 542 | set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); |
7453a54e SL |
543 | set(&mut config.llvm_version_check, llvm.version_check); |
544 | set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); | |
ea8adc8c | 545 | set(&mut config.llvm_link_shared, llvm.link_shared); |
32a655c1 | 546 | config.llvm_targets = llvm.targets.clone(); |
416331ca | 547 | config.llvm_experimental_targets = llvm.experimental_targets.clone(); |
8bb4bdeb | 548 | config.llvm_link_jobs = llvm.link_jobs; |
b7449926 | 549 | config.llvm_version_suffix = llvm.version_suffix.clone(); |
94b46f34 | 550 | config.llvm_clang_cl = llvm.clang_cl.clone(); |
9fa01778 XL |
551 | |
552 | config.llvm_cflags = llvm.cflags.clone(); | |
553 | config.llvm_cxxflags = llvm.cxxflags.clone(); | |
554 | config.llvm_ldflags = llvm.ldflags.clone(); | |
0731742a | 555 | set(&mut config.llvm_use_libcxx, llvm.use_libcxx); |
9fa01778 | 556 | config.llvm_use_linker = llvm.use_linker.clone(); |
74b04a01 | 557 | config.llvm_allow_old_toolchain = llvm.allow_old_toolchain; |
7453a54e | 558 | } |
32a655c1 | 559 | |
7453a54e | 560 | if let Some(ref rust) = toml.rust { |
ea8adc8c XL |
561 | debug = rust.debug; |
562 | debug_assertions = rust.debug_assertions; | |
dc9dc135 XL |
563 | debuginfo_level = rust.debuginfo_level; |
564 | debuginfo_level_rustc = rust.debuginfo_level_rustc; | |
565 | debuginfo_level_std = rust.debuginfo_level_std; | |
566 | debuginfo_level_tools = rust.debuginfo_level_tools; | |
567 | debuginfo_level_tests = rust.debuginfo_level_tests; | |
ea8adc8c XL |
568 | optimize = rust.optimize; |
569 | ignore_git = rust.ignore_git; | |
a7813a04 | 570 | set(&mut config.rust_optimize_tests, rust.optimize_tests); |
9e0c209e | 571 | set(&mut config.codegen_tests, rust.codegen_tests); |
7453a54e | 572 | set(&mut config.rust_rpath, rust.rpath); |
a1dfa0c6 XL |
573 | set(&mut config.jemalloc, rust.jemalloc); |
574 | set(&mut config.test_compare_mode, rust.test_compare_mode); | |
532ac7d7 | 575 | set(&mut config.llvm_libunwind, rust.llvm_libunwind); |
5bcae85e | 576 | set(&mut config.backtrace, rust.backtrace); |
7453a54e | 577 | set(&mut config.channel, rust.channel.clone()); |
ea8adc8c | 578 | set(&mut config.rust_dist_src, rust.dist_src); |
94b46f34 | 579 | set(&mut config.verbose_tests, rust.verbose_tests); |
94b46f34 XL |
580 | // in the case "false" is set explicitly, do not overwrite the command line args |
581 | if let Some(true) = rust.incremental { | |
582 | config.incremental = true; | |
583 | } | |
74b04a01 | 584 | set(&mut config.use_lld, rust.use_lld); |
0531ce1d | 585 | set(&mut config.lld_enabled, rust.lld); |
b7449926 | 586 | set(&mut config.lldb_enabled, rust.lldb); |
8faf50e0 | 587 | set(&mut config.llvm_tools_enabled, rust.llvm_tools); |
9fa01778 | 588 | config.rustc_parallel = rust.parallel_compiler.unwrap_or(false); |
7453a54e | 589 | config.rustc_default_linker = rust.default_linker.clone(); |
7453a54e | 590 | config.musl_root = rust.musl_root.clone().map(PathBuf::from); |
ff7c6d11 | 591 | config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from); |
416331ca | 592 | set(&mut config.deny_warnings, flags.deny_warnings.or(rust.deny_warnings)); |
83c7162d | 593 | set(&mut config.backtrace_on_ice, rust.backtrace_on_ice); |
8faf50e0 | 594 | set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir); |
dfeec247 | 595 | config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit; |
b7449926 | 596 | set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo); |
74b04a01 | 597 | set(&mut config.control_flow_guard, rust.control_flow_guard); |
7453a54e | 598 | |
2c00a5a8 | 599 | if let Some(ref backends) = rust.codegen_backends { |
dfeec247 XL |
600 | config.rust_codegen_backends = |
601 | backends.iter().map(|s| INTERNER.intern_str(s)).collect(); | |
2c00a5a8 XL |
602 | } |
603 | ||
dc9dc135 XL |
604 | config.rust_codegen_units = rust.codegen_units.map(threads_from_config); |
605 | config.rust_codegen_units_std = rust.codegen_units_std.map(threads_from_config); | |
7453a54e SL |
606 | } |
607 | ||
608 | if let Some(ref t) = toml.target { | |
609 | for (triple, cfg) in t { | |
74b04a01 | 610 | let mut target = Target::from_triple(triple); |
7453a54e SL |
611 | |
612 | if let Some(ref s) = cfg.llvm_config { | |
83c7162d | 613 | target.llvm_config = Some(config.src.join(s)); |
7453a54e | 614 | } |
0bf4aa26 XL |
615 | if let Some(ref s) = cfg.llvm_filecheck { |
616 | target.llvm_filecheck = Some(config.src.join(s)); | |
617 | } | |
7453a54e | 618 | if let Some(ref s) = cfg.android_ndk { |
83c7162d | 619 | target.ndk = Some(config.src.join(s)); |
7453a54e | 620 | } |
74b04a01 XL |
621 | if let Some(s) = cfg.no_std { |
622 | target.no_std = s; | |
623 | } | |
7453a54e | 624 | target.cc = cfg.cc.clone().map(PathBuf::from); |
abe05a73 XL |
625 | target.cxx = cfg.cxx.clone().map(PathBuf::from); |
626 | target.ar = cfg.ar.clone().map(PathBuf::from); | |
b7449926 | 627 | target.ranlib = cfg.ranlib.clone().map(PathBuf::from); |
abe05a73 | 628 | target.linker = cfg.linker.clone().map(PathBuf::from); |
74b04a01 | 629 | target.crt_static = cfg.crt_static; |
c30ab7b3 | 630 | target.musl_root = cfg.musl_root.clone().map(PathBuf::from); |
532ac7d7 | 631 | target.wasi_root = cfg.wasi_root.clone().map(PathBuf::from); |
8bb4bdeb | 632 | target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from); |
7453a54e | 633 | |
3b2f2976 | 634 | config.target_config.insert(INTERNER.intern_string(triple.clone()), target); |
7453a54e SL |
635 | } |
636 | } | |
637 | ||
32a655c1 SL |
638 | if let Some(ref t) = toml.dist { |
639 | config.dist_sign_folder = t.sign_folder.clone().map(PathBuf::from); | |
640 | config.dist_gpg_password_file = t.gpg_password_file.clone().map(PathBuf::from); | |
641 | config.dist_upload_addr = t.upload_addr.clone(); | |
8bb4bdeb | 642 | set(&mut config.rust_dist_src, t.src_tarball); |
0bf4aa26 | 643 | set(&mut config.missing_tools, t.missing_tools); |
32a655c1 SL |
644 | } |
645 | ||
ea8adc8c XL |
646 | // Now that we've reached the end of our configuration, infer the |
647 | // default values for all options that we haven't otherwise stored yet. | |
7cac9316 | 648 | |
83c7162d XL |
649 | set(&mut config.initial_rustc, build.rustc.map(PathBuf::from)); |
650 | set(&mut config.initial_cargo, build.cargo.map(PathBuf::from)); | |
651 | ||
dfeec247 XL |
652 | config.llvm_skip_rebuild = llvm_skip_rebuild.unwrap_or(false); |
653 | ||
abe05a73 | 654 | let default = false; |
ea8adc8c | 655 | config.llvm_assertions = llvm_assertions.unwrap_or(default); |
7453a54e | 656 | |
0bf4aa26 XL |
657 | let default = true; |
658 | config.rust_optimize = optimize.unwrap_or(default); | |
659 | ||
ea8adc8c | 660 | let default = debug == Some(true); |
ea8adc8c | 661 | config.rust_debug_assertions = debug_assertions.unwrap_or(default); |
7453a54e | 662 | |
dc9dc135 | 663 | let with_defaults = |debuginfo_level_specific: Option<u32>| { |
dfeec247 XL |
664 | debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { |
665 | 2 | |
666 | } else { | |
667 | 0 | |
668 | }) | |
dc9dc135 XL |
669 | }; |
670 | config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc); | |
671 | config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std); | |
672 | config.rust_debuginfo_level_tools = with_defaults(debuginfo_level_tools); | |
673 | config.rust_debuginfo_level_tests = debuginfo_level_tests.unwrap_or(0); | |
674 | ||
ea8adc8c XL |
675 | let default = config.channel == "dev"; |
676 | config.ignore_git = ignore_git.unwrap_or(default); | |
8bb4bdeb | 677 | |
ea8adc8c | 678 | config |
7453a54e | 679 | } |
32a655c1 | 680 | |
60c5eb7d XL |
681 | /// Try to find the relative path of `bindir`, otherwise return it in full. |
682 | pub fn bindir_relative(&self) -> &Path { | |
683 | let bindir = &self.bindir; | |
684 | if bindir.is_absolute() { | |
685 | // Try to make it relative to the prefix. | |
686 | if let Some(prefix) = &self.prefix { | |
687 | if let Ok(stripped) = bindir.strip_prefix(prefix) { | |
688 | return stripped; | |
689 | } | |
690 | } | |
691 | } | |
692 | bindir | |
693 | } | |
694 | ||
2c00a5a8 XL |
695 | /// Try to find the relative path of `libdir`. |
696 | pub fn libdir_relative(&self) -> Option<&Path> { | |
697 | let libdir = self.libdir.as_ref()?; | |
698 | if libdir.is_relative() { | |
699 | Some(libdir) | |
700 | } else { | |
701 | // Try to make it relative to the prefix. | |
702 | libdir.strip_prefix(self.prefix.as_ref()?).ok() | |
703 | } | |
704 | } | |
705 | ||
32a655c1 SL |
706 | pub fn verbose(&self) -> bool { |
707 | self.verbose > 0 | |
708 | } | |
709 | ||
710 | pub fn very_verbose(&self) -> bool { | |
711 | self.verbose > 1 | |
712 | } | |
532ac7d7 XL |
713 | |
714 | pub fn llvm_enabled(&self) -> bool { | |
715 | self.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) | |
532ac7d7 | 716 | } |
7453a54e SL |
717 | } |
718 | ||
719 | fn set<T>(field: &mut T, val: Option<T>) { | |
720 | if let Some(v) = val { | |
721 | *field = v; | |
722 | } | |
723 | } | |
dc9dc135 XL |
724 | |
725 | fn threads_from_config(v: u32) -> u32 { | |
726 | match v { | |
727 | 0 => num_cpus::get() as u32, | |
728 | n => n, | |
729 | } | |
730 | } |