//! This module implements parsing `config.toml` configuration files to tweak
//! how the build runs.
+use std::cmp;
use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;
-use std::cmp;
-use build_helper::t;
-use toml;
-use serde::Deserialize;
-use crate::cache::{INTERNER, Interned};
+use crate::cache::{Interned, INTERNER};
use crate::flags::Flags;
pub use crate::flags::Subcommand;
+use build_helper::t;
+use serde::Deserialize;
+use toml;
/// Global configuration for the entire build and/or bootstrap.
///
pub backtrace_on_ice: bool,
// llvm codegen options
+ pub llvm_skip_rebuild: bool,
pub llvm_assertions: bool,
pub llvm_optimize: bool,
pub llvm_thin_lto: bool,
pub rust_dist_src: bool,
pub rust_codegen_backends: Vec<Interned<String>>,
pub rust_verify_llvm_ir: bool,
+ pub rust_thin_lto_import_instr_limit: Option<u32>,
pub rust_remap_debuginfo: bool,
pub build: Interned<String>,
target: Vec<String>,
cargo: Option<String>,
rustc: Option<String>,
+ rustfmt: Option<String>, /* allow bootstrap.py to use rustfmt key */
docs: Option<bool>,
compiler_docs: Option<bool>,
submodules: Option<bool>,
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
+ skip_rebuild: Option<bool>,
optimize: Option<bool>,
thin_lto: Option<bool>,
release_debuginfo: Option<bool>,
deny_warnings: Option<bool>,
backtrace_on_ice: Option<bool>,
verify_llvm_ir: Option<bool>,
+ thin_lto_import_instr_limit: Option<u32>,
remap_debuginfo: Option<bool>,
jemalloc: Option<bool>,
test_compare_mode: Option<bool>,
let has_targets = !flags.target.is_empty();
config.skip_only_host_steps = !has_hosts && has_targets;
- let toml = file.map(|file| {
- let contents = t!(fs::read_to_string(&file));
- match toml::from_str(&contents) {
- Ok(table) => table,
- Err(err) => {
- println!("failed to parse TOML configuration '{}': {}",
- file.display(), err);
- process::exit(2);
+ let toml = file
+ .map(|file| {
+ let contents = t!(fs::read_to_string(&file));
+ match toml::from_str(&contents) {
+ Ok(table) => table,
+ Err(err) => {
+ println!(
+ "failed to parse TOML configuration '{}': {}",
+ file.display(),
+ err
+ );
+ process::exit(2);
+ }
}
- }
- }).unwrap_or_else(|| TomlConfig::default());
+ })
+ .unwrap_or_else(|| TomlConfig::default());
let build = toml.build.clone().unwrap_or_default();
// set by bootstrap.py
config.hosts.push(host);
}
}
- for target in config.hosts.iter().cloned()
- .chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
+ for target in
+ config.hosts.iter().cloned().chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
{
if !config.targets.contains(&target) {
config.targets.push(target);
}
}
- config.hosts = if !flags.host.is_empty() {
- flags.host
- } else {
- config.hosts
- };
- config.targets = if !flags.target.is_empty() {
- flags.target
- } else {
- config.targets
- };
-
+ config.hosts = if !flags.host.is_empty() { flags.host } else { config.hosts };
+ config.targets = if !flags.target.is_empty() { flags.target } else { config.targets };
config.nodejs = build.nodejs.map(PathBuf::from);
config.gdb = build.gdb.map(PathBuf::from);
// Store off these values as options because if they're not provided
// we'll infer default values for them later
+ let mut llvm_skip_rebuild = None;
let mut llvm_assertions = None;
let mut debug = None;
let mut debug_assertions = None;
if let Some(ref llvm) = toml.llvm {
match llvm.ccache {
- Some(StringOrBool::String(ref s)) => {
- config.ccache = Some(s.to_string())
- }
+ Some(StringOrBool::String(ref s)) => config.ccache = Some(s.to_string()),
Some(StringOrBool::Bool(true)) => {
config.ccache = Some("ccache".to_string());
}
}
set(&mut config.ninja, llvm.ninja);
llvm_assertions = llvm.assertions;
+ llvm_skip_rebuild = llvm.skip_rebuild;
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.deny_warnings, flags.deny_warnings.or(rust.deny_warnings));
set(&mut config.backtrace_on_ice, rust.backtrace_on_ice);
set(&mut config.rust_verify_llvm_ir, rust.verify_llvm_ir);
+ config.rust_thin_lto_import_instr_limit = rust.thin_lto_import_instr_limit;
set(&mut config.rust_remap_debuginfo, rust.remap_debuginfo);
if let Some(ref backends) = rust.codegen_backends {
- config.rust_codegen_backends = backends.iter()
- .map(|s| INTERNER.intern_str(s))
- .collect();
+ config.rust_codegen_backends =
+ backends.iter().map(|s| INTERNER.intern_str(s)).collect();
}
config.rust_codegen_units = rust.codegen_units.map(threads_from_config);
set(&mut config.initial_rustc, build.rustc.map(PathBuf::from));
set(&mut config.initial_cargo, build.cargo.map(PathBuf::from));
+ config.llvm_skip_rebuild = llvm_skip_rebuild.unwrap_or(false);
+
let default = false;
config.llvm_assertions = llvm_assertions.unwrap_or(default);
config.rust_debug_assertions = debug_assertions.unwrap_or(default);
let with_defaults = |debuginfo_level_specific: Option<u32>| {
- debuginfo_level_specific
- .or(debuginfo_level)
- .unwrap_or(if debug == Some(true) { 2 } else { 0 })
+ debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) {
+ 2
+ } else {
+ 0
+ })
};
config.rust_debuginfo_level_rustc = with_defaults(debuginfo_level_rustc);
config.rust_debuginfo_level_std = with_defaults(debuginfo_level_std);