Skip to content

Commit 311814a

Browse files
authored
Rollup merge of rust-lang#49193 - davidtwco:issue-29893, r=alexcrichton
Host compiler documentation Fixes rust-lang#29893. Rust Central Station PR: rust-lang/rust-central-station#40 r? @alexcrichton
2 parents 8d57071 + 73fa6d5 commit 311814a

File tree

5 files changed

+202
-45
lines changed

5 files changed

+202
-45
lines changed

src/bootstrap/builder.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -321,11 +321,13 @@ impl<'a> Builder<'a> {
321321
test::RunMake),
322322
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
323323
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
324-
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
325-
doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook),
326-
Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts,
327-
dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo,
328-
dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign),
324+
doc::Standalone, doc::Std, doc::Test, doc::WhitelistedRustc, doc::Rustc,
325+
doc::ErrorIndex, doc::Nomicon, doc::Reference, doc::Rustdoc, doc::RustByExample,
326+
doc::CargoBook),
327+
Kind::Dist => describe!(dist::Docs, dist::RustcDocs, dist::Mingw, dist::Rustc,
328+
dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src,
329+
dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Rustfmt, dist::Extended,
330+
dist::HashSign),
329331
Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls,
330332
install::Rustfmt, install::Analysis, install::Src, install::Rustc),
331333
}

src/bootstrap/dist.rs

+62-7
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl Step for Docs {
102102

103103
let dst = image.join("share/doc/rust/html");
104104
t!(fs::create_dir_all(&dst));
105-
let src = build.out.join(host).join("doc");
105+
let src = build.doc_out(host);
106106
cp_r(&src, &dst);
107107

108108
let mut cmd = rust_installer(builder);
@@ -120,14 +120,69 @@ impl Step for Docs {
120120
build.run(&mut cmd);
121121
t!(fs::remove_dir_all(&image));
122122

123-
// As part of this step, *also* copy the docs directory to a directory which
124-
// buildbot typically uploads.
125-
if host == build.build {
126-
let dst = distdir(build).join("doc").join(build.rust_package_vers());
127-
t!(fs::create_dir_all(&dst));
128-
cp_r(&src, &dst);
123+
distdir(build).join(format!("{}-{}.tar.gz", name, host))
124+
}
125+
}
126+
127+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
128+
pub struct RustcDocs {
129+
pub stage: u32,
130+
pub host: Interned<String>,
131+
}
132+
133+
impl Step for RustcDocs {
134+
type Output = PathBuf;
135+
const DEFAULT: bool = true;
136+
137+
fn should_run(run: ShouldRun) -> ShouldRun {
138+
run.path("src/librustc")
139+
}
140+
141+
fn make_run(run: RunConfig) {
142+
run.builder.ensure(RustcDocs {
143+
stage: run.builder.top_stage,
144+
host: run.target,
145+
});
146+
}
147+
148+
/// Builds the `rustc-docs` installer component.
149+
fn run(self, builder: &Builder) -> PathBuf {
150+
let build = builder.build;
151+
let host = self.host;
152+
153+
let name = pkgname(build, "rustc-docs");
154+
155+
println!("Dist compiler docs ({})", host);
156+
if !build.config.compiler_docs {
157+
println!("\tskipping - compiler docs disabled");
158+
return distdir(build).join(format!("{}-{}.tar.gz", name, host));
129159
}
130160

161+
builder.default_doc(None);
162+
163+
let image = tmpdir(build).join(format!("{}-{}-image", name, host));
164+
let _ = fs::remove_dir_all(&image);
165+
166+
let dst = image.join("share/doc/rust/html");
167+
t!(fs::create_dir_all(&dst));
168+
let src = build.compiler_doc_out(host);
169+
cp_r(&src, &dst);
170+
171+
let mut cmd = rust_installer(builder);
172+
cmd.arg("generate")
173+
.arg("--product-name=Rustc-Documentation")
174+
.arg("--rel-manifest-dir=rustlib")
175+
.arg("--success-message=Rustc-documentation-is-installed.")
176+
.arg("--image-dir").arg(&image)
177+
.arg("--work-dir").arg(&tmpdir(build))
178+
.arg("--output-dir").arg(&distdir(build))
179+
.arg(format!("--package-name={}-{}", name, host))
180+
.arg("--component-name=rustc-docs")
181+
.arg("--legacy-manifest-dirs=rustlib,cargo")
182+
.arg("--bulk-dirs=share/doc/rust/html");
183+
build.run(&mut cmd);
184+
t!(fs::remove_dir_all(&image));
185+
131186
distdir(build).join(format!("{}-{}.tar.gz", name, host))
132187
}
133188
}

src/bootstrap/doc.rs

+126-32
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
//! Everything here is basically just a shim around calling either `rustbook` or
1818
//! `rustdoc`.
1919
20+
use std::collections::HashSet;
2021
use std::fs::{self, File};
2122
use std::io::prelude::*;
2223
use std::io;
2324
use std::path::{PathBuf, Path};
2425

25-
use Mode;
26+
use {Build, Mode};
2627
use build_helper::up_to_date;
2728

2829
use util::{cp_r, symlink_dir};
@@ -483,21 +484,17 @@ impl Step for Std {
483484
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc");
484485
compile::std_cargo(builder, &compiler, target, &mut cargo);
485486

486-
// We don't want to build docs for internal std dependencies unless
487-
// in compiler-docs mode. When not in that mode, we whitelist the crates
488-
// for which docs must be built.
489-
if !build.config.compiler_docs {
490-
cargo.arg("--no-deps");
491-
for krate in &["alloc", "core", "std", "std_unicode"] {
492-
cargo.arg("-p").arg(krate);
493-
// Create all crate output directories first to make sure rustdoc uses
494-
// relative links.
495-
// FIXME: Cargo should probably do this itself.
496-
t!(fs::create_dir_all(out_dir.join(krate)));
497-
}
487+
// Keep a whitelist so we do not build internal stdlib crates, these will be
488+
// build by the rustc step later if enabled.
489+
cargo.arg("--no-deps");
490+
for krate in &["alloc", "core", "std", "std_unicode"] {
491+
cargo.arg("-p").arg(krate);
492+
// Create all crate output directories first to make sure rustdoc uses
493+
// relative links.
494+
// FIXME: Cargo should probably do this itself.
495+
t!(fs::create_dir_all(out_dir.join(krate)));
498496
}
499497

500-
501498
build.run(&mut cargo);
502499
cp_r(&my_out, &out);
503500
}
@@ -564,12 +561,12 @@ impl Step for Test {
564561
}
565562

566563
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
567-
pub struct Rustc {
564+
pub struct WhitelistedRustc {
568565
stage: u32,
569566
target: Interned<String>,
570567
}
571568

572-
impl Step for Rustc {
569+
impl Step for WhitelistedRustc {
573570
type Output = ();
574571
const DEFAULT: bool = true;
575572
const ONLY_HOSTS: bool = true;
@@ -580,21 +577,26 @@ impl Step for Rustc {
580577
}
581578

582579
fn make_run(run: RunConfig) {
583-
run.builder.ensure(Rustc {
580+
run.builder.ensure(WhitelistedRustc {
584581
stage: run.builder.top_stage,
585582
target: run.target,
586583
});
587584
}
588585

589-
/// Generate all compiler documentation.
586+
/// Generate whitelisted compiler crate documentation.
590587
///
591-
/// This will generate all documentation for the compiler libraries and their
592-
/// dependencies. This is largely just a wrapper around `cargo doc`.
588+
/// This will generate all documentation for crates that are whitelisted
589+
/// to be included in the standard documentation. This documentation is
590+
/// included in the standard Rust documentation, so we should always
591+
/// document it and symlink to merge with the rest of the std and test
592+
/// documentation. We don't build other compiler documentation
593+
/// here as we want to be able to keep it separate from the standard
594+
/// documentation. This is largely just a wrapper around `cargo doc`.
593595
fn run(self, builder: &Builder) {
594596
let build = builder.build;
595597
let stage = self.stage;
596598
let target = self.target;
597-
println!("Documenting stage{} compiler ({})", stage, target);
599+
println!("Documenting stage{} whitelisted compiler ({})", stage, target);
598600
let out = build.doc_out(target);
599601
t!(fs::create_dir_all(&out));
600602
let compiler = builder.compiler(stage, build.build);
@@ -620,24 +622,116 @@ impl Step for Rustc {
620622
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
621623
compile::rustc_cargo(build, &mut cargo);
622624

623-
if build.config.compiler_docs {
624-
// src/rustc/Cargo.toml contains a bin crate called rustc which
625-
// would otherwise overwrite the docs for the real rustc lib crate.
626-
cargo.arg("-p").arg("rustc_driver");
627-
} else {
628-
// Like with libstd above if compiler docs aren't enabled then we're not
629-
// documenting internal dependencies, so we have a whitelist.
630-
cargo.arg("--no-deps");
631-
for krate in &["proc_macro"] {
632-
cargo.arg("-p").arg(krate);
633-
}
625+
// We don't want to build docs for internal compiler dependencies in this
626+
// step (there is another step for that). Therefore, we whitelist the crates
627+
// for which docs must be built.
628+
cargo.arg("--no-deps");
629+
for krate in &["proc_macro"] {
630+
cargo.arg("-p").arg(krate);
634631
}
635632

636633
build.run(&mut cargo);
637634
cp_r(&my_out, &out);
638635
}
639636
}
640637

638+
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
639+
pub struct Rustc {
640+
stage: u32,
641+
target: Interned<String>,
642+
}
643+
644+
impl Step for Rustc {
645+
type Output = ();
646+
const DEFAULT: bool = true;
647+
const ONLY_HOSTS: bool = true;
648+
649+
fn should_run(run: ShouldRun) -> ShouldRun {
650+
let builder = run.builder;
651+
run.krate("rustc-main").default_condition(builder.build.config.docs)
652+
}
653+
654+
fn make_run(run: RunConfig) {
655+
run.builder.ensure(Rustc {
656+
stage: run.builder.top_stage,
657+
target: run.target,
658+
});
659+
}
660+
661+
/// Generate compiler documentation.
662+
///
663+
/// This will generate all documentation for compiler and dependencies.
664+
/// Compiler documentation is distributed separately, so we make sure
665+
/// we do not merge it with the other documentation from std, test and
666+
/// proc_macros. This is largely just a wrapper around `cargo doc`.
667+
fn run(self, builder: &Builder) {
668+
let build = builder.build;
669+
let stage = self.stage;
670+
let target = self.target;
671+
println!("Documenting stage{} compiler ({})", stage, target);
672+
let out = build.compiler_doc_out(target);
673+
t!(fs::create_dir_all(&out));
674+
let compiler = builder.compiler(stage, build.build);
675+
let rustdoc = builder.rustdoc(compiler.host);
676+
let compiler = if build.force_use_stage1(compiler, target) {
677+
builder.compiler(1, compiler.host)
678+
} else {
679+
compiler
680+
};
681+
682+
if !build.config.compiler_docs {
683+
println!("\tskipping - compiler docs disabled");
684+
return;
685+
}
686+
687+
// Build libstd docs so that we generate relative links
688+
builder.ensure(Std { stage, target });
689+
690+
builder.ensure(compile::Rustc { compiler, target });
691+
let out_dir = build.stage_out(compiler, Mode::Librustc)
692+
.join(target).join("doc");
693+
// We do not symlink to the same shared folder that already contains std library
694+
// documentation from previous steps as we do not want to include that.
695+
build.clear_if_dirty(&out, &rustdoc);
696+
t!(symlink_dir_force(&out, &out_dir));
697+
698+
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
699+
compile::rustc_cargo(build, &mut cargo);
700+
701+
// Only include compiler crates, no dependencies of those, such as `libc`.
702+
cargo.arg("--no-deps");
703+
704+
// Find dependencies for top level crates.
705+
let mut compiler_crates = HashSet::new();
706+
for root_crate in &["rustc", "rustc_driver"] {
707+
let interned_root_crate = INTERNER.intern_str(root_crate);
708+
find_compiler_crates(&build, &interned_root_crate, &mut compiler_crates);
709+
}
710+
711+
for krate in &compiler_crates {
712+
cargo.arg("-p").arg(krate);
713+
}
714+
715+
build.run(&mut cargo);
716+
}
717+
}
718+
719+
fn find_compiler_crates(
720+
build: &Build,
721+
name: &Interned<String>,
722+
crates: &mut HashSet<Interned<String>>
723+
) {
724+
// Add current crate.
725+
crates.insert(*name);
726+
727+
// Look for dependencies.
728+
for dep in build.crates.get(name).unwrap().deps.iter() {
729+
if build.crates.get(dep).unwrap().is_local(build) {
730+
find_compiler_crates(build, dep, crates);
731+
}
732+
}
733+
}
734+
641735
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
642736
pub struct ErrorIndex {
643737
target: Interned<String>,

src/bootstrap/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,11 @@ impl Build {
511511
self.out.join(&*target).join("doc")
512512
}
513513

514+
/// Output directory for all documentation for a target
515+
fn compiler_doc_out(&self, target: Interned<String>) -> PathBuf {
516+
self.out.join(&*target).join("compiler-doc")
517+
}
518+
514519
/// Output directory for some generated md crate documentation for a target (temporary)
515520
fn md_doc_out(&self, target: Interned<String>) -> Interned<PathBuf> {
516521
INTERNER.intern_path(self.out.join(&*target).join("md-doc"))

src/ci/docker/dist-x86_64-linux/Dockerfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ ENV HOSTS=x86_64-unknown-linux-gnu
8484
ENV RUST_CONFIGURE_ARGS \
8585
--enable-full-tools \
8686
--enable-sanitizers \
87-
--enable-profiler
87+
--enable-profiler \
88+
--enable-compiler-docs
8889
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
8990

9091
# This is the only builder which will create source tarballs

0 commit comments

Comments
 (0)