From ff2f7c5bd18018418a4f995f30a71698cdbc6e94 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 28 Jul 2017 12:28:28 -0600 Subject: [PATCH] Build rustdoc only at the topmost stage. This effectively ensures that rustdoc will only ever be built once for any given host. This does not introduce cycles into the build since we only depend on rustdoc from documentation or test steps, which run after the required compiler was built. --- src/bootstrap/bin/rustdoc.rs | 2 +- src/bootstrap/builder.rs | 21 ++++++++++----------- src/bootstrap/check.rs | 6 +++--- src/bootstrap/dist.rs | 3 +-- src/bootstrap/doc.rs | 12 ++++++------ src/bootstrap/tool.rs | 16 +++++++++------- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index d7d72d5dd56c9..38ad2515d95ab 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -24,7 +24,7 @@ fn main() { let args = env::args_os().skip(1).collect::>(); let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set"); let libdir = env::var_os("RUSTC_LIBDIR").expect("RUSTC_LIBDIR was not set"); - let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); + let stage = env::var("RUSTDOC_STAGE").expect("RUSTDOC_STAGE was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); let mut dylib_path = bootstrap::util::dylib_path(); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 2f6e3ca9253f8..01b2623b15f3b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -412,22 +412,20 @@ impl<'a> Builder<'a> { } } - pub fn rustdoc(&self, compiler: Compiler) -> PathBuf { - self.ensure(tool::Rustdoc { target_compiler: compiler }) + pub fn rustdoc(&self, host: Interned) -> PathBuf { + self.ensure(tool::Rustdoc { host }) } - pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command { + pub fn rustdoc_cmd(&self, host: Interned) -> Command { let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc")); + // See rational for top_stage in rustdoc + let compiler = self.compiler(self.top_stage, host); cmd - .env("RUSTC_STAGE", compiler.stage.to_string()) - .env("RUSTC_SYSROOT", if compiler.is_snapshot(&self.build) { - INTERNER.intern_path(self.build.rustc_snapshot_libdir()) - } else { - self.sysroot(compiler) - }) + .env("RUSTDOC_STAGE", compiler.stage.to_string()) + .env("RUSTC_SYSROOT", self.sysroot(compiler)) .env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build)) .env("CFG_RELEASE_CHANNEL", &self.build.config.channel) - .env("RUSTDOC_REAL", self.rustdoc(compiler)); + .env("RUSTDOC_REAL", self.rustdoc(compiler.host)); cmd } @@ -480,8 +478,9 @@ impl<'a> Builder<'a> { .env("RUSTC_LIBDIR", self.rustc_libdir(compiler)) .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) + .env("RUSTDOC_STAGE", self.top_stage.to_string()) .env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" { - self.rustdoc(compiler) + self.rustdoc(compiler.host) } else { PathBuf::from("/path/to/nowhere/rustdoc/not/required") }) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index b04e4de774453..2c17423077855 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -164,7 +164,7 @@ impl Step for Cargotest { try_run(build, cmd.arg(&build.initial_cargo) .arg(&out_dir) .env("RUSTC", builder.rustc(compiler)) - .env("RUSTDOC", builder.rustdoc(compiler))); + .env("RUSTDOC", builder.rustdoc(compiler.host))); } } @@ -565,7 +565,7 @@ impl Step for Compiletest { // Avoid depending on rustdoc when we don't need it. if mode == "rustdoc" || mode == "run-make" { - cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler)); + cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host)); } cmd.arg("--src-base").arg(build.src.join("src/test").join(suite)); @@ -814,7 +814,7 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) { } println!("doc tests for: {}", markdown.display()); - let mut cmd = builder.rustdoc_cmd(compiler); + let mut cmd = builder.rustdoc_cmd(compiler.host); build.add_rust_test_threads(&mut cmd); cmd.arg("--test"); cmd.arg(markdown); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c322d75dd5b45..c8fb02daa83d6 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -413,8 +413,7 @@ impl Step for Rustc { t!(fs::create_dir_all(image.join("bin"))); cp_r(&src.join("bin"), &image.join("bin")); - install(&builder.ensure(tool::Rustdoc { target_compiler: compiler }), - &image.join("bin"), 0o755); + install(&builder.rustdoc(compiler.host), &image.join("bin"), 0o755); // Copy runtime DLLs needed by the compiler if libdir != "bin" { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 1ee578bb62b19..f0e0874abed60 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -260,7 +260,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned, } impl Step for Rustdoc { @@ -240,30 +240,32 @@ impl Step for Rustdoc { fn make_run(run: RunConfig) { run.builder.ensure(Rustdoc { - target_compiler: run.builder.compiler(run.builder.top_stage, run.host), + host: run.host, }); } fn run(self, builder: &Builder) -> PathBuf { - let target_compiler = self.target_compiler; - let build_compiler = if target_compiler.stage == 0 { + // Always build rustdoc at the top stage; otherwise we rebuild it twice (or more). + let stage = builder.top_stage; + let build_compiler = if stage == 0 { builder.compiler(0, builder.build.build) } else { // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise // we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage // compilers, which isn't what we want. - builder.compiler(target_compiler.stage - 1, builder.build.build) + builder.compiler(stage - 1, builder.build.build) }; let tool_rustdoc = builder.ensure(ToolBuild { compiler: build_compiler, - target: target_compiler.host, + target: self.host, tool: "rustdoc", mode: Mode::Librustc, }); // don't create a stage0-sysroot/bin directory. - if target_compiler.stage > 0 { + if stage > 0 { + let target_compiler = builder.compiler(build_compiler.stage + 1, self.host); let sysroot = builder.sysroot(target_compiler); let bindir = sysroot.join("bin"); t!(fs::create_dir_all(&bindir));