about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Markeffsky <@>2023-06-23 16:28:08 +0000
committerLukas Markeffsky <@>2023-07-14 09:41:35 +0000
commitb1a5423ff8e2284a02aa75bf4467c9f49bb2e95b (patch)
treed6c87aef4ea90385b1f1bad73fb0317a1bbc8fb9
parentfe03b46ee4688a99d7155b4f9dcd875b6903952d (diff)
downloadrust-b1a5423ff8e2284a02aa75bf4467c9f49bb2e95b.tar.gz
rust-b1a5423ff8e2284a02aa75bf4467c9f49bb2e95b.zip
bootstrap: update defaults for `compiler` and `library` aliases
-rw-r--r--src/bootstrap/builder.rs37
-rw-r--r--src/bootstrap/builder/tests.rs8
-rw-r--r--src/bootstrap/check.rs21
-rw-r--r--src/bootstrap/compile.rs18
-rw-r--r--src/bootstrap/dist.rs7
-rw-r--r--src/bootstrap/doc.rs107
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/bootstrap/test.rs1
8 files changed, 114 insertions, 86 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index c0c749552e6..535a005c396 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -115,6 +115,43 @@ impl RunConfig<'_> {
         }
         INTERNER.intern_list(crates)
     }
+
+    /// Given an `alias` selected by the `Step` and the paths passed on the command line,
+    /// return a list of the crates that should be built.
+    ///
+    /// Normally, people will pass *just* `library` if they pass it.
+    /// But it's possible (although strange) to pass something like `library std core`.
+    /// Build all crates anyway, as if they hadn't passed the other args.
+    pub fn make_run_crates(&self, alias: Alias) -> Interned<Vec<String>> {
+        let has_alias =
+            self.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias.as_str()));
+        if !has_alias {
+            return self.cargo_crates_in_set();
+        }
+
+        let crates = match alias {
+            Alias::Library => self.builder.in_tree_crates("sysroot", Some(self.target)),
+            Alias::Compiler => self.builder.in_tree_crates("rustc-main", Some(self.target)),
+        };
+
+        let crate_names = crates.into_iter().map(|krate| krate.name.to_string()).collect();
+        INTERNER.intern_list(crate_names)
+    }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub enum Alias {
+    Library,
+    Compiler,
+}
+
+impl Alias {
+    fn as_str(self) -> &'static str {
+        match self {
+            Alias::Library => "library",
+            Alias::Compiler => "compiler",
+        }
+    }
 }
 
 /// A description of the crates in this set, suitable for passing to `builder.info`.
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 31dcee58216..65b8f7fd3b7 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -68,13 +68,17 @@ macro_rules! std {
 }
 
 macro_rules! doc_std {
-    ($host:ident => $target:ident, stage = $stage:literal) => {
+    ($host:ident => $target:ident, stage = $stage:literal) => {{
+        let config = configure("doc", &["A"], &["A"]);
+        let build = Build::new(config);
+        let builder = Builder::new(&build);
         doc::Std::new(
             $stage,
             TargetSelection::from_user(stringify!($target)),
+            &builder,
             DocumentationFormat::HTML,
         )
-    };
+    }};
 }
 
 macro_rules! rustc {
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 1a0f0047812..691e5ce4eb2 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -1,10 +1,8 @@
 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
-use crate::builder::{crate_description, Builder, Kind, RunConfig, ShouldRun, Step};
+use crate::builder::{crate_description, Alias, Builder, Kind, RunConfig, ShouldRun, Step};
 use crate::cache::Interned;
-use crate::compile::{
-    add_to_sysroot, make_run_crates, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo,
-};
+use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo};
 use crate::config::TargetSelection;
 use crate::tool::{prepare_tool_cargo, SourceType};
 use crate::INTERNER;
@@ -89,7 +87,7 @@ impl Step for Std {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let crates = make_run_crates(&run, "library");
+        let crates = run.make_run_crates(Alias::Library);
         run.builder.ensure(Std { target: run.target, crates });
     }
 
@@ -140,7 +138,7 @@ impl Step for Std {
 
         // don't run on std twice with x.py clippy
         // don't check test dependencies if we haven't built libtest
-        if builder.kind == Kind::Clippy || !self.crates.is_empty() {
+        if builder.kind == Kind::Clippy || !self.crates.iter().any(|krate| krate == "test") {
             return;
         }
 
@@ -200,10 +198,11 @@ pub struct Rustc {
 
 impl Rustc {
     pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
-        let mut crates = vec![];
-        for krate in builder.in_tree_crates("rustc-main", None) {
-            crates.push(krate.name.to_string());
-        }
+        let crates = builder
+            .in_tree_crates("rustc-main", Some(target))
+            .into_iter()
+            .map(|krate| krate.name.to_string())
+            .collect();
         Self { target, crates: INTERNER.intern_list(crates) }
     }
 }
@@ -218,7 +217,7 @@ impl Step for Rustc {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        let crates = make_run_crates(&run, "compiler");
+        let crates = run.make_run_crates(Alias::Compiler);
         run.builder.ensure(Rustc { target: run.target, crates });
     }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index caa7417011e..07a07983bd7 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -55,17 +55,6 @@ impl Std {
     }
 }
 
-/// Given an `alias` selected by the `Step` and the paths passed on the command line,
-/// return a list of the crates that should be built.
-///
-/// Normally, people will pass *just* `library` if they pass it.
-/// But it's possible (although strange) to pass something like `library std core`.
-/// Build all crates anyway, as if they hadn't passed the other args.
-pub(crate) fn make_run_crates(run: &RunConfig<'_>, alias: &str) -> Interned<Vec<String>> {
-    let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias));
-    if has_alias { Default::default() } else { run.cargo_crates_in_set() }
-}
-
 impl Step for Std {
     type Output = ();
     const DEFAULT: bool = true;
@@ -80,10 +69,15 @@ impl Step for Std {
     }
 
     fn make_run(run: RunConfig<'_>) {
+        // If the paths include "library", build the entire standard library.
+        let has_alias =
+            run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library"));
+        let crates = if has_alias { Default::default() } else { run.cargo_crates_in_set() };
+
         run.builder.ensure(Std {
             compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
             target: run.target,
-            crates: make_run_crates(&run, "library"),
+            crates,
             force_recompile: false,
         });
     }
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index b34a4b2dc63..2141bb0ddd9 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -106,7 +106,12 @@ impl Step for JsonDocs {
     /// Builds the `rust-docs-json` installer component.
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
         let host = self.host;
-        builder.ensure(crate::doc::Std::new(builder.top_stage, host, DocumentationFormat::JSON));
+        builder.ensure(crate::doc::Std::new(
+            builder.top_stage,
+            host,
+            builder,
+            DocumentationFormat::JSON,
+        ));
 
         let dest = "share/doc/rust/json";
 
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 5ebfe0995a8..0fd6b46d562 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -11,10 +11,9 @@ use std::fs;
 use std::path::{Path, PathBuf};
 
 use crate::builder::crate_description;
-use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
+use crate::builder::{Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
 use crate::cache::{Interned, INTERNER};
 use crate::compile;
-use crate::compile::make_run_crates;
 use crate::config::{Config, TargetSelection};
 use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
 use crate::util::{symlink_dir, t, up_to_date};
@@ -424,8 +423,18 @@ pub struct Std {
 }
 
 impl Std {
-    pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self {
-        Std { stage, target, format, crates: INTERNER.intern_list(vec![]) }
+    pub(crate) fn new(
+        stage: u32,
+        target: TargetSelection,
+        builder: &Builder<'_>,
+        format: DocumentationFormat,
+    ) -> Self {
+        let crates = builder
+            .in_tree_crates("sysroot", Some(target))
+            .into_iter()
+            .map(|krate| krate.name.to_string())
+            .collect();
+        Std { stage, target, format, crates: INTERNER.intern_list(crates) }
     }
 }
 
@@ -447,7 +456,7 @@ impl Step for Std {
             } else {
                 DocumentationFormat::HTML
             },
-            crates: make_run_crates(&run, "library"),
+            crates: run.make_run_crates(Alias::Library),
         });
     }
 
@@ -455,7 +464,7 @@ impl Step for Std {
     ///
     /// This will generate all documentation for the standard library and its
     /// dependencies. This is largely just a wrapper around `cargo doc`.
-    fn run(mut self, builder: &Builder<'_>) {
+    fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
         let out = match self.format {
@@ -493,20 +502,17 @@ impl Step for Std {
             return;
         }
 
-        // Look for library/std, library/core etc in the `x.py doc` arguments and
-        // open the corresponding rendered docs.
-        if self.crates.is_empty() {
-            self.crates = INTERNER.intern_list(vec!["library".to_owned()]);
-        };
-
-        for requested_crate in &*self.crates {
-            if requested_crate == "library" {
-                // For `x.py doc library --open`, open `std` by default.
-                let index = out.join("std").join("index.html");
-                builder.open_in_browser(index);
-            } else if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
-                let index = out.join(requested_crate).join("index.html");
-                builder.open_in_browser(index);
+        if builder.paths.iter().any(|path| path.ends_with("library")) {
+            // For `x.py doc library --open`, open `std` by default.
+            let index = out.join("std").join("index.html");
+            builder.open_in_browser(index);
+        } else {
+            for requested_crate in &*self.crates {
+                if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) {
+                    let index = out.join(requested_crate).join("index.html");
+                    builder.open_in_browser(index);
+                    break;
+                }
             }
         }
     }
@@ -539,9 +545,6 @@ impl DocumentationFormat {
 }
 
 /// Build the documentation for public standard library crates.
-///
-/// `requested_crates` can be used to build only a subset of the crates. If empty, all crates will
-/// be built.
 fn doc_std(
     builder: &Builder<'_>,
     format: DocumentationFormat,
@@ -592,19 +595,11 @@ fn doc_std(
         cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items");
     }
 
-    // HACK: because we use `--manifest-path library/sysroot/Cargo.toml`, cargo thinks we only want to document that specific crate, not its dependencies.
-    // Override its default.
-    let built_crates = if requested_crates.is_empty() {
-        builder
-            .in_tree_crates("sysroot", None)
-            .into_iter()
-            .map(|krate| krate.name.to_string())
-            .collect()
-    } else {
-        requested_crates.to_vec()
-    };
-
-    for krate in built_crates {
+    for krate in requested_crates {
+        if krate == "sysroot" {
+            // The sysroot crate is an implementation detail, don't include it in public docs.
+            continue;
+        }
         cargo.arg("-p").arg(krate);
     }
 
@@ -621,20 +616,10 @@ pub struct Rustc {
 
 impl Rustc {
     pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self {
-        // Find dependencies for top level crates.
-        let root_crates = vec![
-            INTERNER.intern_str("rustc_driver"),
-            INTERNER.intern_str("rustc_codegen_llvm"),
-            INTERNER.intern_str("rustc_codegen_ssa"),
-        ];
-        let crates: Vec<_> = root_crates
-            .iter()
-            .flat_map(|krate| {
-                builder
-                    .in_tree_crates(krate, Some(target))
-                    .into_iter()
-                    .map(|krate| krate.name.to_string())
-            })
+        let crates = builder
+            .in_tree_crates("rustc-main", Some(target))
+            .into_iter()
+            .map(|krate| krate.name.to_string())
             .collect();
         Self { stage, target, crates: INTERNER.intern_list(crates) }
     }
@@ -656,7 +641,7 @@ impl Step for Rustc {
         run.builder.ensure(Rustc {
             stage: run.builder.top_stage,
             target: run.target,
-            crates: make_run_crates(&run, "compiler"),
+            crates: run.make_run_crates(Alias::Compiler),
         });
     }
 
@@ -666,7 +651,7 @@ impl Step for Rustc {
     /// Compiler documentation is distributed separately, so we make sure
     /// we do not merge it with the other documentation from std, test and
     /// proc_macros. This is largely just a wrapper around `cargo doc`.
-    fn run(mut self, builder: &Builder<'_>) {
+    fn run(self, builder: &Builder<'_>) {
         let stage = self.stage;
         let target = self.target;
 
@@ -726,24 +711,26 @@ impl Step for Rustc {
 
         let mut to_open = None;
 
-        if self.crates.is_empty() {
-            self.crates = INTERNER.intern_list(vec!["rustc_driver".to_owned()]);
-        };
-
         for krate in &*self.crates {
             // 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(krate)));
+            let dir_name = krate.replace("-", "_");
+            t!(fs::create_dir_all(out_dir.join(&*dir_name)));
             cargo.arg("-p").arg(krate);
             if to_open.is_none() {
-                to_open = Some(krate);
+                to_open = Some(dir_name);
             }
         }
 
         builder.run(&mut cargo.into());
-        // Let's open the first crate documentation page:
-        if let Some(krate) = to_open {
+
+        if builder.paths.iter().any(|path| path.ends_with("compiler")) {
+            // For `x.py doc compiler --open`, open `rustc_middle` by default.
+            let index = out.join("rustc_middle").join("index.html");
+            builder.open_in_browser(index);
+        } else if let Some(krate) = to_open {
+            // Let's open the first crate documentation page:
             let index = out.join(krate).join("index.html");
             builder.open_in_browser(index);
         }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 0b509132043..f5ad4f336a7 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1502,6 +1502,7 @@ impl Build {
                 }
             }
         }
+        ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests
         ret
     }
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 3b8b837682d..284efff348d 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -901,6 +901,7 @@ impl Step for RustdocJSStd {
         builder.ensure(crate::doc::Std::new(
             builder.top_stage,
             self.target,
+            builder,
             DocumentationFormat::HTML,
         ));
         builder.run(&mut command);