use std::io::prelude::*;
use std::path::PathBuf;
use std::process;
+use std::cmp;
use num_cpus;
use toml;
use util::{exe, push_exe_path};
use cache::{INTERNER, Interned};
+use flags::Flags;
+pub use flags::Subcommand;
/// Global configuration for the entire build and/or bootstrap.
///
/// Note that this structure is not decoded directly into, but rather it is
/// filled out from the decoded forms of the structs below. For documentation
/// each field, see the corresponding fields in
-/// `src/bootstrap/config.toml.example`.
+/// `config.toml.example`.
#[derive(Default)]
pub struct Config {
pub ccache: Option<String>,
pub extended: bool,
pub sanitizers: bool,
pub profiler: bool,
+ pub ignore_git: bool,
+
+ pub run_host_only: bool,
+
+ pub on_fail: Option<String>,
+ pub stage: Option<u32>,
+ pub keep_stage: Option<u32>,
+ pub src: PathBuf,
+ pub jobs: Option<u32>,
+ pub cmd: Subcommand,
+ pub incremental: bool,
// llvm codegen options
+ pub llvm_enabled: bool,
pub llvm_assertions: bool,
pub llvm_optimize: bool,
pub llvm_release_debuginfo: bool,
pub llvm_targets: Option<String>,
pub llvm_experimental_targets: Option<String>,
pub llvm_link_jobs: Option<u32>,
- pub llvm_clean_rebuild: bool,
// rust codegen options
pub rust_optimize: bool,
pub rust_dist_src: bool,
pub build: Interned<String>,
- pub host: Vec<Interned<String>>,
- pub target: Vec<Interned<String>>,
+ pub hosts: Vec<Interned<String>>,
+ pub targets: Vec<Interned<String>>,
pub local_rebuild: bool,
// dist misc
pub cc: Option<PathBuf>,
pub cxx: Option<PathBuf>,
pub ndk: Option<PathBuf>,
+ pub crt_static: Option<bool>,
pub musl_root: Option<PathBuf>,
pub qemu_rootfs: Option<PathBuf>,
}
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
+ enabled: Option<bool>,
ccache: Option<StringOrBool>,
ninja: Option<bool>,
assertions: Option<bool>,
targets: Option<String>,
experimental_targets: Option<String>,
link_jobs: Option<u32>,
- clean_rebuild: Option<bool>,
}
#[derive(Deserialize, Default, Clone)]
optimize_tests: Option<bool>,
debuginfo_tests: Option<bool>,
codegen_tests: Option<bool>,
+ ignore_git: Option<bool>,
}
/// TOML representation of how each build target is configured.
cc: Option<String>,
cxx: Option<String>,
android_ndk: Option<String>,
+ crt_static: Option<bool>,
musl_root: Option<String>,
qemu_rootfs: Option<String>,
}
impl Config {
- pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
+ pub fn parse(args: &[String]) -> Config {
+ let flags = Flags::parse(&args);
+ let file = flags.config.clone();
let mut config = Config::default();
+ config.llvm_enabled = true;
config.llvm_optimize = true;
config.use_jemalloc = true;
config.backtrace = true;
config.docs = true;
config.rust_rpath = true;
config.rust_codegen_units = 1;
- config.build = INTERNER.intern_str(build);
config.channel = "dev".to_string();
config.codegen_tests = true;
+ config.ignore_git = false;
config.rust_dist_src = true;
+ config.on_fail = flags.on_fail;
+ config.stage = flags.stage;
+ config.src = flags.src;
+ config.jobs = flags.jobs;
+ config.cmd = flags.cmd;
+ config.incremental = flags.incremental;
+ config.keep_stage = flags.keep_stage;
+
+ // If --target was specified but --host wasn't specified, don't run any host-only tests.
+ config.run_host_only = flags.host.is_empty() && !flags.target.is_empty();
+
let toml = file.map(|file| {
let mut f = t!(File::open(&file));
let mut contents = String::new();
let build = toml.build.clone().unwrap_or(Build::default());
set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x)));
- config.host.push(config.build.clone());
+ set(&mut config.build, flags.build);
+ if config.build.is_empty() {
+ // set by bootstrap.py
+ config.build = INTERNER.intern_str(&env::var("BUILD").unwrap());
+ }
+ config.hosts.push(config.build.clone());
for host in build.host.iter() {
let host = INTERNER.intern_str(host);
- if !config.host.contains(&host) {
- config.host.push(host);
+ if !config.hosts.contains(&host) {
+ config.hosts.push(host);
}
}
- for target in config.host.iter().cloned()
+ for target in config.hosts.iter().cloned()
.chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
{
- if !config.target.contains(&target) {
- config.target.push(target);
+ 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.nodejs = build.nodejs.map(PathBuf::from);
config.gdb = build.gdb.map(PathBuf::from);
config.python = build.python.map(PathBuf::from);
set(&mut config.sanitizers, build.sanitizers);
set(&mut config.profiler, build.profiler);
set(&mut config.openssl_static, build.openssl_static);
+ config.verbose = cmp::max(config.verbose, flags.verbose);
if let Some(ref install) = toml.install {
config.prefix = install.prefix.clone().map(PathBuf::from);
Some(StringOrBool::Bool(false)) | None => {}
}
set(&mut config.ninja, llvm.ninja);
+ set(&mut config.llvm_enabled, llvm.enabled);
set(&mut config.llvm_assertions, llvm.assertions);
set(&mut config.llvm_optimize, llvm.optimize);
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
set(&mut config.llvm_version_check, llvm.version_check);
set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp);
- set(&mut config.llvm_clean_rebuild, llvm.clean_rebuild);
config.llvm_targets = llvm.targets.clone();
config.llvm_experimental_targets = llvm.experimental_targets.clone();
config.llvm_link_jobs = llvm.link_jobs;
set(&mut config.use_jemalloc, rust.use_jemalloc);
set(&mut config.backtrace, rust.backtrace);
set(&mut config.channel, rust.channel.clone());
+ set(&mut config.ignore_git, rust.ignore_git);
config.rustc_default_linker = rust.default_linker.clone();
config.rustc_default_ar = rust.default_ar.clone();
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
}
target.cxx = cfg.cxx.clone().map(PathBuf::from);
target.cc = cfg.cc.clone().map(PathBuf::from);
+ target.crt_static = cfg.crt_static.clone();
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
("LLVM_VERSION_CHECK", self.llvm_version_check),
("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp),
("LLVM_LINK_SHARED", self.llvm_link_shared),
- ("LLVM_CLEAN_REBUILD", self.llvm_clean_rebuild),
("OPTIMIZE", self.rust_optimize),
("DEBUG_ASSERTIONS", self.rust_debug_assertions),
("DEBUGINFO", self.rust_debuginfo),
match key {
"CFG_BUILD" if value.len() > 0 => self.build = INTERNER.intern_str(value),
"CFG_HOST" if value.len() > 0 => {
- self.host.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
+ self.hosts.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
}
"CFG_TARGET" if value.len() > 0 => {
- self.target.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
+ self.targets.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
}
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
self.llvm_experimental_targets = Some(value.to_string());
let target = self.target_config.entry(target).or_insert(Target::default());
target.qemu_rootfs = Some(parse_configure_path(value));
}
+ "CFG_QEMU_AARCH64_ROOTFS" if value.len() > 0 => {
+ let target = INTERNER.intern_str("aarch64-unknown-linux-gnu");
+ let target = self.target_config.entry(target).or_insert(Target::default());
+ target.qemu_rootfs = Some(parse_configure_path(value));
+ }
_ => {}
}
}