Skip to content

Commit

Permalink
Rollup merge of rust-lang#74352 - ehuss:fix-alloc-links, r=Mark-Simul…
Browse files Browse the repository at this point in the history
…acrum

Use local links in the alloc docs.

Links to other crates (like core) from the alloc crate were incorrectly using the `https://doc.rust-lang.org/nightly/` absolute (remote) links, instead of relative (local) links.  For example, the link to `Result` at https://doc.rust-lang.org/1.44.1/alloc/vec/struct.Vec.html#method.try_reserve goes to /nightly/.

This is because alloc was being documented before core, and rustdoc relies on the existence of the local directory to know if it should use a local or remote link.

There was code that tried to compensate for this (`create_dir_all`), but in rust-lang#54543 it was broken because instead of running `cargo doc` once for all the crates, it was changed to run `cargo rustdoc` for each crate individually. This means that `create_dir_all` was no longer doing what it was supposed to be doing (creating all the directories before starting).

The solution here is to just build in the correct order (from the dependency leaves towards the root).  An alternate solution would be to switch back to running `cargo doc` once (and use RUSTDOCFLAGS for passing in flags).  Another alternate solution would be to iterate over the list twice, creating the directories during the first pass.

I also did a little cleanup to remove the "crate-docs" directory. This was added in the past because different crates were built in different directories. Over time, things have been unified (and rustc docs no longer include std), so it is no longer necessary.
  • Loading branch information
Manishearth authored Jul 16, 2020
2 parents 80a7a87 + 8334419 commit 2872da3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 32 deletions.
3 changes: 2 additions & 1 deletion src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,8 @@ impl<'a> Builder<'a> {
let my_out = match mode {
// This is the intended out directory for compiler documentation.
Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
_ => self.crate_doc_out(target),
Mode::Std => out_dir.join(target).join("doc"),
_ => panic!("doc mode {:?} not expected", mode),
};
let rustdoc = self.rustdoc(compiler);
self.clear_if_dirty(&my_out, &rustdoc);
Expand Down
39 changes: 15 additions & 24 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,34 +417,16 @@ impl Step for Std {
builder.ensure(compile::Std { compiler, target });
let out_dir = builder.stage_out(compiler, Mode::Std).join(target).join("doc");

// Here what we're doing is creating a *symlink* (directory junction on
// Windows) to the final output location. This is not done as an
// optimization but rather for correctness. We've got three trees of
// documentation, one for std, one for test, and one for rustc. It's then
// our job to merge them all together.
//
// Unfortunately rustbuild doesn't know nearly as well how to merge doc
// trees as rustdoc does itself, so instead of actually having three
// separate trees we just have rustdoc output to the same location across
// all of them.
//
// This way rustdoc generates output directly into the output, and rustdoc
// will also directly handle merging.
let my_out = builder.crate_doc_out(target);
t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));

let run_cargo_rustdoc_for = |package: &str| {
let mut cargo =
builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustdoc");
compile::std_cargo(builder, target, compiler.stage, &mut cargo);

cargo.arg("-p").arg(package);
// Create all crate output directories first to make sure rustdoc uses
// relative links.
// FIXME: Cargo should probably do this itself.
t!(fs::create_dir_all(out_dir.join(package)));
cargo
.arg("-p")
.arg(package)
.arg("--")
.arg("--markdown-css")
.arg("rust.css")
Expand All @@ -462,11 +444,17 @@ impl Step for Std {
// folder structure, that would also build internal crates that we do
// not want to show in documentation. These crates will later be visited
// by the rustc step, so internal documentation will show them.
let krates = ["alloc", "core", "std", "proc_macro", "test"];
//
// Note that the order here is important! The crates need to be
// processed starting from the leaves, otherwise rustdoc will not
// create correct links between crates because rustdoc depends on the
// existence of the output directories to know if it should be a local
// or remote link.
let krates = ["core", "alloc", "std", "proc_macro", "test"];
for krate in &krates {
run_cargo_rustdoc_for(krate);
}
builder.cp_r(&my_out, &out);
builder.cp_r(&out_dir, &out);

// Look for src/libstd, src/libcore etc in the `x.py doc` arguments and
// open the corresponding rendered docs.
Expand Down Expand Up @@ -529,8 +517,11 @@ impl Step for Rustc {
// Build rustc.
builder.ensure(compile::Rustc { compiler, target });

// We do not symlink to the same shared folder that already contains std library
// documentation from previous steps as we do not want to include that.
// This uses a shared directory so that librustdoc documentation gets
// correctly built and merged with the rustc documentation. This is
// needed because rustdoc is built in a different directory from
// rustc. rustdoc needs to be able to see everything, for example when
// merging the search index, or generating local (relative) links.
let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc");
t!(symlink_dir_force(&builder.config, &out, &out_dir));

Expand Down
7 changes: 0 additions & 7 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,13 +612,6 @@ impl Build {
INTERNER.intern_path(self.out.join(&*target).join("md-doc"))
}

/// Output directory for all crate documentation for a target (temporary)
///
/// The artifacts here are then copied into `doc_out` above.
fn crate_doc_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("crate-docs")
}

/// Returns `true` if no custom `llvm-config` is set for the specified target.
///
/// If no custom `llvm-config` was specified then Rust's llvm will be used.
Expand Down

0 comments on commit 2872da3

Please sign in to comment.