Make sure to clear out the stageN-{rustc,std,tools} directories.
We copy built tool binaries into a dedicated directory to avoid deleting them, stageN-tools-bin. These aren't ever cleared out by code, since there should be no reason to do so, and we'll simply overwrite them as necessary. When clearing out the stageN-{std,rustc,tools} directories, make sure to delete both Cargo directories -- per-target and build scripts. This ensures that changing libstd doesn't cause problems due to build scripts not being rebuilt, even though they should be.
This commit is contained in:
parent
b7960878ba
commit
0fcd3e7b07
5 changed files with 72 additions and 31 deletions
|
@ -612,7 +612,7 @@ impl<'a> Builder<'a> {
|
||||||
// Set this for all builds to make sure doc builds also get it.
|
// Set this for all builds to make sure doc builds also get it.
|
||||||
cargo.env("CFG_RELEASE_CHANNEL", &self.build.config.channel);
|
cargo.env("CFG_RELEASE_CHANNEL", &self.build.config.channel);
|
||||||
|
|
||||||
if self.is_verbose() {
|
if self.is_very_verbose() {
|
||||||
cargo.arg("-v");
|
cargo.arg("-v");
|
||||||
}
|
}
|
||||||
// FIXME: cargo bench does not accept `--release`
|
// FIXME: cargo bench does not accept `--release`
|
||||||
|
|
|
@ -29,7 +29,7 @@ use build_helper::{output, mtime, up_to_date};
|
||||||
use filetime::FileTime;
|
use filetime::FileTime;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use util::{exe, libdir, is_dylib, copy};
|
use util::{exe, libdir, is_dylib, copy, read_stamp_file};
|
||||||
use {Build, Compiler, Mode};
|
use {Build, Compiler, Mode};
|
||||||
use native;
|
use native;
|
||||||
use tool;
|
use tool;
|
||||||
|
@ -102,7 +102,7 @@ impl Step for Std {
|
||||||
copy_musl_third_party_objects(build, target, &libdir);
|
copy_musl_third_party_objects(build, target, &libdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
|
let out_dir = build.stage_out(compiler, Mode::Libstd);
|
||||||
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
|
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
|
||||||
std_cargo(build, &compiler, target, &mut cargo);
|
std_cargo(build, &compiler, target, &mut cargo);
|
||||||
|
@ -354,7 +354,7 @@ impl Step for Test {
|
||||||
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
|
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
|
||||||
println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
|
println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
|
||||||
&compiler.host, target);
|
&compiler.host, target);
|
||||||
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
|
let out_dir = build.stage_out(compiler, Mode::Libtest);
|
||||||
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
|
let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
|
||||||
test_cargo(build, &compiler, target, &mut cargo);
|
test_cargo(build, &compiler, target, &mut cargo);
|
||||||
|
@ -480,8 +480,9 @@ impl Step for Rustc {
|
||||||
println!("Building stage{} compiler artifacts ({} -> {})",
|
println!("Building stage{} compiler artifacts ({} -> {})",
|
||||||
compiler.stage, &compiler.host, target);
|
compiler.stage, &compiler.host, target);
|
||||||
|
|
||||||
let out_dir = build.cargo_out(compiler, Mode::Librustc, target);
|
let stage_out = builder.stage_out(compiler, Mode::Librustc);
|
||||||
build.clear_if_dirty(&out_dir, &libtest_stamp(build, compiler, target));
|
build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target));
|
||||||
|
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
|
||||||
|
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
|
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
|
||||||
rustc_cargo(build, &compiler, target, &mut cargo);
|
rustc_cargo(build, &compiler, target, &mut cargo);
|
||||||
|
@ -757,15 +758,7 @@ impl Step for Assemble {
|
||||||
/// `sysroot_dst` provided.
|
/// `sysroot_dst` provided.
|
||||||
fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
||||||
t!(fs::create_dir_all(&sysroot_dst));
|
t!(fs::create_dir_all(&sysroot_dst));
|
||||||
let mut contents = Vec::new();
|
for path in read_stamp_file(stamp) {
|
||||||
t!(t!(File::open(stamp)).read_to_end(&mut contents));
|
|
||||||
// This is the method we use for extracting paths from the stamp file passed to us. See
|
|
||||||
// run_cargo for more information (in this file).
|
|
||||||
for part in contents.split(|b| *b == 0) {
|
|
||||||
if part.is_empty() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let path = Path::new(t!(str::from_utf8(part)));
|
|
||||||
copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
|
copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -938,6 +931,8 @@ fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
||||||
let max = max.unwrap();
|
let max = max.unwrap();
|
||||||
let max_path = max_path.unwrap();
|
let max_path = max_path.unwrap();
|
||||||
if stamp_contents == new_contents && max <= stamp_mtime {
|
if stamp_contents == new_contents && max <= stamp_mtime {
|
||||||
|
build.verbose(&format!("not updating {:?}; contents equal and {} <= {}",
|
||||||
|
stamp, max, stamp_mtime));
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if max > stamp_mtime {
|
if max > stamp_mtime {
|
||||||
|
|
|
@ -385,16 +385,19 @@ impl Build {
|
||||||
/// Clear out `dir` if `input` is newer.
|
/// Clear out `dir` if `input` is newer.
|
||||||
///
|
///
|
||||||
/// After this executes, it will also ensure that `dir` exists.
|
/// After this executes, it will also ensure that `dir` exists.
|
||||||
fn clear_if_dirty(&self, dir: &Path, input: &Path) {
|
fn clear_if_dirty(&self, dir: &Path, input: &Path) -> bool {
|
||||||
let stamp = dir.join(".stamp");
|
let stamp = dir.join(".stamp");
|
||||||
|
let mut cleared = false;
|
||||||
if mtime(&stamp) < mtime(input) {
|
if mtime(&stamp) < mtime(input) {
|
||||||
self.verbose(&format!("Dirty - {}", dir.display()));
|
self.verbose(&format!("Dirty - {}", dir.display()));
|
||||||
let _ = fs::remove_dir_all(dir);
|
let _ = fs::remove_dir_all(dir);
|
||||||
|
cleared = true;
|
||||||
} else if stamp.exists() {
|
} else if stamp.exists() {
|
||||||
return
|
return cleared;
|
||||||
}
|
}
|
||||||
t!(fs::create_dir_all(dir));
|
t!(fs::create_dir_all(dir));
|
||||||
t!(File::create(stamp));
|
t!(File::create(stamp));
|
||||||
|
cleared
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the space-separated set of activated features for the standard
|
/// Get the space-separated set of activated features for the standard
|
||||||
|
@ -435,6 +438,12 @@ impl Build {
|
||||||
if self.config.rust_optimize {"release"} else {"debug"}
|
if self.config.rust_optimize {"release"} else {"debug"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tools_dir(&self, compiler: Compiler) -> PathBuf {
|
||||||
|
let out = self.out.join(&*compiler.host).join(format!("stage{}-tools-bin", compiler.stage));
|
||||||
|
t!(fs::create_dir_all(&out));
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the directory for incremental by-products when using the
|
/// Get the directory for incremental by-products when using the
|
||||||
/// given compiler.
|
/// given compiler.
|
||||||
fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
|
fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
|
||||||
|
|
|
@ -38,24 +38,40 @@ impl Step for CleanTools {
|
||||||
run.never()
|
run.never()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a tool in `src/tools`
|
|
||||||
///
|
|
||||||
/// This will build the specified tool with the specified `host` compiler in
|
|
||||||
/// `stage` into the normal cargo output directory.
|
|
||||||
fn run(self, builder: &Builder) {
|
fn run(self, builder: &Builder) {
|
||||||
let build = builder.build;
|
let build = builder.build;
|
||||||
let compiler = self.compiler;
|
let compiler = self.compiler;
|
||||||
let target = self.target;
|
let target = self.target;
|
||||||
let mode = self.mode;
|
let mode = self.mode;
|
||||||
|
|
||||||
let stamp = match mode {
|
// This is for the original compiler, but if we're forced to use stage 1, then
|
||||||
Mode::Libstd => libstd_stamp(build, compiler, target),
|
// std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
|
||||||
Mode::Libtest => libtest_stamp(build, compiler, target),
|
// we copy the libs forward.
|
||||||
Mode::Librustc => librustc_stamp(build, compiler, target),
|
let tools_dir = build.stage_out(compiler, Mode::Tool);
|
||||||
_ => panic!(),
|
let compiler = if builder.force_use_stage1(compiler, target) {
|
||||||
|
builder.compiler(1, compiler.host)
|
||||||
|
} else {
|
||||||
|
compiler
|
||||||
};
|
};
|
||||||
let out_dir = build.cargo_out(compiler, Mode::Tool, target);
|
|
||||||
build.clear_if_dirty(&out_dir, &stamp);
|
for &cur_mode in &[Mode::Libstd, Mode::Libtest, Mode::Librustc] {
|
||||||
|
let stamp = match cur_mode {
|
||||||
|
Mode::Libstd => libstd_stamp(build, compiler, target),
|
||||||
|
Mode::Libtest => libtest_stamp(build, compiler, target),
|
||||||
|
Mode::Librustc => librustc_stamp(build, compiler, target),
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if build.clear_if_dirty(&tools_dir, &stamp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we are a rustc tool, and std changed, we also need to clear ourselves out -- our
|
||||||
|
// dependencies depend on std. Therefore, we iterate up until our own mode.
|
||||||
|
if mode == cur_mode {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +116,11 @@ impl Step for ToolBuild {
|
||||||
|
|
||||||
let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
|
let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
|
||||||
build.run_expecting(&mut cargo, expectation);
|
build.run_expecting(&mut cargo, expectation);
|
||||||
build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host))
|
let cargo_out = build.cargo_out(compiler, Mode::Tool, target)
|
||||||
|
.join(exe(tool, &compiler.host));
|
||||||
|
let bin = build.tools_dir(compiler).join(exe(tool, &compiler.host));
|
||||||
|
copy(&cargo_out, &bin);
|
||||||
|
bin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
//! not a lot of interesting happenings here unfortunately.
|
//! not a lot of interesting happenings here unfortunately.
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::str;
|
||||||
use std::io::{self, Write};
|
use std::fs::{self, File};
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::time::{SystemTime, Instant};
|
use std::time::{SystemTime, Instant};
|
||||||
|
@ -50,6 +51,22 @@ pub fn copy(src: &Path, dst: &Path) {
|
||||||
t!(filetime::set_file_times(dst, atime, mtime));
|
t!(filetime::set_file_times(dst, atime, mtime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_stamp_file(stamp: &Path) -> Vec<PathBuf> {
|
||||||
|
let mut paths = Vec::new();
|
||||||
|
let mut contents = Vec::new();
|
||||||
|
t!(t!(File::open(stamp)).read_to_end(&mut contents));
|
||||||
|
// This is the method we use for extracting paths from the stamp file passed to us. See
|
||||||
|
// run_cargo for more information (in compile.rs).
|
||||||
|
for part in contents.split(|b| *b == 0) {
|
||||||
|
if part.is_empty() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
let path = PathBuf::from(t!(str::from_utf8(part)));
|
||||||
|
paths.push(path);
|
||||||
|
}
|
||||||
|
paths
|
||||||
|
}
|
||||||
|
|
||||||
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
|
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
|
||||||
/// when this function is called.
|
/// when this function is called.
|
||||||
pub fn cp_r(src: &Path, dst: &Path) {
|
pub fn cp_r(src: &Path, dst: &Path) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue