Skip to content

Commit

Permalink
Allow building single crates for the compiler and standard library
Browse files Browse the repository at this point in the history
- Add `Interned<Vec<String>>` and use it for tail args
- Refactor `cache.rs` not to need a separate impl for each internable type
  • Loading branch information
jyn514 committed Jul 3, 2022
1 parent 0566ade commit d0011b0
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 110 deletions.
15 changes: 12 additions & 3 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use std::process::{Command, Stdio};
use std::time::{Duration, Instant};

use crate::cache::{Cache, Interned, INTERNER};
use crate::compile;
use crate::config::{SplitDebuginfo, TargetSelection};
use crate::dist;
use crate::doc;
Expand All @@ -26,6 +25,7 @@ use crate::tool::{self, SourceType};
use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t};
use crate::EXTRA_CHECK_CFGS;
use crate::{check, Config};
use crate::{compile, Crate};
use crate::{Build, CLang, DocTests, GitRepo, Mode};

pub use crate::Compiler;
Expand Down Expand Up @@ -422,8 +422,16 @@ impl<'a> ShouldRun<'a> {
/// any of its (local) dependencies.
///
/// `make_run` will be called a single time with all matching command-line paths.
pub fn krate(mut self, name: &str) -> Self {
for krate in self.builder.in_tree_crates(name, None) {
pub fn crate_or_deps(self, name: &str) -> Self {
let crates = self.builder.in_tree_crates(name, None);
self.crates(crates)
}

/// Indicates it should run if the command-line selects any of the given crates.
///
/// `make_run` will be called a single time with all matching command-line paths.
pub(crate) fn crates(mut self, crates: Vec<&Crate>) -> Self {
for krate in crates {
let path = krate.local_path(self.builder);
self.paths.insert(PathSet::one(path, self.kind));
}
Expand Down Expand Up @@ -579,6 +587,7 @@ impl<'a> Builder<'a> {
match kind {
Kind::Build => describe!(
compile::Std,
compile::Rustc,
compile::Assemble,
compile::CodegenBackend,
compile::StartupObjects,
Expand Down
125 changes: 63 additions & 62 deletions src/bootstrap/builder/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ fn check_cli<const N: usize>(paths: [&str; N]) {
);
}

macro_rules! std {
($host:ident => $target:ident, stage = $stage:literal) => {
compile::Std::new(
Compiler { host: TargetSelection::from_user(stringify!($host)), stage: $stage },
TargetSelection::from_user(stringify!($target)),
)
};
}

macro_rules! rustc {
($host:ident => $target:ident, stage = $stage:literal) => {
compile::Rustc::new(
Compiler { host: TargetSelection::from_user(stringify!($host)), stage: $stage },
TargetSelection::from_user(stringify!($target)),
)
};
}

#[test]
fn test_valid() {
// make sure multi suite paths are accepted
Expand Down Expand Up @@ -117,6 +135,17 @@ fn test_exclude_kind() {
assert!(run_build(&[path], config).contains::<tool::CargoTest>());
}

/// Ensure that if someone passes both a single crate and `library`, all library crates get built.
#[test]
fn alias_and_path_for_library() {
let mut cache =
run_build(&["library".into(), "core".into()], configure("build", &["A"], &["A"]));
assert_eq!(
first(cache.all::<compile::Std>()),
&[std!(A => A, stage = 0), std!(A => A, stage = 1)]
);
}

mod defaults {
use super::{configure, first, run_build};
use crate::builder::*;
Expand All @@ -130,10 +159,7 @@ mod defaults {
let a = TargetSelection::from_user("A");
assert_eq!(
first(cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
]
&[std!(A => A, stage = 0), std!(A => A, stage = 1),]
);
assert!(!cache.all::<compile::Assemble>().is_empty());
// Make sure rustdoc is only built once.
Expand All @@ -143,10 +169,7 @@ mod defaults {
// - this is the compiler it's _linked_ to, not built with.
&[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
);
assert_eq!(
first(cache.all::<compile::Rustc>()),
&[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },]
);
assert_eq!(first(cache.all::<compile::Rustc>()), &[rustc!(A => A, stage = 0)],);
}

#[test]
Expand All @@ -155,10 +178,7 @@ mod defaults {
let mut cache = run_build(&[], config);

let a = TargetSelection::from_user("A");
assert_eq!(
first(cache.all::<compile::Std>()),
&[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },]
);
assert_eq!(first(cache.all::<compile::Std>()), &[std!(A => A, stage = 0)]);
assert!(!cache.all::<compile::Assemble>().is_empty());
assert_eq!(
first(cache.all::<tool::Rustdoc>()),
Expand All @@ -185,10 +205,10 @@ mod defaults {
assert_eq!(
first(cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: b },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
std!(A => A, stage = 0),
std!(A => A, stage = 1),
std!(A => B, stage = 0),
std!(A => B, stage = 1),
]
);
assert_eq!(
Expand All @@ -208,10 +228,7 @@ mod defaults {
);
assert_eq!(
first(cache.all::<compile::Rustc>()),
&[
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: b },
]
&[rustc!(A => A, stage = 0), rustc!(A => B, stage = 0),]
);
}

Expand Down Expand Up @@ -334,19 +351,18 @@ mod dist {
assert_eq!(
first(cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
std!(A => A, stage = 0),
std!(A => A, stage = 1),
std!(A => A, stage = 2),
std!(A => B, stage = 1),
std!(A => B, stage = 2),
],
);
assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
}

#[test]
fn dist_only_cross_host() {
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let mut config = configure(&["A", "B"], &["A", "B"]);
config.docs = false;
Expand All @@ -360,10 +376,7 @@ mod dist {
);
assert_eq!(
first(cache.all::<compile::Rustc>()),
&[
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
]
&[rustc!(A => A, stage = 0), rustc!(A => B, stage = 1),]
);
}

Expand Down Expand Up @@ -450,11 +463,11 @@ mod dist {
assert_eq!(
first(cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
std!(A => A, stage = 0),
std!(A => A, stage = 1),
std!(A => A, stage = 2),
std!(A => B, stage = 1),
std!(A => B, stage = 2),
]
);
assert_eq!(
Expand All @@ -474,33 +487,29 @@ mod dist {
let mut builder = Builder::new(&build);
builder.run_step_descriptions(
&Builder::get_step_descriptions(Kind::Build),
&["compiler/rustc".into(), "library/std".into()],
&["compiler/rustc".into(), "library".into()],
);

let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let c = TargetSelection::from_user("C");

assert_eq!(
first(builder.cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
std!(A => A, stage = 0),
std!(A => A, stage = 1),
std!(A => A, stage = 2),
std!(A => B, stage = 1),
std!(A => B, stage = 2),
std!(A => C, stage = 2),
]
);
assert!(!builder.cache.all::<compile::Assemble>().is_empty());
assert_eq!(builder.cache.all::<compile::Assemble>().len(), 5);
assert_eq!(
first(builder.cache.all::<compile::Rustc>()),
&[
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b },
rustc!(A => A, stage = 0),
rustc!(A => A, stage = 1),
rustc!(A => A, stage = 2),
rustc!(A => B, stage = 1),
rustc!(A => B, stage = 2),
]
);
}
Expand All @@ -513,15 +522,10 @@ mod dist {
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);

let a = TargetSelection::from_user("A");
let c = TargetSelection::from_user("C");

assert_eq!(
first(builder.cache.all::<compile::Std>()),
&[
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
]
&[std!(A => A, stage = 0), std!(A => A, stage = 1), std!(A => C, stage = 2),]
);
assert_eq!(
first(builder.cache.all::<compile::Assemble>()),
Expand All @@ -533,10 +537,7 @@ mod dist {
);
assert_eq!(
first(builder.cache.all::<compile::Rustc>()),
&[
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
]
&[rustc!(A => A, stage = 0), rustc!(A => A, stage = 1),]
);
}

Expand Down
11 changes: 11 additions & 0 deletions src/bootstrap/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ impl<T: Hash + Clone + Eq> TyIntern<T> {
pub struct Interner {
strs: Mutex<TyIntern<String>>,
paths: Mutex<TyIntern<PathBuf>>,
lists: Mutex<TyIntern<Vec<String>>>,
}

trait Internable: Clone + Eq + Hash + 'static {
Expand All @@ -184,6 +185,12 @@ impl Internable for PathBuf {
}
}

impl Internable for Vec<String> {
fn intern_cache() -> &'static Mutex<TyIntern<Self>> {
&INTERNER.lists
}
}

impl Interner {
pub fn intern_str(&self, s: &str) -> Interned<String> {
self.strs.lock().unwrap().intern_borrow(s)
Expand All @@ -195,6 +202,10 @@ impl Interner {
pub fn intern_path(&self, s: PathBuf) -> Interned<PathBuf> {
self.paths.lock().unwrap().intern(s)
}

pub fn intern_list(&self, v: Vec<String>) -> Interned<Vec<String>> {
self.lists.lock().unwrap().intern(v)
}
}

pub static INTERNER: Lazy<Interner> = Lazy::new(Interner::default);
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ impl Step for Rustc {
// the sysroot for the compiler to find. Otherwise, we're going to
// fail when building crates that need to generate code (e.g., build
// scripts and their dependencies).
builder.ensure(crate::compile::Std { target: compiler.host, compiler });
builder.ensure(crate::compile::Std { target, compiler });
builder.ensure(crate::compile::Std::new(compiler, compiler.host));
builder.ensure(crate::compile::Std::new(compiler, target));
} else {
builder.ensure(Std { target });
}
Expand Down
Loading

0 comments on commit d0011b0

Please sign in to comment.