mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Auto merge of #112982 - lukas-code:bootstrap-alias-default-crates, r=albertlarsan68
bootstrap: update defaults for `compiler` and `library` aliases * `x doc compiler` now documents all of compiler, not just `rustc_driver`. * `x doc` with compiler docs enabled now includes `rustc-main` and `rustc_smir`. `rustc_codegen_llvm` is only included if the LLVM backend is enabled, which is the default. * `x doc library` now excludes `sysroot`. * `x check compiler` and `x check library` now properly check tests/benches/examples of all compiler or library crates, respectively. Note that `x check compiler` will check the library artifacts, but not tests. fixes the fallout from https://github.com/rust-lang/rust/pull/111955, cc `@jyn514`
This commit is contained in:
commit
bacf5bcbc7
@ -1,6 +1,6 @@
|
||||
//! The WIP stable interface to rustc internals.
|
||||
//!
|
||||
//! For more information see https://github.com/rust-lang/project-stable-mir
|
||||
//! For more information see <https://github.com/rust-lang/project-stable-mir>
|
||||
//!
|
||||
//! # Note
|
||||
//!
|
||||
@ -14,6 +14,7 @@
|
||||
#![feature(local_key_cell_methods)]
|
||||
#![feature(ptr_metadata)]
|
||||
#![feature(type_alias_impl_trait)] // Used to define opaque types.
|
||||
#![feature(intra_doc_pointers)]
|
||||
|
||||
// Declare extern rustc_* crates to enable building this crate separately from the compiler.
|
||||
#[cfg(not(feature = "default"))]
|
||||
|
@ -185,9 +185,9 @@ pub enum Rvalue {
|
||||
/// [#91095]. Note too that the value of the discriminant is not the same thing as the
|
||||
/// variant index; use [`discriminant_for_variant`] to convert.
|
||||
///
|
||||
/// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
|
||||
/// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty
|
||||
/// [#91095]: https://github.com/rust-lang/rust/issues/91095
|
||||
/// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
|
||||
/// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant
|
||||
Discriminant(Place),
|
||||
|
||||
/// Yields the length of the place, as a `usize`.
|
||||
|
@ -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`.
|
||||
|
@ -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 {
|
||||
|
@ -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 });
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1502,6 +1502,7 @@ impl Build {
|
||||
}
|
||||
}
|
||||
}
|
||||
ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user