diff --git a/src/bootstrap/build/clean.rs b/src/bootstrap/build/clean.rs new file mode 100644 index 0000000000000..8f78fed001cf1 --- /dev/null +++ b/src/bootstrap/build/clean.rs @@ -0,0 +1,36 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fs; +use std::path::Path; + +use build::Build; + +pub fn clean(build: &Build) { + for host in build.config.host.iter() { + + let out = build.out.join(host); + + rm_rf(build, &out.join("compiler-rt")); + + for stage in 0..4 { + rm_rf(build, &out.join(format!("stage{}", stage))); + rm_rf(build, &out.join(format!("stage{}-std", stage))); + rm_rf(build, &out.join(format!("stage{}-rustc", stage))); + } + } +} + +fn rm_rf(build: &Build, path: &Path) { + if path.exists() { + build.verbose(&format!("removing `{}`", path.display())); + t!(fs::remove_dir_all(path)); + } +} diff --git a/src/bootstrap/build/flags.rs b/src/bootstrap/build/flags.rs index cd538bb0a905a..d91dfe0903d11 100644 --- a/src/bootstrap/build/flags.rs +++ b/src/bootstrap/build/flags.rs @@ -26,6 +26,7 @@ pub struct Flags { pub src: Option, pub jobs: Option, pub args: Vec, + pub clean: bool, } pub struct Filter { @@ -44,6 +45,7 @@ impl Flags { opts.optopt("", "stage", "stage to build", "N"); opts.optopt("", "src", "path to repo root", "DIR"); opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS"); + opts.optflag("", "clean", "clean output directory"); opts.optflag("h", "help", "print this help message"); let usage = |n| -> ! { @@ -75,6 +77,7 @@ impl Flags { Flags { verbose: m.opt_present("v"), + clean: m.opt_present("clean"), stage: m.opt_str("stage").map(|j| j.parse().unwrap()), build: m.opt_str("build").unwrap(), host: Filter { values: m.opt_strs("host") }, diff --git a/src/bootstrap/build/job.rs b/src/bootstrap/build/job.rs index 49e027ffda596..a4e53bc45fcfb 100644 --- a/src/bootstrap/build/job.rs +++ b/src/bootstrap/build/job.rs @@ -64,9 +64,20 @@ pub unsafe fn setup() { mem::size_of_val(&info) as DWORD); assert!(r != 0, "{}", io::Error::last_os_error()); - // Assign our process to this job object + // Assign our process to this job object. Note that if this fails, one very + // likely reason is that we are ourselves already in a job object! This can + // happen on the build bots that we've got for Windows, or if just anyone + // else is instrumenting the build. In this case we just bail out + // immediately and assume that they take care of it. + // + // Also note that nested jobs (why this might fail) are supported in recent + // versions of Windows, but the version of Windows that our bots are running + // at least don't support nested job objects. let r = AssignProcessToJobObject(job, GetCurrentProcess()); - assert!(r != 0, "{}", io::Error::last_os_error()); + if r == 0 { + CloseHandle(job); + return + } // If we've got a parent process (e.g. the python script that called us) // then move ownership of this job object up to them. That way if the python diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs index 6f962aae92334..92043ee3f253d 100644 --- a/src/bootstrap/build/mod.rs +++ b/src/bootstrap/build/mod.rs @@ -30,6 +30,7 @@ macro_rules! t { mod cc; mod channel; +mod clean; mod compile; mod config; mod flags; @@ -122,6 +123,10 @@ impl Build { #[cfg(not(windows))] fn setup_job() {} setup_job(); + if self.flags.clean { + return clean::clean(self); + } + cc::find(self); sanity::check(self); channel::collect(self); diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 1157346d774ab..bd29fd8612d4e 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -21,3 +21,6 @@ BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py $(BOOTSTRAP_ all: $(Q)$(BOOTSTRAP) + +clean: + $(Q)$(BOOTSTRAP) --clean