diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 74dd4a6fa014..b65c20e398e8 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -119,7 +119,28 @@ impl StepDescription { } } - fn maybe_run(&self, builder: &Builder, path: Option<&Path>) { + fn maybe_run(&self, builder: &Builder, should_run: &ShouldRun, path: Option<&Path>) { + if let Some(path) = path { + if builder.config.exclude.iter().any(|e| e == path) { + eprintln!("Skipping {:?} because this path is excluded", path); + return; + } else if !builder.config.exclude.is_empty() { + eprintln!("{:?} not skipped -- not in {:?}", path, builder.config.exclude); + } + } else { + if !should_run.paths.is_empty() { + if should_run.paths.iter().all(|p| builder.config.exclude.contains(&p)) { + eprintln!("Skipping because all of its paths ({:?}) are excluded", + should_run.paths); + return; + } else if should_run.paths.len() > 1 { + for path in &should_run.paths { + self.maybe_run(builder, should_run, Some(path)); + } + return; + } + } + } let build = builder.build; let hosts = if self.only_build_targets || self.only_build { build.build_triple() @@ -160,7 +181,7 @@ impl StepDescription { if paths.is_empty() { for (desc, should_run) in v.iter().zip(should_runs) { if desc.default && should_run.is_really_default { - desc.maybe_run(builder, None); + desc.maybe_run(builder, &should_run, None); } } } else { @@ -169,7 +190,7 @@ impl StepDescription { for (desc, should_run) in v.iter().zip(&should_runs) { if should_run.run(path) { attempted_run = true; - desc.maybe_run(builder, Some(path)); + desc.maybe_run(builder, &should_run, Some(path)); } } @@ -208,13 +229,13 @@ impl<'a> ShouldRun<'a> { pub fn krate(mut self, name: &str) -> Self { for (_, krate_path) in self.builder.crates(name) { - self.paths.insert(PathBuf::from(krate_path)); + self.paths.insert(t!(env::current_dir()).join(krate_path)); } self } pub fn path(mut self, path: &str) -> Self { - self.paths.insert(PathBuf::from(path)); + self.paths.insert(t!(env::current_dir()).join(path)); self } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 4f4fd14ae8ca..812ca6d64fb6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -56,6 +56,7 @@ pub struct Config { pub sanitizers: bool, pub profiler: bool, pub ignore_git: bool, + pub exclude: Vec, pub run_host_only: bool, @@ -311,6 +312,7 @@ impl Config { let flags = Flags::parse(&args); let file = flags.config.clone(); let mut config = Config::default(); + config.exclude = flags.exclude; config.llvm_enabled = true; config.llvm_optimize = true; config.llvm_version_check = true; diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 478e496078ad..465ebf846d3d 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -42,6 +42,7 @@ pub struct Flags { pub jobs: Option, pub cmd: Subcommand, pub incremental: bool, + pub exclude: Vec, } pub enum Subcommand { @@ -109,6 +110,7 @@ To learn more about a subcommand, run `./x.py -h`"); opts.optopt("", "build", "build target of the stage0 compiler", "BUILD"); opts.optmulti("", "host", "host targets to build", "HOST"); opts.optmulti("", "target", "target targets to build", "TARGET"); + opts.optmulti("", "exclude", "build paths to exclude", "PATH"); opts.optopt("", "on-fail", "command to run on failure", "CMD"); opts.optopt("", "stage", "stage to build", "N"); opts.optopt("", "keep-stage", "stage to keep without recompiling", "N"); @@ -358,10 +360,9 @@ Arguments: stage = Some(1); } - let cwd = t!(env::current_dir()); let src = matches.opt_str("src").map(PathBuf::from) .or_else(|| env::var_os("SRC").map(PathBuf::from)) - .unwrap_or(cwd); + .unwrap_or(cwd.clone()); Flags { verbose: matches.opt_count("verbose"), @@ -378,6 +379,8 @@ Arguments: jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()), cmd, incremental: matches.opt_present("incremental"), + exclude: split(matches.opt_strs("exclude")) + .into_iter().map(|p| cwd.join(p)).collect::>(), } } }