Skip to content

Commit 3ee6036

Browse files
authored
Rollup merge of rust-lang#63470 - Mark-Simulacrum:rustc-depdep, r=alexcrichton
Utilize -Zbinary-dep-depinfo in rustbuild The last commit moves us over to using binary-dep-depinfo while the first two permit us to bootstrap from what will become future beta, to be released in the next week (it's the `cfg(bootstrap)` processing). We no longer utilize stamp-file mtimes at all inside rustbuild, and a future PR may be able to entirely eliminate them by eagerly copying to the appropriate sysroot. The only mtime-based dependency tracking left is for documentation because we lie to Cargo about the rustdoc binary, so Cargo does not track changes to the real binary, and codegen-backends because binary-dep-depinfo does not emit that information into the depfiles. Both of these are fixable in the longer term but this existing patch gives us the following benefits: * We no longer delete Cargo target directories manually within a stage. Cross-stage, changes to codegen backends will still clear out target directories. This means that incremental state persists across individual steps (e.g., rebuilding libstd does not clear out librustc incremental state). Fixes rust-lang#54712. * Dependency tracking across steps within a given stage is now fully precise. We will not clear out all codegen backend dependencies due to changes in librustc_driver, for example, only deleting the final librustc_codegen_llvm crate. Fixes rust-lang#54008, fixes rust-lang#50481. * We properly track codegen backends as a dependency (equivalent to rustc) across changes. Fixes rust-lang#53284, and fixes rust-lang#52719. * Cross-stage dependency tracking of crates is also much more accurate and reliable. Most likely fixes rust-lang#49979 (but no reproduction steps in that issue). Fixes rust-lang#59105. cc rust-lang#63012
2 parents acf2315 + 417f9ea commit 3ee6036

File tree

3 files changed

+23
-100
lines changed

3 files changed

+23
-100
lines changed

src/bootstrap/builder.rs

+22-65
Original file line numberDiff line numberDiff line change
@@ -754,76 +754,20 @@ impl<'a> Builder<'a> {
754754
let mut cargo = Command::new(&self.initial_cargo);
755755
let out_dir = self.stage_out(compiler, mode);
756756

757-
// command specific path, we call clear_if_dirty with this
758-
let mut my_out = match cmd {
759-
"build" => self.cargo_out(compiler, mode, target),
760-
761-
// This is the intended out directory for crate documentation.
762-
"doc" | "rustdoc" => self.crate_doc_out(target),
763-
764-
_ => self.stage_out(compiler, mode),
765-
};
766-
767-
// This is for the original compiler, but if we're forced to use stage 1, then
768-
// std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
769-
// we copy the libs forward.
770-
let cmp = self.compiler_for(compiler.stage, compiler.host, target);
771-
772-
let libstd_stamp = match cmd {
773-
"check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
774-
_ => compile::libstd_stamp(self, cmp, target),
775-
};
776-
777-
let libtest_stamp = match cmd {
778-
"check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
779-
_ => compile::libtest_stamp(self, cmp, target),
780-
};
781-
782-
let librustc_stamp = match cmd {
783-
"check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
784-
_ => compile::librustc_stamp(self, cmp, target),
785-
};
757+
// Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
758+
// so we need to explicitly clear out if they've been updated.
759+
for backend in self.codegen_backends(compiler) {
760+
self.clear_if_dirty(&out_dir, &backend);
761+
}
786762

787763
if cmd == "doc" || cmd == "rustdoc" {
788-
if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen {
764+
let my_out = match mode {
789765
// This is the intended out directory for compiler documentation.
790-
my_out = self.compiler_doc_out(target);
791-
}
766+
Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
767+
_ => self.crate_doc_out(target),
768+
};
792769
let rustdoc = self.rustdoc(compiler);
793770
self.clear_if_dirty(&my_out, &rustdoc);
794-
} else if cmd != "test" {
795-
match mode {
796-
Mode::Std => {
797-
self.clear_if_dirty(&my_out, &self.rustc(compiler));
798-
for backend in self.codegen_backends(compiler) {
799-
self.clear_if_dirty(&my_out, &backend);
800-
}
801-
},
802-
Mode::Test => {
803-
self.clear_if_dirty(&my_out, &libstd_stamp);
804-
},
805-
Mode::Rustc => {
806-
self.clear_if_dirty(&my_out, &self.rustc(compiler));
807-
self.clear_if_dirty(&my_out, &libstd_stamp);
808-
self.clear_if_dirty(&my_out, &libtest_stamp);
809-
},
810-
Mode::Codegen => {
811-
self.clear_if_dirty(&my_out, &librustc_stamp);
812-
},
813-
Mode::ToolBootstrap => { },
814-
Mode::ToolStd => {
815-
self.clear_if_dirty(&my_out, &libstd_stamp);
816-
},
817-
Mode::ToolTest => {
818-
self.clear_if_dirty(&my_out, &libstd_stamp);
819-
self.clear_if_dirty(&my_out, &libtest_stamp);
820-
},
821-
Mode::ToolRustc => {
822-
self.clear_if_dirty(&my_out, &libstd_stamp);
823-
self.clear_if_dirty(&my_out, &libtest_stamp);
824-
self.clear_if_dirty(&my_out, &librustc_stamp);
825-
},
826-
}
827771
}
828772

829773
cargo
@@ -861,6 +805,19 @@ impl<'a> Builder<'a> {
861805
},
862806
}
863807

808+
// This tells Cargo (and in turn, rustc) to output more complete
809+
// dependency information. Most importantly for rustbuild, this
810+
// includes sysroot artifacts, like libstd, which means that we don't
811+
// need to track those in rustbuild (an error prone process!). This
812+
// feature is currently unstable as there may be some bugs and such, but
813+
// it represents a big improvement in rustbuild's reliability on
814+
// rebuilds, so we're using it here.
815+
//
816+
// For some additional context, see #63470 (the PR originally adding
817+
// this), as well as #63012 which is the tracking issue for this
818+
// feature on the rustc side.
819+
cargo.arg("-Zbinary-dep-depinfo");
820+
864821
cargo.arg("-j").arg(self.jobs().to_string());
865822
// Remove make-related flags to ensure Cargo can correctly set things up
866823
cargo.env_remove("MAKEFLAGS");

src/bootstrap/check.rs

-1
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ impl Step for Rustdoc {
245245
let libdir = builder.sysroot_libdir(compiler, target);
246246
let hostdir = builder.sysroot_libdir(compiler, compiler.host);
247247
add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
248-
builder.cargo(compiler, Mode::ToolRustc, target, "clean");
249248
}
250249
}
251250

src/bootstrap/compile.rs

+1-34
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
1515
use std::process::{Command, Stdio, exit};
1616
use std::str;
1717

18-
use build_helper::{output, mtime, t, up_to_date};
18+
use build_helper::{output, t, up_to_date};
1919
use filetime::FileTime;
2020
use serde::Deserialize;
2121
use serde_json;
@@ -274,8 +274,6 @@ impl Step for StdLink {
274274
// for reason why the sanitizers are not built in stage0.
275275
copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir);
276276
}
277-
278-
builder.cargo(target_compiler, Mode::ToolStd, target, "clean");
279277
}
280278
}
281279

@@ -480,8 +478,6 @@ impl Step for TestLink {
480478
&builder.sysroot_libdir(target_compiler, compiler.host),
481479
&libtest_stamp(builder, compiler, target)
482480
);
483-
484-
builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
485481
}
486482
}
487483

@@ -639,7 +635,6 @@ impl Step for RustcLink {
639635
&builder.sysroot_libdir(target_compiler, compiler.host),
640636
&librustc_stamp(builder, compiler, target)
641637
);
642-
builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
643638
}
644639
}
645640

@@ -1202,41 +1197,13 @@ pub fn run_cargo(builder: &Builder<'_>,
12021197
deps.push((path_to_add.into(), false));
12031198
}
12041199

1205-
// Now we want to update the contents of the stamp file, if necessary. First
1206-
// we read off the previous contents along with its mtime. If our new
1207-
// contents (the list of files to copy) is different or if any dep's mtime
1208-
// is newer then we rewrite the stamp file.
12091200
deps.sort();
1210-
let stamp_contents = fs::read(stamp);
1211-
let stamp_mtime = mtime(&stamp);
12121201
let mut new_contents = Vec::new();
1213-
let mut max = None;
1214-
let mut max_path = None;
12151202
for (dep, proc_macro) in deps.iter() {
1216-
let mtime = mtime(dep);
1217-
if Some(mtime) > max {
1218-
max = Some(mtime);
1219-
max_path = Some(dep.clone());
1220-
}
12211203
new_contents.extend(if *proc_macro { b"h" } else { b"t" });
12221204
new_contents.extend(dep.to_str().unwrap().as_bytes());
12231205
new_contents.extend(b"\0");
12241206
}
1225-
let max = max.unwrap();
1226-
let max_path = max_path.unwrap();
1227-
let contents_equal = stamp_contents
1228-
.map(|contents| contents == new_contents)
1229-
.unwrap_or_default();
1230-
if contents_equal && max <= stamp_mtime {
1231-
builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
1232-
stamp, max, stamp_mtime));
1233-
return deps.into_iter().map(|(d, _)| d).collect()
1234-
}
1235-
if max > stamp_mtime {
1236-
builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
1237-
} else {
1238-
builder.verbose(&format!("updating {:?} as deps changed", stamp));
1239-
}
12401207
t!(fs::write(&stamp, &new_contents));
12411208
deps.into_iter().map(|(d, _)| d).collect()
12421209
}

0 commit comments

Comments
 (0)