Add ./x.py check src/{libstd,libtest,rustc}.
This currently only supports a limited subset of the full compilation, but is likely 90% of what people will want and is possible without building a full compiler (i.e., running LLVM). In theory, this means that contributors who don't want to build LLVM now have an easy way to compile locally, though running tests won't work.
This commit is contained in:
parent
734ee0fb43
commit
6aeb1cfb64
7 changed files with 211 additions and 27 deletions
|
@ -125,11 +125,6 @@ fn main() {
|
|||
cmd.arg(format!("-Clinker={}", target_linker));
|
||||
}
|
||||
|
||||
// Pass down incremental directory, if any.
|
||||
if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
|
||||
cmd.arg(format!("-Zincremental={}", dir));
|
||||
}
|
||||
|
||||
let crate_name = args.windows(2)
|
||||
.find(|a| &*a[0] == "--crate-name")
|
||||
.unwrap();
|
||||
|
|
|
@ -602,6 +602,7 @@ class RustBuild(object):
|
|||
env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
|
||||
(os.pathsep + env["LIBRARY_PATH"]) \
|
||||
if "LIBRARY_PATH" in env else ""
|
||||
env["RUSTFLAGS"] = "-Cdebuginfo=2"
|
||||
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
|
||||
os.pathsep + env["PATH"]
|
||||
if not os.path.isfile(self.cargo()):
|
||||
|
|
|
@ -26,6 +26,7 @@ use util::{exe, libdir, add_lib_path};
|
|||
use {Build, Mode};
|
||||
use cache::{INTERNER, Interned, Cache};
|
||||
use check;
|
||||
use test;
|
||||
use flags::Subcommand;
|
||||
use doc;
|
||||
use tool;
|
||||
|
@ -230,6 +231,7 @@ impl<'a> ShouldRun<'a> {
|
|||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Kind {
|
||||
Build,
|
||||
Check,
|
||||
Test,
|
||||
Bench,
|
||||
Dist,
|
||||
|
@ -251,13 +253,13 @@ impl<'a> Builder<'a> {
|
|||
tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient,
|
||||
tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy,
|
||||
native::Llvm, tool::Rustfmt, tool::Miri),
|
||||
Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest,
|
||||
check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc,
|
||||
check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs,
|
||||
check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy,
|
||||
check::RustdocJS),
|
||||
|
||||
Kind::Bench => describe!(check::Crate, check::CrateLibrustc),
|
||||
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),
|
||||
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),
|
||||
|
@ -304,6 +306,7 @@ impl<'a> Builder<'a> {
|
|||
pub fn run(build: &Build) {
|
||||
let (kind, paths) = match build.config.cmd {
|
||||
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
|
||||
Subcommand::Check { ref paths } => (Kind::Check, &paths[..]),
|
||||
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
|
||||
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
|
||||
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
|
||||
|
@ -493,13 +496,14 @@ impl<'a> Builder<'a> {
|
|||
cargo.env("RUSTC_CODEGEN_UNITS", n.to_string());
|
||||
}
|
||||
|
||||
|
||||
if let Some(host_linker) = self.build.linker(compiler.host) {
|
||||
cargo.env("RUSTC_HOST_LINKER", host_linker);
|
||||
}
|
||||
if let Some(target_linker) = self.build.linker(target) {
|
||||
cargo.env("RUSTC_TARGET_LINKER", target_linker);
|
||||
}
|
||||
if cmd != "build" {
|
||||
if cmd != "build" && cmd != "check" {
|
||||
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.build.build)));
|
||||
}
|
||||
|
||||
|
@ -566,8 +570,7 @@ impl<'a> Builder<'a> {
|
|||
// not guaranteeing correctness across builds if the compiler
|
||||
// is changing under your feet.`
|
||||
if self.config.incremental && compiler.stage == 0 {
|
||||
let incr_dir = self.incremental_dir(compiler);
|
||||
cargo.env("RUSTC_INCREMENTAL", incr_dir);
|
||||
cargo.env("CARGO_INCREMENTAL", "1");
|
||||
}
|
||||
|
||||
if let Some(ref on_fail) = self.config.on_fail {
|
||||
|
|
163
src/bootstrap/check.rs
Normal file
163
src/bootstrap/check.rs
Normal file
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementation of compiling the compiler and standard library, in "check" mode.
|
||||
|
||||
use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, add_to_sysroot};
|
||||
use builder::{RunConfig, Builder, ShouldRun, Step};
|
||||
use {Build, Compiler, Mode};
|
||||
use cache::Interned;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Std {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Std {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libstd").krate("std")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(Std {
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
let build = builder.build;
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(0, build.build);
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
|
||||
println!("Checking std artifacts ({} -> {})", &compiler.host, target);
|
||||
|
||||
let out_dir = build.stage_out(compiler, Mode::Libstd);
|
||||
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
||||
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check");
|
||||
std_cargo(build, &compiler, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&libstd_stamp(build, compiler, target),
|
||||
true);
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustc {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Rustc {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/librustc").krate("rustc-main")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(Rustc {
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Build the compiler.
|
||||
///
|
||||
/// This will build the compiler for a particular stage of the build using
|
||||
/// the `compiler` targeting the `target` architecture. The artifacts
|
||||
/// created will also be linked into the sysroot directory.
|
||||
fn run(self, builder: &Builder) {
|
||||
let build = builder.build;
|
||||
let compiler = builder.compiler(0, build.build);
|
||||
let target = self.target;
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
|
||||
println!("Checking compiler artifacts ({} -> {})", &compiler.host, target);
|
||||
|
||||
let stage_out = builder.stage_out(compiler, Mode::Librustc);
|
||||
build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target));
|
||||
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
|
||||
|
||||
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
|
||||
rustc_cargo(build, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&librustc_stamp(build, compiler, target),
|
||||
true);
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
add_to_sysroot(&libdir, &librustc_stamp(build, compiler, target));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Test {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
run.path("src/libtest").krate("test")
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(Test {
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
let build = builder.build;
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(0, build.build);
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
|
||||
println!("Checking test artifacts ({} -> {})", &compiler.host, target);
|
||||
let out_dir = build.stage_out(compiler, Mode::Libtest);
|
||||
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
||||
let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check");
|
||||
test_cargo(build, &compiler, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&libtest_stamp(build, compiler, target),
|
||||
true);
|
||||
let libdir = builder.sysroot_libdir(compiler, target);
|
||||
add_to_sysroot(&libdir, &libtest_stamp(build, compiler, target));
|
||||
}
|
||||
}
|
||||
|
||||
/// Cargo's output path for the standard library in a given stage, compiled
|
||||
/// by a particular compiler for the specified target.
|
||||
pub fn libstd_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Libstd, target).join(".libstd-check.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for libtest in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn libtest_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Libtest, target).join(".libtest-check.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for librustc in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
|
||||
}
|
||||
|
|
@ -108,7 +108,8 @@ impl Step for Std {
|
|||
std_cargo(build, &compiler, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&libstd_stamp(build, compiler, target));
|
||||
&libstd_stamp(build, compiler, target),
|
||||
false);
|
||||
|
||||
builder.ensure(StdLink {
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
|
@ -360,7 +361,8 @@ impl Step for Test {
|
|||
test_cargo(build, &compiler, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&libtest_stamp(build, compiler, target));
|
||||
&libtest_stamp(build, compiler, target),
|
||||
false);
|
||||
|
||||
builder.ensure(TestLink {
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
|
@ -488,7 +490,8 @@ impl Step for Rustc {
|
|||
rustc_cargo(build, target, &mut cargo);
|
||||
run_cargo(build,
|
||||
&mut cargo,
|
||||
&librustc_stamp(build, compiler, target));
|
||||
&librustc_stamp(build, compiler, target),
|
||||
false);
|
||||
|
||||
builder.ensure(RustcLink {
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
|
@ -755,7 +758,7 @@ impl Step for Assemble {
|
|||
///
|
||||
/// For a particular stage this will link the file listed in `stamp` into the
|
||||
/// `sysroot_dst` provided.
|
||||
fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
||||
pub fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
|
||||
t!(fs::create_dir_all(&sysroot_dst));
|
||||
for path in read_stamp_file(stamp) {
|
||||
copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
|
||||
|
@ -785,7 +788,7 @@ fn stderr_isatty() -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
||||
pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: bool) {
|
||||
// Instruct Cargo to give us json messages on stdout, critically leaving
|
||||
// stderr as piped so we can get those pretty colors.
|
||||
cargo.arg("--message-format").arg("json")
|
||||
|
@ -836,7 +839,8 @@ fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
|
|||
// Skip files like executables
|
||||
if !filename.ends_with(".rlib") &&
|
||||
!filename.ends_with(".lib") &&
|
||||
!is_dylib(&filename) {
|
||||
!is_dylib(&filename) &&
|
||||
!(is_check && filename.ends_with(".rmeta")) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ pub enum Subcommand {
|
|||
Build {
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
Check {
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
Doc {
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
|
@ -88,6 +91,7 @@ Usage: x.py <subcommand> [options] [<paths>...]
|
|||
|
||||
Subcommands:
|
||||
build Compile either the compiler or libraries
|
||||
check Compile either the compiler or libraries, using cargo check
|
||||
test Build and run some test suites
|
||||
bench Build and run some benchmarks
|
||||
doc Build documentation
|
||||
|
@ -128,6 +132,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||
// there on out.
|
||||
let subcommand = args.iter().find(|&s|
|
||||
(s == "build")
|
||||
|| (s == "check")
|
||||
|| (s == "test")
|
||||
|| (s == "bench")
|
||||
|| (s == "doc")
|
||||
|
@ -217,6 +222,21 @@ Arguments:
|
|||
arguments would), and then use the compiler built in stage 0 to build
|
||||
src/libtest and its dependencies.
|
||||
Once this is done, build/$ARCH/stage1 contains a usable compiler.");
|
||||
}
|
||||
"check" => {
|
||||
subcommand_help.push_str("\n
|
||||
Arguments:
|
||||
This subcommand accepts a number of paths to directories to the crates
|
||||
and/or artifacts to compile. For example:
|
||||
|
||||
./x.py check src/libcore
|
||||
./x.py check src/libcore src/libproc_macro
|
||||
|
||||
If no arguments are passed then the complete artifacts are compiled: std, test, and rustc. Note
|
||||
also that since we use `cargo check`, by default this will automatically enable incremental
|
||||
compilation, so there's no need to pass it separately, though it won't hurt. We also completely
|
||||
ignore the stage passed, as there's no way to compile in non-stage 0 without actually building
|
||||
the compiler.");
|
||||
}
|
||||
"test" => {
|
||||
subcommand_help.push_str("\n
|
||||
|
@ -286,6 +306,9 @@ Arguments:
|
|||
"build" => {
|
||||
Subcommand::Build { paths: paths }
|
||||
}
|
||||
"check" => {
|
||||
Subcommand::Check { paths: paths }
|
||||
}
|
||||
"test" => {
|
||||
Subcommand::Test {
|
||||
paths,
|
||||
|
|
|
@ -150,6 +150,7 @@ use util::{exe, libdir, OutputFolder, CiEnv};
|
|||
mod cc_detect;
|
||||
mod channel;
|
||||
mod check;
|
||||
mod test;
|
||||
mod clean;
|
||||
mod compile;
|
||||
mod metadata;
|
||||
|
@ -449,12 +450,6 @@ impl Build {
|
|||
out
|
||||
}
|
||||
|
||||
/// Get the directory for incremental by-products when using the
|
||||
/// given compiler.
|
||||
fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
|
||||
self.out.join(&*compiler.host).join(format!("stage{}-incremental", compiler.stage))
|
||||
}
|
||||
|
||||
/// Returns the root directory for all output generated in a particular
|
||||
/// stage when running with a particular host compiler.
|
||||
///
|
||||
|
|
Loading…
Add table
Reference in a new issue