1 //! Serialized configuration of a build.
3 //! This module implements parsing `config.toml` configuration files to tweak
4 //! how the build runs.
7 use std
::collections
::{HashMap, HashSet}
;
9 use std
::ffi
::OsString
;
11 use std
::path
::{Path, PathBuf}
;
14 use crate::cache
::{Interned, INTERNER}
;
15 use crate::flags
::Flags
;
16 pub use crate::flags
::Subcommand
;
18 use serde
::Deserialize
;
20 /// Global configuration for the entire build and/or bootstrap.
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`.
27 /// Note that this structure is not decoded directly into, but rather it is
28 /// filled out from the decoded forms of the structs below. For documentation
29 /// each field, see the corresponding fields in
30 /// `config.toml.example`.
33 pub ccache
: Option
<String
>,
37 pub fast_submodules
: bool
,
38 pub compiler_docs
: bool
,
40 pub locked_deps
: bool
,
42 pub target_config
: HashMap
<Interned
<String
>, Target
>,
43 pub full_bootstrap
: bool
,
45 pub tools
: Option
<HashSet
<String
>>,
49 pub exclude
: Vec
<PathBuf
>,
50 pub rustc_error_format
: Option
<String
>,
51 pub json_output
: bool
,
52 pub test_compare_mode
: bool
,
53 pub llvm_libunwind
: bool
,
55 pub skip_only_host_steps
: bool
,
57 pub on_fail
: Option
<String
>,
58 pub stage
: Option
<u32>,
59 pub keep_stage
: Vec
<u32>,
61 pub jobs
: Option
<u32>,
63 pub incremental
: bool
,
66 pub deny_warnings
: bool
,
67 pub backtrace_on_ice
: bool
,
69 // llvm codegen options
70 pub llvm_skip_rebuild
: bool
,
71 pub llvm_assertions
: bool
,
72 pub llvm_optimize
: bool
,
73 pub llvm_thin_lto
: bool
,
74 pub llvm_release_debuginfo
: bool
,
75 pub llvm_version_check
: bool
,
76 pub llvm_static_stdcpp
: bool
,
77 pub llvm_link_shared
: bool
,
78 pub llvm_clang_cl
: Option
<String
>,
79 pub llvm_targets
: Option
<String
>,
80 pub llvm_experimental_targets
: Option
<String
>,
81 pub llvm_link_jobs
: Option
<u32>,
82 pub llvm_version_suffix
: Option
<String
>,
83 pub llvm_use_linker
: Option
<String
>,
84 pub llvm_allow_old_toolchain
: Option
<bool
>,
87 pub lld_enabled
: bool
,
88 pub llvm_tools_enabled
: bool
,
90 pub llvm_cflags
: Option
<String
>,
91 pub llvm_cxxflags
: Option
<String
>,
92 pub llvm_ldflags
: Option
<String
>,
93 pub llvm_use_libcxx
: bool
,
95 // rust codegen options
96 pub rust_optimize
: bool
,
97 pub rust_codegen_units
: Option
<u32>,
98 pub rust_codegen_units_std
: Option
<u32>,
99 pub rust_debug_assertions
: bool
,
100 pub rust_debug_assertions_std
: bool
,
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,
105 pub rust_rpath
: bool
,
106 pub rustc_parallel
: bool
,
107 pub rustc_default_linker
: Option
<String
>,
108 pub rust_optimize_tests
: bool
,
109 pub rust_dist_src
: bool
,
110 pub rust_codegen_backends
: Vec
<Interned
<String
>>,
111 pub rust_verify_llvm_ir
: bool
,
112 pub rust_thin_lto_import_instr_limit
: Option
<u32>,
113 pub rust_remap_debuginfo
: bool
,
115 pub build
: Interned
<String
>,
116 pub hosts
: Vec
<Interned
<String
>>,
117 pub targets
: Vec
<Interned
<String
>>,
118 pub local_rebuild
: bool
,
120 pub control_flow_guard
: bool
,
123 pub dist_sign_folder
: Option
<PathBuf
>,
124 pub dist_upload_addr
: Option
<String
>,
125 pub dist_gpg_password_file
: Option
<PathBuf
>,
128 pub backtrace
: bool
, // support for RUST_BACKTRACE
131 pub low_priority
: bool
,
133 pub verbose_tests
: bool
,
134 pub save_toolstates
: Option
<PathBuf
>,
135 pub print_step_timings
: bool
,
136 pub missing_tools
: bool
,
138 // Fallback musl-root for all targets
139 pub musl_root
: Option
<PathBuf
>,
140 pub prefix
: Option
<PathBuf
>,
141 pub sysconfdir
: Option
<PathBuf
>,
142 pub datadir
: Option
<PathBuf
>,
143 pub docdir
: Option
<PathBuf
>,
145 pub libdir
: Option
<PathBuf
>,
146 pub mandir
: Option
<PathBuf
>,
147 pub codegen_tests
: bool
,
148 pub nodejs
: Option
<PathBuf
>,
149 pub gdb
: Option
<PathBuf
>,
150 pub python
: Option
<PathBuf
>,
151 pub cargo_native_static
: bool
,
152 pub configure_args
: Vec
<String
>,
154 // These are either the stage0 downloaded binaries or the locally installed ones.
155 pub initial_cargo
: PathBuf
,
156 pub initial_rustc
: PathBuf
,
157 pub initial_rustfmt
: Option
<PathBuf
>,
161 /// Per-target configuration stored in the global configuration structure.
164 /// Some(path to llvm-config) if using an external LLVM.
165 pub llvm_config
: Option
<PathBuf
>,
166 /// Some(path to FileCheck) if one was specified.
167 pub llvm_filecheck
: Option
<PathBuf
>,
168 pub cc
: Option
<PathBuf
>,
169 pub cxx
: Option
<PathBuf
>,
170 pub ar
: Option
<PathBuf
>,
171 pub ranlib
: Option
<PathBuf
>,
172 pub linker
: Option
<PathBuf
>,
173 pub ndk
: Option
<PathBuf
>,
174 pub crt_static
: Option
<bool
>,
175 pub musl_root
: Option
<PathBuf
>,
176 pub wasi_root
: Option
<PathBuf
>,
177 pub qemu_rootfs
: Option
<PathBuf
>,
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;
190 /// Structure of the `config.toml` file that configuration is read from.
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.
195 #[derive(Deserialize, Default)]
196 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
198 build
: Option
<Build
>,
199 install
: Option
<Install
>,
202 target
: Option
<HashMap
<String
, TomlTarget
>>,
206 /// TOML representation of various global build decisions.
207 #[derive(Deserialize, Default, Clone)]
208 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
210 build
: Option
<String
>,
215 // This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable
216 build_dir
: Option
<String
>,
217 cargo
: Option
<String
>,
218 rustc
: Option
<String
>,
219 rustfmt
: Option
<String
>, /* allow bootstrap.py to use rustfmt key */
221 compiler_docs
: Option
<bool
>,
222 submodules
: Option
<bool
>,
223 fast_submodules
: Option
<bool
>,
225 nodejs
: Option
<String
>,
226 python
: Option
<String
>,
227 locked_deps
: Option
<bool
>,
228 vendor
: Option
<bool
>,
229 full_bootstrap
: Option
<bool
>,
230 extended
: Option
<bool
>,
231 tools
: Option
<HashSet
<String
>>,
232 verbose
: Option
<usize>,
233 sanitizers
: Option
<bool
>,
234 profiler
: Option
<bool
>,
235 cargo_native_static
: Option
<bool
>,
236 low_priority
: Option
<bool
>,
237 configure_args
: Option
<Vec
<String
>>,
238 local_rebuild
: Option
<bool
>,
239 print_step_timings
: Option
<bool
>,
242 /// TOML representation of various global install decisions.
243 #[derive(Deserialize, Default, Clone)]
244 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
246 prefix
: Option
<String
>,
247 sysconfdir
: Option
<String
>,
248 docdir
: Option
<String
>,
249 bindir
: Option
<String
>,
250 libdir
: Option
<String
>,
251 mandir
: Option
<String
>,
252 datadir
: Option
<String
>,
254 // standard paths, currently unused
255 infodir
: Option
<String
>,
256 localstatedir
: Option
<String
>,
259 /// TOML representation of how the LLVM build is configured.
260 #[derive(Deserialize, Default)]
261 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
263 skip_rebuild
: Option
<bool
>,
264 optimize
: Option
<bool
>,
265 thin_lto
: Option
<bool
>,
266 release_debuginfo
: Option
<bool
>,
267 assertions
: Option
<bool
>,
268 ccache
: Option
<StringOrBool
>,
269 version_check
: Option
<bool
>,
270 static_libstdcpp
: Option
<bool
>,
272 targets
: Option
<String
>,
273 experimental_targets
: Option
<String
>,
274 link_jobs
: Option
<u32>,
275 link_shared
: Option
<bool
>,
276 version_suffix
: Option
<String
>,
277 clang_cl
: Option
<String
>,
278 cflags
: Option
<String
>,
279 cxxflags
: Option
<String
>,
280 ldflags
: Option
<String
>,
281 use_libcxx
: Option
<bool
>,
282 use_linker
: Option
<String
>,
283 allow_old_toolchain
: Option
<bool
>,
286 #[derive(Deserialize, Default, Clone)]
287 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
289 sign_folder
: Option
<String
>,
290 gpg_password_file
: Option
<String
>,
291 upload_addr
: Option
<String
>,
292 src_tarball
: Option
<bool
>,
293 missing_tools
: Option
<bool
>,
296 #[derive(Deserialize)]
303 impl Default
for StringOrBool
{
304 fn default() -> StringOrBool
{
305 StringOrBool
::Bool(false)
309 /// TOML representation of how the Rust build is configured.
310 #[derive(Deserialize, Default)]
311 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
313 optimize
: Option
<bool
>,
315 codegen_units
: Option
<u32>,
316 codegen_units_std
: Option
<u32>,
317 debug_assertions
: Option
<bool
>,
318 debug_assertions_std
: Option
<bool
>,
319 debuginfo_level
: Option
<u32>,
320 debuginfo_level_rustc
: Option
<u32>,
321 debuginfo_level_std
: Option
<u32>,
322 debuginfo_level_tools
: Option
<u32>,
323 debuginfo_level_tests
: Option
<u32>,
324 backtrace
: Option
<bool
>,
325 incremental
: Option
<bool
>,
326 parallel_compiler
: Option
<bool
>,
327 default_linker
: Option
<String
>,
328 channel
: Option
<String
>,
329 musl_root
: Option
<String
>,
331 verbose_tests
: Option
<bool
>,
332 optimize_tests
: Option
<bool
>,
333 codegen_tests
: Option
<bool
>,
334 ignore_git
: Option
<bool
>,
335 dist_src
: Option
<bool
>,
336 save_toolstates
: Option
<String
>,
337 codegen_backends
: Option
<Vec
<String
>>,
339 use_lld
: Option
<bool
>,
340 llvm_tools
: Option
<bool
>,
341 deny_warnings
: Option
<bool
>,
342 backtrace_on_ice
: Option
<bool
>,
343 verify_llvm_ir
: Option
<bool
>,
344 thin_lto_import_instr_limit
: Option
<u32>,
345 remap_debuginfo
: Option
<bool
>,
346 jemalloc
: Option
<bool
>,
347 test_compare_mode
: Option
<bool
>,
348 llvm_libunwind
: Option
<bool
>,
349 control_flow_guard
: Option
<bool
>,
352 /// TOML representation of how each build target is configured.
353 #[derive(Deserialize, Default)]
354 #[serde(deny_unknown_fields, rename_all = "kebab-case")]
359 ranlib
: Option
<String
>,
360 linker
: Option
<String
>,
361 llvm_config
: Option
<String
>,
362 llvm_filecheck
: Option
<String
>,
363 android_ndk
: Option
<String
>,
364 crt_static
: Option
<bool
>,
365 musl_root
: Option
<String
>,
366 wasi_root
: Option
<String
>,
367 qemu_rootfs
: Option
<String
>,
368 no_std
: Option
<bool
>,
372 fn path_from_python(var_key
: &str) -> PathBuf
{
373 match env
::var_os(var_key
) {
374 Some(var_val
) => Self::normalize_python_path(var_val
),
375 _
=> panic
!("expected '{}' to be set", var_key
),
379 /// Normalizes paths from Python slightly. We don't trust paths from Python (#49785).
380 fn normalize_python_path(path
: OsString
) -> PathBuf
{
381 Path
::new(&path
).components().collect()
384 pub fn default_opts() -> Config
{
385 let mut config
= Config
::default();
386 config
.llvm_optimize
= true;
387 config
.llvm_version_check
= true;
388 config
.backtrace
= true;
389 config
.rust_optimize
= true;
390 config
.rust_optimize_tests
= true;
391 config
.submodules
= true;
392 config
.fast_submodules
= true;
394 config
.rust_rpath
= true;
395 config
.channel
= "dev".to_string();
396 config
.codegen_tests
= true;
397 config
.ignore_git
= false;
398 config
.rust_dist_src
= true;
399 config
.rust_codegen_backends
= vec
![INTERNER
.intern_str("llvm")];
400 config
.deny_warnings
= true;
401 config
.missing_tools
= false;
403 // set by bootstrap.py
404 config
.build
= INTERNER
.intern_str(&env
::var("BUILD").expect("'BUILD' to be set"));
405 config
.src
= Config
::path_from_python("SRC");
406 config
.out
= Config
::path_from_python("BUILD_DIR");
408 config
.initial_rustc
= Config
::path_from_python("RUSTC");
409 config
.initial_cargo
= Config
::path_from_python("CARGO");
410 config
.initial_rustfmt
= env
::var_os("RUSTFMT").map(Config
::normalize_python_path
);
415 pub fn parse(args
: &[String
]) -> Config
{
416 let flags
= Flags
::parse(&args
);
417 let file
= flags
.config
.clone();
418 let mut config
= Config
::default_opts();
419 config
.exclude
= flags
.exclude
;
420 config
.rustc_error_format
= flags
.rustc_error_format
;
421 config
.json_output
= flags
.json_output
;
422 config
.on_fail
= flags
.on_fail
;
423 config
.stage
= flags
.stage
;
424 config
.jobs
= flags
.jobs
.map(threads_from_config
);
425 config
.cmd
= flags
.cmd
;
426 config
.incremental
= flags
.incremental
;
427 config
.dry_run
= flags
.dry_run
;
428 config
.keep_stage
= flags
.keep_stage
;
429 config
.bindir
= "bin".into(); // default
430 if let Some(value
) = flags
.deny_warnings
{
431 config
.deny_warnings
= value
;
435 let dir
= config
.out
.join("tmp-dry-run");
436 t
!(fs
::create_dir_all(&dir
));
440 // If --target was specified but --host wasn't specified, don't run any host-only tests.
441 let has_hosts
= !flags
.host
.is_empty();
442 let has_targets
= !flags
.target
.is_empty();
443 config
.skip_only_host_steps
= !has_hosts
&& has_targets
;
447 let contents
= t
!(fs
::read_to_string(&file
));
448 match toml
::from_str(&contents
) {
452 "failed to parse TOML configuration '{}': {}",
460 .unwrap_or_else(TomlConfig
::default);
462 let build
= toml
.build
.clone().unwrap_or_default();
463 // set by bootstrap.py
464 config
.hosts
.push(config
.build
.clone());
465 for host
in build
.host
.iter() {
466 let host
= INTERNER
.intern_str(host
);
467 if !config
.hosts
.contains(&host
) {
468 config
.hosts
.push(host
);
472 config
.hosts
.iter().cloned().chain(build
.target
.iter().map(|s
| INTERNER
.intern_str(s
)))
474 if !config
.targets
.contains(&target
) {
475 config
.targets
.push(target
);
478 config
.hosts
= if !flags
.host
.is_empty() { flags.host }
else { config.hosts }
;
479 config
.targets
= if !flags
.target
.is_empty() { flags.target }
else { config.targets }
;
481 config
.nodejs
= build
.nodejs
.map(PathBuf
::from
);
482 config
.gdb
= build
.gdb
.map(PathBuf
::from
);
483 config
.python
= build
.python
.map(PathBuf
::from
);
484 set(&mut config
.low_priority
, build
.low_priority
);
485 set(&mut config
.compiler_docs
, build
.compiler_docs
);
486 set(&mut config
.docs
, build
.docs
);
487 set(&mut config
.submodules
, build
.submodules
);
488 set(&mut config
.fast_submodules
, build
.fast_submodules
);
489 set(&mut config
.locked_deps
, build
.locked_deps
);
490 set(&mut config
.vendor
, build
.vendor
);
491 set(&mut config
.full_bootstrap
, build
.full_bootstrap
);
492 set(&mut config
.extended
, build
.extended
);
493 config
.tools
= build
.tools
;
494 set(&mut config
.verbose
, build
.verbose
);
495 set(&mut config
.sanitizers
, build
.sanitizers
);
496 set(&mut config
.profiler
, build
.profiler
);
497 set(&mut config
.cargo_native_static
, build
.cargo_native_static
);
498 set(&mut config
.configure_args
, build
.configure_args
);
499 set(&mut config
.local_rebuild
, build
.local_rebuild
);
500 set(&mut config
.print_step_timings
, build
.print_step_timings
);
501 config
.verbose
= cmp
::max(config
.verbose
, flags
.verbose
);
503 if let Some(ref install
) = toml
.install
{
504 config
.prefix
= install
.prefix
.clone().map(PathBuf
::from
);
505 config
.sysconfdir
= install
.sysconfdir
.clone().map(PathBuf
::from
);
506 config
.datadir
= install
.datadir
.clone().map(PathBuf
::from
);
507 config
.docdir
= install
.docdir
.clone().map(PathBuf
::from
);
508 set(&mut config
.bindir
, install
.bindir
.clone().map(PathBuf
::from
));
509 config
.libdir
= install
.libdir
.clone().map(PathBuf
::from
);
510 config
.mandir
= install
.mandir
.clone().map(PathBuf
::from
);
513 // We want the llvm-skip-rebuild flag to take precedence over the
514 // skip-rebuild config.toml option so we store it separately
515 // so that we can infer the right value
516 let mut llvm_skip_rebuild
= flags
.llvm_skip_rebuild
;
518 // Store off these values as options because if they're not provided
519 // we'll infer default values for them later
520 let mut llvm_assertions
= None
;
521 let mut debug
= None
;
522 let mut debug_assertions
= None
;
523 let mut debug_assertions_std
= None
;
524 let mut debuginfo_level
= None
;
525 let mut debuginfo_level_rustc
= None
;
526 let mut debuginfo_level_std
= None
;
527 let mut debuginfo_level_tools
= None
;
528 let mut debuginfo_level_tests
= None
;
529 let mut optimize
= None
;
530 let mut ignore_git
= None
;
532 if let Some(ref llvm
) = toml
.llvm
{
534 Some(StringOrBool
::String(ref s
)) => config
.ccache
= Some(s
.to_string()),
535 Some(StringOrBool
::Bool(true)) => {
536 config
.ccache
= Some("ccache".to_string());
538 Some(StringOrBool
::Bool(false)) | None
=> {}
540 set(&mut config
.ninja
, llvm
.ninja
);
541 llvm_assertions
= llvm
.assertions
;
542 llvm_skip_rebuild
= llvm_skip_rebuild
.or(llvm
.skip_rebuild
);
543 set(&mut config
.llvm_optimize
, llvm
.optimize
);
544 set(&mut config
.llvm_thin_lto
, llvm
.thin_lto
);
545 set(&mut config
.llvm_release_debuginfo
, llvm
.release_debuginfo
);
546 set(&mut config
.llvm_version_check
, llvm
.version_check
);
547 set(&mut config
.llvm_static_stdcpp
, llvm
.static_libstdcpp
);
548 set(&mut config
.llvm_link_shared
, llvm
.link_shared
);
549 config
.llvm_targets
= llvm
.targets
.clone();
550 config
.llvm_experimental_targets
= llvm
.experimental_targets
.clone();
551 config
.llvm_link_jobs
= llvm
.link_jobs
;
552 config
.llvm_version_suffix
= llvm
.version_suffix
.clone();
553 config
.llvm_clang_cl
= llvm
.clang_cl
.clone();
555 config
.llvm_cflags
= llvm
.cflags
.clone();
556 config
.llvm_cxxflags
= llvm
.cxxflags
.clone();
557 config
.llvm_ldflags
= llvm
.ldflags
.clone();
558 set(&mut config
.llvm_use_libcxx
, llvm
.use_libcxx
);
559 config
.llvm_use_linker
= llvm
.use_linker
.clone();
560 config
.llvm_allow_old_toolchain
= llvm
.allow_old_toolchain
;
563 if let Some(ref rust
) = toml
.rust
{
565 debug_assertions
= rust
.debug_assertions
;
566 debug_assertions_std
= rust
.debug_assertions_std
;
567 debuginfo_level
= rust
.debuginfo_level
;
568 debuginfo_level_rustc
= rust
.debuginfo_level_rustc
;
569 debuginfo_level_std
= rust
.debuginfo_level_std
;
570 debuginfo_level_tools
= rust
.debuginfo_level_tools
;
571 debuginfo_level_tests
= rust
.debuginfo_level_tests
;
572 optimize
= rust
.optimize
;
573 ignore_git
= rust
.ignore_git
;
574 set(&mut config
.rust_optimize_tests
, rust
.optimize_tests
);
575 set(&mut config
.codegen_tests
, rust
.codegen_tests
);
576 set(&mut config
.rust_rpath
, rust
.rpath
);
577 set(&mut config
.jemalloc
, rust
.jemalloc
);
578 set(&mut config
.test_compare_mode
, rust
.test_compare_mode
);
579 set(&mut config
.llvm_libunwind
, rust
.llvm_libunwind
);
580 set(&mut config
.backtrace
, rust
.backtrace
);
581 set(&mut config
.channel
, rust
.channel
.clone());
582 set(&mut config
.rust_dist_src
, rust
.dist_src
);
583 set(&mut config
.verbose_tests
, rust
.verbose_tests
);
584 // in the case "false" is set explicitly, do not overwrite the command line args
585 if let Some(true) = rust
.incremental
{
586 config
.incremental
= true;
588 set(&mut config
.use_lld
, rust
.use_lld
);
589 set(&mut config
.lld_enabled
, rust
.lld
);
590 set(&mut config
.llvm_tools_enabled
, rust
.llvm_tools
);
591 config
.rustc_parallel
= rust
.parallel_compiler
.unwrap_or(false);
592 config
.rustc_default_linker
= rust
.default_linker
.clone();
593 config
.musl_root
= rust
.musl_root
.clone().map(PathBuf
::from
);
594 config
.save_toolstates
= rust
.save_toolstates
.clone().map(PathBuf
::from
);
595 set(&mut config
.deny_warnings
, flags
.deny_warnings
.or(rust
.deny_warnings
));
596 set(&mut config
.backtrace_on_ice
, rust
.backtrace_on_ice
);
597 set(&mut config
.rust_verify_llvm_ir
, rust
.verify_llvm_ir
);
598 config
.rust_thin_lto_import_instr_limit
= rust
.thin_lto_import_instr_limit
;
599 set(&mut config
.rust_remap_debuginfo
, rust
.remap_debuginfo
);
600 set(&mut config
.control_flow_guard
, rust
.control_flow_guard
);
602 if let Some(ref backends
) = rust
.codegen_backends
{
603 config
.rust_codegen_backends
=
604 backends
.iter().map(|s
| INTERNER
.intern_str(s
)).collect();
607 config
.rust_codegen_units
= rust
.codegen_units
.map(threads_from_config
);
608 config
.rust_codegen_units_std
= rust
.codegen_units_std
.map(threads_from_config
);
611 if let Some(ref t
) = toml
.target
{
612 for (triple
, cfg
) in t
{
613 let mut target
= Target
::from_triple(triple
);
615 if let Some(ref s
) = cfg
.llvm_config
{
616 target
.llvm_config
= Some(config
.src
.join(s
));
618 if let Some(ref s
) = cfg
.llvm_filecheck
{
619 target
.llvm_filecheck
= Some(config
.src
.join(s
));
621 if let Some(ref s
) = cfg
.android_ndk
{
622 target
.ndk
= Some(config
.src
.join(s
));
624 if let Some(s
) = cfg
.no_std
{
627 target
.cc
= cfg
.cc
.clone().map(PathBuf
::from
);
628 target
.cxx
= cfg
.cxx
.clone().map(PathBuf
::from
);
629 target
.ar
= cfg
.ar
.clone().map(PathBuf
::from
);
630 target
.ranlib
= cfg
.ranlib
.clone().map(PathBuf
::from
);
631 target
.linker
= cfg
.linker
.clone().map(PathBuf
::from
);
632 target
.crt_static
= cfg
.crt_static
;
633 target
.musl_root
= cfg
.musl_root
.clone().map(PathBuf
::from
);
634 target
.wasi_root
= cfg
.wasi_root
.clone().map(PathBuf
::from
);
635 target
.qemu_rootfs
= cfg
.qemu_rootfs
.clone().map(PathBuf
::from
);
637 config
.target_config
.insert(INTERNER
.intern_string(triple
.clone()), target
);
641 if let Some(ref t
) = toml
.dist
{
642 config
.dist_sign_folder
= t
.sign_folder
.clone().map(PathBuf
::from
);
643 config
.dist_gpg_password_file
= t
.gpg_password_file
.clone().map(PathBuf
::from
);
644 config
.dist_upload_addr
= t
.upload_addr
.clone();
645 set(&mut config
.rust_dist_src
, t
.src_tarball
);
646 set(&mut config
.missing_tools
, t
.missing_tools
);
649 // Now that we've reached the end of our configuration, infer the
650 // default values for all options that we haven't otherwise stored yet.
652 set(&mut config
.initial_rustc
, build
.rustc
.map(PathBuf
::from
));
653 set(&mut config
.initial_cargo
, build
.cargo
.map(PathBuf
::from
));
655 config
.llvm_skip_rebuild
= llvm_skip_rebuild
.unwrap_or(false);
658 config
.llvm_assertions
= llvm_assertions
.unwrap_or(default);
661 config
.rust_optimize
= optimize
.unwrap_or(default);
663 let default = debug
== Some(true);
664 config
.rust_debug_assertions
= debug_assertions
.unwrap_or(default);
665 config
.rust_debug_assertions_std
=
666 debug_assertions_std
.unwrap_or(config
.rust_debug_assertions
);
668 let with_defaults
= |debuginfo_level_specific
: Option
<u32>| {
669 debuginfo_level_specific
.or(debuginfo_level
).unwrap_or(if debug
== Some(true) {
675 config
.rust_debuginfo_level_rustc
= with_defaults(debuginfo_level_rustc
);
676 config
.rust_debuginfo_level_std
= with_defaults(debuginfo_level_std
);
677 config
.rust_debuginfo_level_tools
= with_defaults(debuginfo_level_tools
);
678 config
.rust_debuginfo_level_tests
= debuginfo_level_tests
.unwrap_or(0);
680 let default = config
.channel
== "dev";
681 config
.ignore_git
= ignore_git
.unwrap_or(default);
686 /// Try to find the relative path of `bindir`, otherwise return it in full.
687 pub fn bindir_relative(&self) -> &Path
{
688 let bindir
= &self.bindir
;
689 if bindir
.is_absolute() {
690 // Try to make it relative to the prefix.
691 if let Some(prefix
) = &self.prefix
{
692 if let Ok(stripped
) = bindir
.strip_prefix(prefix
) {
700 /// Try to find the relative path of `libdir`.
701 pub fn libdir_relative(&self) -> Option
<&Path
> {
702 let libdir
= self.libdir
.as_ref()?
;
703 if libdir
.is_relative() {
706 // Try to make it relative to the prefix.
707 libdir
.strip_prefix(self.prefix
.as_ref()?
).ok()
711 pub fn verbose(&self) -> bool
{
715 pub fn very_verbose(&self) -> bool
{
719 pub fn llvm_enabled(&self) -> bool
{
720 self.rust_codegen_backends
.contains(&INTERNER
.intern_str("llvm"))
724 fn set
<T
>(field
: &mut T
, val
: Option
<T
>) {
725 if let Some(v
) = val
{
730 fn threads_from_config(v
: u32) -> u32 {
732 0 => num_cpus
::get() as u32,