Auto merge of #48105 - Mark-Simulacrum:exclude-paths, r=alexcrichton
Implement excluding a build-step via --exclude First step to fixing https://github.com/rust-lang/rust/issues/47911. This doesn't change any CI configuration, but implements what I believe necessary to make that feasible in rustbuild. In theory this should be sufficient to allow someone to open a PR against .travis.yml and appveyor.yml which splits the Windows 32-bit tests and maybe the OS X tests into multiple builders (depending on what our cost-concerns are) to reduce runtimes. r? @alexcrichton cc @kennytm
This commit is contained in:
commit
c83fa5d91c
10 changed files with 452 additions and 335 deletions
|
@ -95,7 +95,7 @@ pub struct RunConfig<'a> {
|
|||
pub builder: &'a Builder<'a>,
|
||||
pub host: Interned<String>,
|
||||
pub target: Interned<String>,
|
||||
pub path: Option<&'a Path>,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
struct StepDescription {
|
||||
|
@ -105,6 +105,32 @@ struct StepDescription {
|
|||
only_build: bool,
|
||||
should_run: fn(ShouldRun) -> ShouldRun,
|
||||
make_run: fn(RunConfig),
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
|
||||
struct PathSet {
|
||||
set: BTreeSet<PathBuf>,
|
||||
}
|
||||
|
||||
impl PathSet {
|
||||
fn empty() -> PathSet {
|
||||
PathSet { set: BTreeSet::new() }
|
||||
}
|
||||
|
||||
fn one<P: Into<PathBuf>>(path: P) -> PathSet {
|
||||
let mut set = BTreeSet::new();
|
||||
set.insert(path.into());
|
||||
PathSet { set }
|
||||
}
|
||||
|
||||
fn has(&self, needle: &Path) -> bool {
|
||||
self.set.iter().any(|p| p.ends_with(needle))
|
||||
}
|
||||
|
||||
fn path(&self, builder: &Builder) -> PathBuf {
|
||||
self.set.iter().next().unwrap_or(&builder.build.src).to_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
impl StepDescription {
|
||||
|
@ -116,10 +142,18 @@ impl StepDescription {
|
|||
only_build: S::ONLY_BUILD,
|
||||
should_run: S::should_run,
|
||||
make_run: S::make_run,
|
||||
name: unsafe { ::std::intrinsics::type_name::<S>() },
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_run(&self, builder: &Builder, path: Option<&Path>) {
|
||||
fn maybe_run(&self, builder: &Builder, pathset: &PathSet) {
|
||||
if builder.config.exclude.iter().any(|e| pathset.has(e)) {
|
||||
eprintln!("Skipping {:?} because it is excluded", pathset);
|
||||
return;
|
||||
} else if !builder.config.exclude.is_empty() {
|
||||
eprintln!("{:?} not skipped for {:?} -- not in {:?}", pathset,
|
||||
self.name, builder.config.exclude);
|
||||
}
|
||||
let build = builder.build;
|
||||
let hosts = if self.only_build_targets || self.only_build {
|
||||
build.build_triple()
|
||||
|
@ -144,7 +178,7 @@ impl StepDescription {
|
|||
for target in targets {
|
||||
let run = RunConfig {
|
||||
builder,
|
||||
path,
|
||||
path: pathset.path(builder),
|
||||
host: *host,
|
||||
target: *target,
|
||||
};
|
||||
|
@ -157,19 +191,28 @@ impl StepDescription {
|
|||
let should_runs = v.iter().map(|desc| {
|
||||
(desc.should_run)(ShouldRun::new(builder))
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
// sanity checks on rules
|
||||
for (desc, should_run) in v.iter().zip(&should_runs) {
|
||||
assert!(!should_run.paths.is_empty(),
|
||||
"{:?} should have at least one pathset", desc.name);
|
||||
}
|
||||
|
||||
if paths.is_empty() {
|
||||
for (desc, should_run) in v.iter().zip(should_runs) {
|
||||
if desc.default && should_run.is_really_default {
|
||||
desc.maybe_run(builder, None);
|
||||
for pathset in &should_run.paths {
|
||||
desc.maybe_run(builder, pathset);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for path in paths {
|
||||
let mut attempted_run = false;
|
||||
for (desc, should_run) in v.iter().zip(&should_runs) {
|
||||
if should_run.run(path) {
|
||||
if let Some(pathset) = should_run.pathset_for_path(path) {
|
||||
attempted_run = true;
|
||||
desc.maybe_run(builder, Some(path));
|
||||
desc.maybe_run(builder, pathset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +228,7 @@ impl StepDescription {
|
|||
pub struct ShouldRun<'a> {
|
||||
pub builder: &'a Builder<'a>,
|
||||
// use a BTreeSet to maintain sort order
|
||||
paths: BTreeSet<PathBuf>,
|
||||
paths: BTreeSet<PathSet>,
|
||||
|
||||
// If this is a default rule, this is an additional constraint placed on
|
||||
// it's run. Generally something like compiler docs being enabled.
|
||||
|
@ -206,25 +249,46 @@ impl<'a> ShouldRun<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
// Unlike `krate` this will create just one pathset. As such, it probably shouldn't actually
|
||||
// ever be used, but as we transition to having all rules properly handle passing krate(...) by
|
||||
// actually doing something different for every crate passed.
|
||||
pub fn all_krates(mut self, name: &str) -> Self {
|
||||
let mut set = BTreeSet::new();
|
||||
for krate in self.builder.in_tree_crates(name) {
|
||||
set.insert(PathBuf::from(&krate.path));
|
||||
}
|
||||
self.paths.insert(PathSet { set });
|
||||
self
|
||||
}
|
||||
|
||||
pub fn krate(mut self, name: &str) -> Self {
|
||||
for (_, krate_path) in self.builder.crates(name) {
|
||||
self.paths.insert(PathBuf::from(krate_path));
|
||||
for krate in self.builder.in_tree_crates(name) {
|
||||
self.paths.insert(PathSet::one(&krate.path));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn path(mut self, path: &str) -> Self {
|
||||
self.paths.insert(PathBuf::from(path));
|
||||
// single, non-aliased path
|
||||
pub fn path(self, path: &str) -> Self {
|
||||
self.paths(&[path])
|
||||
}
|
||||
|
||||
// multiple aliases for the same job
|
||||
pub fn paths(mut self, paths: &[&str]) -> Self {
|
||||
self.paths.insert(PathSet {
|
||||
set: paths.iter().map(PathBuf::from).collect(),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
// allows being more explicit about why should_run in Step returns the value passed to it
|
||||
pub fn never(self) -> ShouldRun<'a> {
|
||||
pub fn never(mut self) -> ShouldRun<'a> {
|
||||
self.paths.insert(PathSet::empty());
|
||||
self
|
||||
}
|
||||
|
||||
fn run(&self, path: &Path) -> bool {
|
||||
self.paths.iter().any(|p| path.ends_with(p))
|
||||
fn pathset_for_path(&self, path: &Path) -> Option<&PathSet> {
|
||||
self.paths.iter().find(|pathset| pathset.has(path))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,19 +318,23 @@ impl<'a> Builder<'a> {
|
|||
tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy,
|
||||
native::Llvm, tool::Rustfmt, tool::Miri),
|
||||
Kind::Check => describe!(check::Std, check::Test, check::Rustc),
|
||||
Kind::Test => describe!(test::Tidy, test::Bootstrap, test::DefaultCompiletest,
|
||||
test::HostCompiletest, test::Crate, test::CrateLibrustc, test::Rustdoc,
|
||||
test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::Docs,
|
||||
test::ErrorIndex, test::Distcheck, test::Rustfmt, test::Miri, test::Clippy,
|
||||
test::RustdocJS, test::RustdocTheme),
|
||||
Kind::Test => describe!(test::Tidy, test::Bootstrap, test::Ui, test::RunPass,
|
||||
test::CompileFail, test::ParseFail, test::RunFail, test::RunPassValgrind,
|
||||
test::MirOpt, test::Codegen, test::CodegenUnits, test::Incremental, test::Debuginfo,
|
||||
test::UiFullDeps, test::RunPassFullDeps, test::RunFailFullDeps,
|
||||
test::CompileFailFullDeps, test::IncrementalFullDeps, test::Rustdoc, test::Pretty,
|
||||
test::RunPassPretty, test::RunFailPretty, test::RunPassValgrindPretty,
|
||||
test::RunPassFullDepsPretty, test::RunFailFullDepsPretty, test::RunMake,
|
||||
test::Crate, test::CrateLibrustc, test::Rustdoc, test::Linkcheck, test::Cargotest,
|
||||
test::Cargo, test::Rls, test::Docs, test::ErrorIndex, test::Distcheck,
|
||||
test::Rustfmt, test::Miri, test::Clippy, test::RustdocJS, test::RustdocTheme),
|
||||
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
|
||||
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
|
||||
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
|
||||
doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook),
|
||||
Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts,
|
||||
dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo,
|
||||
dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign,
|
||||
dist::DontDistWithMiriEnabled),
|
||||
dist::Rls, dist::Rustfmt, dist::Extended, dist::HashSign),
|
||||
Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls,
|
||||
install::Rustfmt, install::Analysis, install::Src, install::Rustc),
|
||||
}
|
||||
|
@ -297,9 +365,11 @@ impl<'a> Builder<'a> {
|
|||
should_run = (desc.should_run)(should_run);
|
||||
}
|
||||
let mut help = String::from("Available paths:\n");
|
||||
for path in should_run.paths {
|
||||
for pathset in should_run.paths {
|
||||
for path in pathset.set {
|
||||
help.push_str(format!(" ./x.py {} {}\n", subcommand, path.display()).as_str());
|
||||
}
|
||||
}
|
||||
Some(help)
|
||||
}
|
||||
|
||||
|
@ -323,6 +393,12 @@ impl<'a> Builder<'a> {
|
|||
stack: RefCell::new(Vec::new()),
|
||||
};
|
||||
|
||||
if kind == Kind::Dist {
|
||||
assert!(!build.config.test_miri, "Do not distribute with miri enabled.\n\
|
||||
The distributed libraries would include all MIR (increasing binary size).
|
||||
The distributed MIR would include validation statements.");
|
||||
}
|
||||
|
||||
StepDescription::run(&Builder::get_step_descriptions(builder.kind), &builder, paths);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ impl Step for Std {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libstd").krate("std")
|
||||
run.all_krates("std")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -67,7 +67,7 @@ impl Step for Rustc {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/librustc").krate("rustc-main")
|
||||
run.all_krates("rustc-main")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -114,7 +114,7 @@ impl Step for Test {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libtest").krate("test")
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
|
|
@ -48,7 +48,7 @@ impl Step for Std {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libstd").krate("std")
|
||||
run.all_krates("std")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -320,7 +320,7 @@ impl Step for Test {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libtest").krate("test")
|
||||
run.all_krates("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -436,7 +436,7 @@ impl Step for Rustc {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/librustc").krate("rustc-main")
|
||||
run.all_krates("rustc-main")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -593,7 +593,7 @@ impl Step for CodegenBackend {
|
|||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/librustc_trans")
|
||||
run.all_krates("rustc_trans")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -828,7 +828,7 @@ impl Step for Assemble {
|
|||
type Output = Compiler;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/rustc")
|
||||
run.all_krates("rustc-main")
|
||||
}
|
||||
|
||||
/// Prepare a new compiler from the artifacts in `stage`
|
||||
|
|
|
@ -56,6 +56,7 @@ pub struct Config {
|
|||
pub sanitizers: bool,
|
||||
pub profiler: bool,
|
||||
pub ignore_git: bool,
|
||||
pub exclude: Vec<PathBuf>,
|
||||
|
||||
pub run_host_only: bool,
|
||||
|
||||
|
@ -311,6 +312,7 @@ impl Config {
|
|||
let flags = Flags::parse(&args);
|
||||
let file = flags.config.clone();
|
||||
let mut config = Config::default();
|
||||
config.exclude = flags.exclude;
|
||||
config.llvm_enabled = true;
|
||||
config.llvm_optimize = true;
|
||||
config.llvm_version_check = true;
|
||||
|
|
|
@ -1233,31 +1233,6 @@ impl Step for Rustfmt {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct DontDistWithMiriEnabled;
|
||||
|
||||
impl Step for DontDistWithMiriEnabled {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
let build_miri = run.builder.build.config.test_miri;
|
||||
run.default_condition(build_miri)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(DontDistWithMiriEnabled);
|
||||
}
|
||||
|
||||
fn run(self, _: &Builder) -> PathBuf {
|
||||
panic!("Do not distribute with miri enabled.\n\
|
||||
The distributed libraries would include all MIR (increasing binary size).
|
||||
The distributed MIR would include validation statements.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Extended {
|
||||
stage: u32,
|
||||
|
|
|
@ -429,7 +429,7 @@ impl Step for Std {
|
|||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
let builder = run.builder;
|
||||
run.krate("std").default_condition(builder.build.config.docs)
|
||||
run.all_krates("std").default_condition(builder.build.config.docs)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
|
|
@ -42,6 +42,7 @@ pub struct Flags {
|
|||
pub jobs: Option<u32>,
|
||||
pub cmd: Subcommand,
|
||||
pub incremental: bool,
|
||||
pub exclude: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
pub enum Subcommand {
|
||||
|
@ -109,6 +110,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||
opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
|
||||
opts.optmulti("", "host", "host targets to build", "HOST");
|
||||
opts.optmulti("", "target", "target targets to build", "TARGET");
|
||||
opts.optmulti("", "exclude", "build paths to exclude", "PATH");
|
||||
opts.optopt("", "on-fail", "command to run on failure", "CMD");
|
||||
opts.optopt("", "stage", "stage to build", "N");
|
||||
opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
|
||||
|
@ -273,7 +275,12 @@ Arguments:
|
|||
};
|
||||
// Get any optional paths which occur after the subcommand
|
||||
let cwd = t!(env::current_dir());
|
||||
let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();
|
||||
let src = matches.opt_str("src").map(PathBuf::from)
|
||||
.or_else(|| env::var_os("SRC").map(PathBuf::from))
|
||||
.unwrap_or(cwd.clone());
|
||||
let paths = matches.free[1..].iter().map(|p| {
|
||||
cwd.join(p).strip_prefix(&src).expect("paths passed to be inside checkout").into()
|
||||
}).collect::<Vec<PathBuf>>();
|
||||
|
||||
let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
|
||||
if fs::metadata("config.toml").is_ok() {
|
||||
|
@ -358,11 +365,6 @@ Arguments:
|
|||
stage = Some(1);
|
||||
}
|
||||
|
||||
let cwd = t!(env::current_dir());
|
||||
let src = matches.opt_str("src").map(PathBuf::from)
|
||||
.or_else(|| env::var_os("SRC").map(PathBuf::from))
|
||||
.unwrap_or(cwd);
|
||||
|
||||
Flags {
|
||||
verbose: matches.opt_count("verbose"),
|
||||
stage,
|
||||
|
@ -374,10 +376,14 @@ Arguments:
|
|||
target: split(matches.opt_strs("target"))
|
||||
.into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
|
||||
config: cfg_file,
|
||||
src,
|
||||
jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
|
||||
cmd,
|
||||
incremental: matches.opt_present("incremental"),
|
||||
exclude: split(matches.opt_strs("exclude"))
|
||||
.into_iter().map(|p| {
|
||||
cwd.join(p).strip_prefix(&src).expect("paths to be inside checkout").into()
|
||||
}).collect::<Vec<_>>(),
|
||||
src,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,9 +113,8 @@
|
|||
//! More documentation can be found in each respective module below, and you can
|
||||
//! also check out the `src/bootstrap/README.md` file for more information.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![allow(stable_features)]
|
||||
#![feature(associated_consts)]
|
||||
//#![deny(warnings)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate build_helper;
|
||||
|
@ -267,6 +266,18 @@ struct Crate {
|
|||
bench_step: String,
|
||||
}
|
||||
|
||||
impl Crate {
|
||||
fn is_local(&self, build: &Build) -> bool {
|
||||
self.path.starts_with(&build.config.src) &&
|
||||
!self.path.to_string_lossy().ends_with("_shim")
|
||||
}
|
||||
|
||||
fn local_path(&self, build: &Build) -> PathBuf {
|
||||
assert!(self.is_local(build));
|
||||
self.path.strip_prefix(&build.config.src).unwrap().into()
|
||||
}
|
||||
}
|
||||
|
||||
/// The various "modes" of invoking Cargo.
|
||||
///
|
||||
/// These entries currently correspond to the various output directories of the
|
||||
|
@ -949,25 +960,21 @@ impl Build {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a list of crates from a root crate.
|
||||
///
|
||||
/// Returns Vec<(crate, path to crate, is_root_crate)>
|
||||
fn crates(&self, root: &str) -> Vec<(Interned<String>, &Path)> {
|
||||
let interned = INTERNER.intern_string(root.to_owned());
|
||||
fn in_tree_crates(&self, root: &str) -> Vec<&Crate> {
|
||||
let mut ret = Vec::new();
|
||||
let mut list = vec![interned];
|
||||
let mut list = vec![INTERNER.intern_str(root)];
|
||||
let mut visited = HashSet::new();
|
||||
while let Some(krate) = list.pop() {
|
||||
let krate = &self.crates[&krate];
|
||||
// If we can't strip prefix, then out-of-tree path
|
||||
let path = krate.path.strip_prefix(&self.src).unwrap_or(&krate.path);
|
||||
ret.push((krate.name, path));
|
||||
if krate.is_local(self) {
|
||||
ret.push(krate);
|
||||
for dep in &krate.deps {
|
||||
if visited.insert(dep) && dep != "build_helper" {
|
||||
list.push(*dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,9 +51,7 @@ impl Step for Llvm {
|
|||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let emscripten = run.path.map(|p| {
|
||||
p.ends_with("llvm-emscripten")
|
||||
}).unwrap_or(false);
|
||||
let emscripten = run.path.ends_with("llvm-emscripten");
|
||||
run.builder.ensure(Llvm {
|
||||
target: run.target,
|
||||
emscripten,
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
//! This file implements the various regression test suites that we execute on
|
||||
//! our CI.
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::iter;
|
||||
|
@ -26,6 +25,7 @@ use std::io::Read;
|
|||
use build_helper::{self, output};
|
||||
|
||||
use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step};
|
||||
use Crate as CargoCrate;
|
||||
use cache::{INTERNER, Interned};
|
||||
use compile;
|
||||
use dist;
|
||||
|
@ -550,180 +550,213 @@ fn testdir(build: &Build, host: Interned<String>) -> PathBuf {
|
|||
build.out.join(host).join("test")
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct Test {
|
||||
path: &'static str,
|
||||
mode: &'static str,
|
||||
suite: &'static str,
|
||||
macro_rules! default_test {
|
||||
($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => {
|
||||
test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false });
|
||||
}
|
||||
}
|
||||
|
||||
static DEFAULT_COMPILETESTS: &[Test] = &[
|
||||
Test { path: "src/test/ui", mode: "ui", suite: "ui" },
|
||||
Test { path: "src/test/run-pass", mode: "run-pass", suite: "run-pass" },
|
||||
Test { path: "src/test/compile-fail", mode: "compile-fail", suite: "compile-fail" },
|
||||
Test { path: "src/test/parse-fail", mode: "parse-fail", suite: "parse-fail" },
|
||||
Test { path: "src/test/run-fail", mode: "run-fail", suite: "run-fail" },
|
||||
Test {
|
||||
macro_rules! host_test {
|
||||
($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => {
|
||||
test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true });
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! test {
|
||||
($name:ident {
|
||||
path: $path:expr,
|
||||
mode: $mode:expr,
|
||||
suite: $suite:expr,
|
||||
default: $default:expr,
|
||||
host: $host:expr
|
||||
}) => {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct $name {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for $name {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = $default;
|
||||
const ONLY_HOSTS: bool = $host;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path($path)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
||||
|
||||
run.builder.ensure($name {
|
||||
compiler,
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Compiletest {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
mode: $mode,
|
||||
suite: $suite,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default_test!(Ui {
|
||||
path: "src/test/ui",
|
||||
mode: "ui",
|
||||
suite: "ui"
|
||||
});
|
||||
|
||||
default_test!(RunPass {
|
||||
path: "src/test/run-pass",
|
||||
mode: "run-pass",
|
||||
suite: "run-pass"
|
||||
});
|
||||
|
||||
default_test!(CompileFail {
|
||||
path: "src/test/compile-fail",
|
||||
mode: "compile-fail",
|
||||
suite: "compile-fail"
|
||||
});
|
||||
|
||||
default_test!(ParseFail {
|
||||
path: "src/test/parse-fail",
|
||||
mode: "parse-fail",
|
||||
suite: "parse-fail"
|
||||
});
|
||||
|
||||
default_test!(RunFail {
|
||||
path: "src/test/run-fail",
|
||||
mode: "run-fail",
|
||||
suite: "run-fail"
|
||||
});
|
||||
|
||||
default_test!(RunPassValgrind {
|
||||
path: "src/test/run-pass-valgrind",
|
||||
mode: "run-pass-valgrind",
|
||||
suite: "run-pass-valgrind"
|
||||
},
|
||||
Test { path: "src/test/mir-opt", mode: "mir-opt", suite: "mir-opt" },
|
||||
Test { path: "src/test/codegen", mode: "codegen", suite: "codegen" },
|
||||
Test { path: "src/test/codegen-units", mode: "codegen-units", suite: "codegen-units" },
|
||||
Test { path: "src/test/incremental", mode: "incremental", suite: "incremental" },
|
||||
});
|
||||
|
||||
default_test!(MirOpt {
|
||||
path: "src/test/mir-opt",
|
||||
mode: "mir-opt",
|
||||
suite: "mir-opt"
|
||||
});
|
||||
|
||||
default_test!(Codegen {
|
||||
path: "src/test/codegen",
|
||||
mode: "codegen",
|
||||
suite: "codegen"
|
||||
});
|
||||
|
||||
default_test!(CodegenUnits {
|
||||
path: "src/test/codegen-units",
|
||||
mode: "codegen-units",
|
||||
suite: "codegen-units"
|
||||
});
|
||||
|
||||
default_test!(Incremental {
|
||||
path: "src/test/incremental",
|
||||
mode: "incremental",
|
||||
suite: "incremental"
|
||||
});
|
||||
|
||||
default_test!(Debuginfo {
|
||||
path: "src/test/debuginfo",
|
||||
// What this runs varies depending on the native platform being apple
|
||||
Test { path: "src/test/debuginfo", mode: "debuginfo-XXX", suite: "debuginfo" },
|
||||
];
|
||||
mode: "debuginfo-XXX",
|
||||
suite: "debuginfo"
|
||||
});
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct DefaultCompiletest {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: &'static str,
|
||||
suite: &'static str,
|
||||
}
|
||||
host_test!(UiFullDeps {
|
||||
path: "src/test/ui-fulldeps",
|
||||
mode: "ui",
|
||||
suite: "ui-fulldeps"
|
||||
});
|
||||
|
||||
impl Step for DefaultCompiletest {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
host_test!(RunPassFullDeps {
|
||||
path: "src/test/run-pass-fulldeps",
|
||||
mode: "run-pass",
|
||||
suite: "run-pass-fulldeps"
|
||||
});
|
||||
|
||||
fn should_run(mut run: ShouldRun) -> ShouldRun {
|
||||
for test in DEFAULT_COMPILETESTS {
|
||||
run = run.path(test.path);
|
||||
}
|
||||
run
|
||||
}
|
||||
host_test!(RunFailFullDeps {
|
||||
path: "src/test/run-fail-fulldeps",
|
||||
mode: "run-fail",
|
||||
suite: "run-fail-fulldeps"
|
||||
});
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
||||
|
||||
let test = run.path.map(|path| {
|
||||
DEFAULT_COMPILETESTS.iter().find(|&&test| {
|
||||
path.ends_with(test.path)
|
||||
}).unwrap_or_else(|| {
|
||||
panic!("make_run in compile test to receive test path, received {:?}", path);
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(test) = test {
|
||||
run.builder.ensure(DefaultCompiletest {
|
||||
compiler,
|
||||
target: run.target,
|
||||
mode: test.mode,
|
||||
suite: test.suite,
|
||||
});
|
||||
} else {
|
||||
for test in DEFAULT_COMPILETESTS {
|
||||
run.builder.ensure(DefaultCompiletest {
|
||||
compiler,
|
||||
target: run.target,
|
||||
mode: test.mode,
|
||||
suite: test.suite
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Compiletest {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
mode: self.mode,
|
||||
suite: self.suite,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Also default, but host-only.
|
||||
static HOST_COMPILETESTS: &[Test] = &[
|
||||
Test { path: "src/test/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" },
|
||||
Test { path: "src/test/run-pass-fulldeps", mode: "run-pass", suite: "run-pass-fulldeps" },
|
||||
Test { path: "src/test/run-fail-fulldeps", mode: "run-fail", suite: "run-fail-fulldeps" },
|
||||
Test {
|
||||
host_test!(CompileFailFullDeps {
|
||||
path: "src/test/compile-fail-fulldeps",
|
||||
mode: "compile-fail",
|
||||
suite: "compile-fail-fulldeps",
|
||||
},
|
||||
Test {
|
||||
suite: "compile-fail-fulldeps"
|
||||
});
|
||||
|
||||
host_test!(IncrementalFullDeps {
|
||||
path: "src/test/incremental-fulldeps",
|
||||
mode: "incremental",
|
||||
suite: "incremental-fulldeps",
|
||||
},
|
||||
Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" },
|
||||
suite: "incremental-fulldeps"
|
||||
});
|
||||
|
||||
Test { path: "src/test/pretty", mode: "pretty", suite: "pretty" },
|
||||
Test { path: "src/test/run-pass/pretty", mode: "pretty", suite: "run-pass" },
|
||||
Test { path: "src/test/run-fail/pretty", mode: "pretty", suite: "run-fail" },
|
||||
Test { path: "src/test/run-pass-valgrind/pretty", mode: "pretty", suite: "run-pass-valgrind" },
|
||||
Test { path: "src/test/run-pass-fulldeps/pretty", mode: "pretty", suite: "run-pass-fulldeps" },
|
||||
Test { path: "src/test/run-fail-fulldeps/pretty", mode: "pretty", suite: "run-fail-fulldeps" },
|
||||
Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" },
|
||||
];
|
||||
host_test!(Rustdoc {
|
||||
path: "src/test/rustdoc",
|
||||
mode: "rustdoc",
|
||||
suite: "rustdoc"
|
||||
});
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct HostCompiletest {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: &'static str,
|
||||
suite: &'static str,
|
||||
}
|
||||
test!(Pretty {
|
||||
path: "src/test/pretty",
|
||||
mode: "pretty",
|
||||
suite: "pretty",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
test!(RunPassPretty {
|
||||
path: "src/test/run-pass/pretty",
|
||||
mode: "pretty",
|
||||
suite: "run-pass",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
test!(RunFailPretty {
|
||||
path: "src/test/run-fail/pretty",
|
||||
mode: "pretty",
|
||||
suite: "run-fail",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
test!(RunPassValgrindPretty {
|
||||
path: "src/test/run-pass-valgrind/pretty",
|
||||
mode: "pretty",
|
||||
suite: "run-pass-valgrind",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
test!(RunPassFullDepsPretty {
|
||||
path: "src/test/run-pass-fulldeps/pretty",
|
||||
mode: "pretty",
|
||||
suite: "run-pass-fulldeps",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
test!(RunFailFullDepsPretty {
|
||||
path: "src/test/run-fail-fulldeps/pretty",
|
||||
mode: "pretty",
|
||||
suite: "run-fail-fulldeps",
|
||||
default: false,
|
||||
host: true
|
||||
});
|
||||
|
||||
impl Step for HostCompiletest {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(mut run: ShouldRun) -> ShouldRun {
|
||||
for test in HOST_COMPILETESTS {
|
||||
run = run.path(test.path);
|
||||
}
|
||||
run
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let compiler = run.builder.compiler(run.builder.top_stage, run.host);
|
||||
|
||||
let test = run.path.map(|path| {
|
||||
HOST_COMPILETESTS.iter().find(|&&test| {
|
||||
path.ends_with(test.path)
|
||||
}).unwrap_or_else(|| {
|
||||
panic!("make_run in compile test to receive test path, received {:?}", path);
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(test) = test {
|
||||
run.builder.ensure(HostCompiletest {
|
||||
compiler,
|
||||
target: run.target,
|
||||
mode: test.mode,
|
||||
suite: test.suite,
|
||||
});
|
||||
} else {
|
||||
for test in HOST_COMPILETESTS {
|
||||
if test.mode == "pretty" {
|
||||
continue;
|
||||
}
|
||||
run.builder.ensure(HostCompiletest {
|
||||
compiler,
|
||||
target: run.target,
|
||||
mode: test.mode,
|
||||
suite: test.suite
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Compiletest {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
mode: self.mode,
|
||||
suite: self.suite,
|
||||
})
|
||||
}
|
||||
}
|
||||
host_test!(RunMake {
|
||||
path: "src/test/run-make",
|
||||
mode: "run-make",
|
||||
suite: "run-make"
|
||||
});
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct Compiletest {
|
||||
|
@ -902,7 +935,7 @@ impl Step for Compiletest {
|
|||
}
|
||||
}
|
||||
if suite == "run-make" && !build.config.llvm_enabled {
|
||||
println!("Ignoring run-make test suite as they generally don't work without LLVM");
|
||||
println!("Ignoring run-make test suite as they generally dont work without LLVM");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1099,7 +1132,7 @@ pub struct CrateLibrustc {
|
|||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
test_kind: TestKind,
|
||||
krate: Option<Interned<String>>,
|
||||
krate: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for CrateLibrustc {
|
||||
|
@ -1115,7 +1148,8 @@ impl Step for CrateLibrustc {
|
|||
let builder = run.builder;
|
||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||
|
||||
let make = |name: Option<Interned<String>>| {
|
||||
for krate in builder.in_tree_crates("rustc-main") {
|
||||
if run.path.ends_with(&krate.path) {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
|
@ -1128,21 +1162,11 @@ impl Step for CrateLibrustc {
|
|||
compiler,
|
||||
target: run.target,
|
||||
test_kind,
|
||||
krate: name,
|
||||
krate: krate.name,
|
||||
});
|
||||
};
|
||||
|
||||
if let Some(path) = run.path {
|
||||
for (name, krate_path) in builder.crates("rustc-main") {
|
||||
if path.ends_with(krate_path) {
|
||||
make(Some(name));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
make(None);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Crate {
|
||||
|
@ -1156,27 +1180,95 @@ impl Step for CrateLibrustc {
|
|||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Crate {
|
||||
pub struct CrateNotDefault {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: Mode,
|
||||
test_kind: TestKind,
|
||||
krate: Option<Interned<String>>,
|
||||
krate: &'static str,
|
||||
}
|
||||
|
||||
impl Step for Crate {
|
||||
impl Step for CrateNotDefault {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.krate("std").krate("test")
|
||||
run.path("src/liballoc_jemalloc")
|
||||
.path("src/librustc_asan")
|
||||
.path("src/librustc_lsan")
|
||||
.path("src/librustc_msan")
|
||||
.path("src/librustc_tsan")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let builder = run.builder;
|
||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||
|
||||
let make = |mode: Mode, name: Option<Interned<String>>| {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
TestKind::Bench
|
||||
} else {
|
||||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
|
||||
builder.ensure(CrateNotDefault {
|
||||
compiler,
|
||||
target: run.target,
|
||||
test_kind,
|
||||
krate: match run.path {
|
||||
_ if run.path.ends_with("src/liballoc_jemalloc") => "alloc_jemalloc",
|
||||
_ if run.path.ends_with("src/librustc_asan") => "rustc_asan",
|
||||
_ if run.path.ends_with("src/librustc_lsan") => "rustc_lsan",
|
||||
_ if run.path.ends_with("src/librustc_msan") => "rustc_msan",
|
||||
_ if run.path.ends_with("src/librustc_tsan") => "rustc_tsan",
|
||||
_ => panic!("unexpected path {:?}", run.path),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Crate {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
mode: Mode::Libstd,
|
||||
test_kind: self.test_kind,
|
||||
krate: INTERNER.intern_str(self.krate),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Crate {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: Mode,
|
||||
test_kind: TestKind,
|
||||
krate: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Crate {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(mut run: ShouldRun) -> ShouldRun {
|
||||
let builder = run.builder;
|
||||
run = run.krate("test");
|
||||
for krate in run.builder.in_tree_crates("std") {
|
||||
if krate.is_local(&run.builder) &&
|
||||
!krate.name.contains("jemalloc") &&
|
||||
!(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) &&
|
||||
krate.name != "dlmalloc" {
|
||||
run = run.path(krate.local_path(&builder).to_str().unwrap());
|
||||
}
|
||||
}
|
||||
run
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
let builder = run.builder;
|
||||
let compiler = builder.compiler(builder.top_stage, run.host);
|
||||
|
||||
let make = |mode: Mode, krate: &CargoCrate| {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
|
@ -1190,29 +1282,24 @@ impl Step for Crate {
|
|||
target: run.target,
|
||||
mode,
|
||||
test_kind,
|
||||
krate: name,
|
||||
krate: krate.name,
|
||||
});
|
||||
};
|
||||
|
||||
if let Some(path) = run.path {
|
||||
for (name, krate_path) in builder.crates("std") {
|
||||
if path.ends_with(krate_path) {
|
||||
make(Mode::Libstd, Some(name));
|
||||
for krate in builder.in_tree_crates("std") {
|
||||
if run.path.ends_with(&krate.local_path(&builder)) {
|
||||
make(Mode::Libstd, krate);
|
||||
}
|
||||
}
|
||||
for (name, krate_path) in builder.crates("test") {
|
||||
if path.ends_with(krate_path) {
|
||||
make(Mode::Libtest, Some(name));
|
||||
for krate in builder.in_tree_crates("test") {
|
||||
if run.path.ends_with(&krate.local_path(&builder)) {
|
||||
make(Mode::Libtest, krate);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
make(Mode::Libstd, None);
|
||||
make(Mode::Libtest, None);
|
||||
}
|
||||
}
|
||||
|
||||
/// Run all unit tests plus documentation tests for an entire crate DAG defined
|
||||
/// by a `Cargo.toml`
|
||||
/// Run all unit tests plus documentation tests for a given crate defined
|
||||
/// by a `Cargo.toml` (single manifest)
|
||||
///
|
||||
/// This is what runs tests for crates like the standard library, compiler, etc.
|
||||
/// It essentially is the driver for running `cargo test`.
|
||||
|
@ -1241,27 +1328,23 @@ impl Step for Crate {
|
|||
};
|
||||
|
||||
let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
|
||||
let (name, root) = match mode {
|
||||
match mode {
|
||||
Mode::Libstd => {
|
||||
compile::std_cargo(build, &compiler, target, &mut cargo);
|
||||
("libstd", "std")
|
||||
}
|
||||
Mode::Libtest => {
|
||||
compile::test_cargo(build, &compiler, target, &mut cargo);
|
||||
("libtest", "test")
|
||||
}
|
||||
Mode::Librustc => {
|
||||
builder.ensure(compile::Rustc { compiler, target });
|
||||
compile::rustc_cargo(build, &mut cargo);
|
||||
("librustc", "rustc-main")
|
||||
}
|
||||
_ => panic!("can only test libraries"),
|
||||
};
|
||||
let root = INTERNER.intern_string(String::from(root));
|
||||
let _folder = build.fold_output(|| {
|
||||
format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, name)
|
||||
format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, krate)
|
||||
});
|
||||
println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage,
|
||||
println!("{} {} stage{} ({} -> {})", test_kind, krate, compiler.stage,
|
||||
&compiler.host, target);
|
||||
|
||||
// Build up the base `cargo test` command.
|
||||
|
@ -1273,37 +1356,7 @@ impl Step for Crate {
|
|||
cargo.arg("--no-fail-fast");
|
||||
}
|
||||
|
||||
match krate {
|
||||
Some(krate) => {
|
||||
cargo.arg("-p").arg(krate);
|
||||
}
|
||||
None => {
|
||||
let mut visited = HashSet::new();
|
||||
let mut next = vec![root];
|
||||
while let Some(name) = next.pop() {
|
||||
// Right now jemalloc and the sanitizer crates are
|
||||
// target-specific crate in the sense that it's not present
|
||||
// on all platforms. Custom skip it here for now, but if we
|
||||
// add more this probably wants to get more generalized.
|
||||
//
|
||||
// Also skip `build_helper` as it's not compiled normally
|
||||
// for target during the bootstrap and it's just meant to be
|
||||
// a helper crate, not tested. If it leaks through then it
|
||||
// ends up messing with various mtime calculations and such.
|
||||
if !name.contains("jemalloc") &&
|
||||
*name != *"build_helper" &&
|
||||
!(name.starts_with("rustc_") && name.ends_with("san")) &&
|
||||
name != "dlmalloc" {
|
||||
cargo.arg("-p").arg(&format!("{}:0.0.0", name));
|
||||
}
|
||||
for dep in build.crates[&name].deps.iter() {
|
||||
if visited.insert(dep) {
|
||||
next.push(*dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The tests are going to run with the *target* libraries, so we need to
|
||||
// ensure that those libraries show up in the LD_LIBRARY_PATH equivalent.
|
||||
|
@ -1355,18 +1408,18 @@ impl Step for Crate {
|
|||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustdoc {
|
||||
pub struct CrateRustdoc {
|
||||
host: Interned<String>,
|
||||
test_kind: TestKind,
|
||||
}
|
||||
|
||||
impl Step for Rustdoc {
|
||||
impl Step for CrateRustdoc {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/librustdoc").path("src/tools/rustdoc")
|
||||
run.paths(&["src/librustdoc", "src/tools/rustdoc"])
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
|
@ -1380,7 +1433,7 @@ impl Step for Rustdoc {
|
|||
panic!("unexpected builder.kind in crate: {:?}", builder.kind);
|
||||
};
|
||||
|
||||
builder.ensure(Rustdoc {
|
||||
builder.ensure(CrateRustdoc {
|
||||
host: run.host,
|
||||
test_kind,
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue