Skip to content

Commit 44bcde2

Browse files
committed
Refactor Rustdoc
1 parent e932c98 commit 44bcde2

File tree

3 files changed

+90
-96
lines changed

3 files changed

+90
-96
lines changed

src/bootstrap/src/core/build_steps/tool.rs

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -681,15 +681,21 @@ impl Step for RemoteTestServer {
681681
}
682682
}
683683

684-
#[derive(Debug, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
684+
/// Represents `Rustdoc` that either comes from the external stage0 sysroot or that is built
685+
/// locally.
686+
/// Rustdoc is special, because it both essentially corresponds to a `Compiler` (that can be
687+
/// externally provided), but also to a `ToolRustc` tool.
688+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
685689
pub struct Rustdoc {
686-
/// This should only ever be 0 or 2.
687-
/// We sometimes want to reference the "bootstrap" rustdoc, which is why this option is here.
690+
/// If the stage of `target_compiler` is `0`, then rustdoc is externally provided.
691+
/// Otherwise it is built locally.
688692
pub target_compiler: Compiler,
689693
}
690694

691695
impl Step for Rustdoc {
692-
type Output = ToolBuildResult;
696+
/// Path to the built rustdoc binary.
697+
type Output = PathBuf;
698+
693699
const DEFAULT: bool = true;
694700
const ONLY_HOSTS: bool = true;
695701

@@ -703,21 +709,20 @@ impl Step for Rustdoc {
703709
});
704710
}
705711

706-
fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
712+
fn run(self, builder: &Builder<'_>) -> Self::Output {
707713
let target_compiler = self.target_compiler;
708714
let target = target_compiler.host;
709715

716+
// If stage is 0, we use a prebuilt rustdoc from stage0
710717
if target_compiler.stage == 0 {
711718
if !target_compiler.is_snapshot(builder) {
712719
panic!("rustdoc in stage 0 must be snapshot rustdoc");
713720
}
714721

715-
return ToolBuildResult {
716-
tool_path: builder.initial_rustdoc.clone(),
717-
build_compiler: target_compiler,
718-
};
722+
return builder.initial_rustdoc.clone();
719723
}
720724

725+
// If stage is higher, we build rustdoc instead
721726
let bin_rustdoc = || {
722727
let sysroot = builder.sysroot(target_compiler);
723728
let bindir = sysroot.join("bin");
@@ -729,10 +734,7 @@ impl Step for Rustdoc {
729734

730735
// If CI rustc is enabled and we haven't modified the rustdoc sources,
731736
// use the precompiled rustdoc from CI rustc's sysroot to speed up bootstrapping.
732-
if builder.download_rustc()
733-
&& target_compiler.stage > 0
734-
&& builder.rust_info().is_managed_git_subrepository()
735-
{
737+
if builder.download_rustc() && builder.rust_info().is_managed_git_subrepository() {
736738
let files_to_track = &["src/librustdoc", "src/tools/rustdoc", "src/rustdoc-json-types"];
737739

738740
// Check if unchanged
@@ -745,8 +747,7 @@ impl Step for Rustdoc {
745747

746748
let bin_rustdoc = bin_rustdoc();
747749
builder.copy_link(&precompiled_rustdoc, &bin_rustdoc, FileType::Executable);
748-
749-
return ToolBuildResult { tool_path: bin_rustdoc, build_compiler: target_compiler };
750+
return bin_rustdoc;
750751
}
751752
}
752753

@@ -762,45 +763,39 @@ impl Step for Rustdoc {
762763
extra_features.push("jemalloc".to_string());
763764
}
764765

765-
let ToolBuildResult { tool_path, build_compiler } = builder.ensure(ToolBuild {
766-
build_compiler: target_compiler,
767-
target,
768-
// Cargo adds a number of paths to the dylib search path on windows, which results in
769-
// the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
770-
// rustdoc a different name.
771-
tool: "rustdoc_tool_binary",
772-
mode: Mode::ToolRustc,
773-
path: "src/tools/rustdoc",
774-
source_type: SourceType::InTree,
775-
extra_features,
776-
allow_features: "",
777-
cargo_args: Vec::new(),
778-
artifact_kind: ToolArtifactKind::Binary,
779-
});
780-
781-
// FIXME: handle the build/target compiler split here somehow
782-
// don't create a stage0-sysroot/bin directory.
783-
if target_compiler.stage > 0 {
784-
if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None {
785-
// Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into
786-
// our final binaries
787-
compile::strip_debug(builder, target, &tool_path);
788-
}
789-
let bin_rustdoc = bin_rustdoc();
790-
builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable);
791-
ToolBuildResult { tool_path: bin_rustdoc, build_compiler }
792-
} else {
793-
ToolBuildResult { tool_path, build_compiler }
766+
let compilers = RustcPrivateCompilers::from_link_compiler(builder, target_compiler);
767+
let tool_path = builder
768+
.ensure(ToolBuild {
769+
build_compiler: compilers.build_compiler,
770+
target,
771+
// Cargo adds a number of paths to the dylib search path on windows, which results in
772+
// the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
773+
// rustdoc a different name.
774+
tool: "rustdoc_tool_binary",
775+
mode: Mode::ToolRustc,
776+
path: "src/tools/rustdoc",
777+
source_type: SourceType::InTree,
778+
extra_features,
779+
allow_features: "",
780+
cargo_args: Vec::new(),
781+
artifact_kind: ToolArtifactKind::Binary,
782+
})
783+
.tool_path;
784+
785+
if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None {
786+
// Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into
787+
// our final binaries
788+
compile::strip_debug(builder, target, &tool_path);
794789
}
790+
let bin_rustdoc = bin_rustdoc();
791+
builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable);
792+
bin_rustdoc
795793
}
796794

797795
fn metadata(&self) -> Option<StepMetadata> {
798796
Some(
799797
StepMetadata::build("rustdoc", self.target_compiler.host)
800-
// rustdoc is ToolRustc, so stage N rustdoc is built by stage N-1 rustc
801-
// FIXME: make this stage deduction automatic somehow
802-
// FIXME: log the compiler that actually built ToolRustc steps
803-
.stage(self.target_compiler.stage.saturating_sub(1)),
798+
.stage(self.target_compiler.stage),
804799
)
805800
}
806801
}
@@ -1317,18 +1312,11 @@ impl RustcPrivateCompilers {
13171312
/// Create compilers for a `rustc_private` tool with the given `stage` and for the given
13181313
/// `target`.
13191314
pub fn new(builder: &Builder<'_>, stage: u32, target: TargetSelection) -> Self {
1320-
assert!(stage > 0);
1321-
1322-
let build_compiler = if builder.download_rustc() && stage == 1 {
1323-
// We shouldn't drop to stage0 compiler when using CI rustc.
1324-
builder.compiler(1, builder.config.host_target)
1325-
} else {
1326-
builder.compiler(stage - 1, builder.config.host_target)
1327-
};
1315+
let build_compiler = Self::build_compiler_from_stage(builder, stage);
13281316

13291317
// This is the compiler we'll link to
13301318
// FIXME: make 100% sure that `link_compiler` was indeed built with `build_compiler`...
1331-
let link_compiler = builder.compiler(stage, target);
1319+
let link_compiler = builder.compiler(build_compiler.stage + 1, target);
13321320

13331321
Self { build_compiler, link_compiler }
13341322
}
@@ -1343,6 +1331,25 @@ impl RustcPrivateCompilers {
13431331
Self { build_compiler, link_compiler }
13441332
}
13451333

1334+
/// Create rustc tool compilers from the link compiler.
1335+
pub fn from_link_compiler(builder: &Builder<'_>, link_compiler: Compiler) -> Self {
1336+
Self {
1337+
build_compiler: Self::build_compiler_from_stage(builder, link_compiler.stage),
1338+
link_compiler,
1339+
}
1340+
}
1341+
1342+
fn build_compiler_from_stage(builder: &Builder<'_>, stage: u32) -> Compiler {
1343+
assert!(stage > 0);
1344+
1345+
if builder.download_rustc() && stage == 1 {
1346+
// We shouldn't drop to stage0 compiler when using CI rustc.
1347+
builder.compiler(1, builder.config.host_target)
1348+
} else {
1349+
builder.compiler(stage - 1, builder.config.host_target)
1350+
}
1351+
}
1352+
13461353
pub fn build_compiler(&self) -> Compiler {
13471354
self.build_compiler
13481355
}

src/bootstrap/src/core/builder/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1539,7 +1539,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
15391539
/// It can be either a stage0 rustdoc or a locally built rustdoc that *links* to
15401540
/// `target_compiler`.
15411541
pub fn rustdoc_for_compiler(&self, target_compiler: Compiler) -> PathBuf {
1542-
self.ensure(tool::Rustdoc { target_compiler }).tool_path
1542+
self.ensure(tool::Rustdoc { target_compiler })
15431543
}
15441544

15451545
pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> BootstrapCommand {

0 commit comments

Comments
 (0)