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 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>,
}
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.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);
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);
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());