Skip to content

Commit 6aeb1cf

Browse files
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.
1 parent 734ee0f commit 6aeb1cf

File tree

7 files changed

+211
-27
lines changed

7 files changed

+211
-27
lines changed

src/bootstrap/bin/rustc.rs

-5
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,6 @@ fn main() {
125125
cmd.arg(format!("-Clinker={}", target_linker));
126126
}
127127

128-
// Pass down incremental directory, if any.
129-
if let Ok(dir) = env::var("RUSTC_INCREMENTAL") {
130-
cmd.arg(format!("-Zincremental={}", dir));
131-
}
132-
133128
let crate_name = args.windows(2)
134129
.find(|a| &*a[0] == "--crate-name")
135130
.unwrap();

src/bootstrap/bootstrap.py

+1
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ def build_bootstrap(self):
602602
env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
603603
(os.pathsep + env["LIBRARY_PATH"]) \
604604
if "LIBRARY_PATH" in env else ""
605+
env["RUSTFLAGS"] = "-Cdebuginfo=2"
605606
env["PATH"] = os.path.join(self.bin_root(), "bin") + \
606607
os.pathsep + env["PATH"]
607608
if not os.path.isfile(self.cargo()):

src/bootstrap/builder.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use util::{exe, libdir, add_lib_path};
2626
use {Build, Mode};
2727
use cache::{INTERNER, Interned, Cache};
2828
use check;
29+
use test;
2930
use flags::Subcommand;
3031
use doc;
3132
use tool;
@@ -230,6 +231,7 @@ impl<'a> ShouldRun<'a> {
230231
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
231232
pub enum Kind {
232233
Build,
234+
Check,
233235
Test,
234236
Bench,
235237
Dist,
@@ -251,13 +253,13 @@ impl<'a> Builder<'a> {
251253
tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient,
252254
tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy,
253255
native::Llvm, tool::Rustfmt, tool::Miri),
254-
Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest,
255-
check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc,
256-
check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs,
257-
check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy,
258-
check::RustdocJS),
259-
260-
Kind::Bench => describe!(check::Crate, check::CrateLibrustc),
256+
Kind::Check => describe!(check::Std, check::Test, check::Rustc),
257+
Kind::Test => describe!(test::Tidy, test::Bootstrap, test::DefaultCompiletest,
258+
test::HostCompiletest, test::Crate, test::CrateLibrustc, test::Rustdoc,
259+
test::Linkcheck, test::Cargotest, test::Cargo, test::Rls, test::Docs,
260+
test::ErrorIndex, test::Distcheck, test::Rustfmt, test::Miri, test::Clippy,
261+
test::RustdocJS),
262+
Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
261263
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
262264
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
263265
doc::Reference, doc::Rustdoc, doc::RustByExample, doc::CargoBook),
@@ -304,6 +306,7 @@ impl<'a> Builder<'a> {
304306
pub fn run(build: &Build) {
305307
let (kind, paths) = match build.config.cmd {
306308
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
309+
Subcommand::Check { ref paths } => (Kind::Check, &paths[..]),
307310
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
308311
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
309312
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
@@ -493,13 +496,14 @@ impl<'a> Builder<'a> {
493496
cargo.env("RUSTC_CODEGEN_UNITS", n.to_string());
494497
}
495498

499+
496500
if let Some(host_linker) = self.build.linker(compiler.host) {
497501
cargo.env("RUSTC_HOST_LINKER", host_linker);
498502
}
499503
if let Some(target_linker) = self.build.linker(target) {
500504
cargo.env("RUSTC_TARGET_LINKER", target_linker);
501505
}
502-
if cmd != "build" {
506+
if cmd != "build" && cmd != "check" {
503507
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.build.build)));
504508
}
505509

@@ -566,8 +570,7 @@ impl<'a> Builder<'a> {
566570
// not guaranteeing correctness across builds if the compiler
567571
// is changing under your feet.`
568572
if self.config.incremental && compiler.stage == 0 {
569-
let incr_dir = self.incremental_dir(compiler);
570-
cargo.env("RUSTC_INCREMENTAL", incr_dir);
573+
cargo.env("CARGO_INCREMENTAL", "1");
571574
}
572575

573576
if let Some(ref on_fail) = self.config.on_fail {

src/bootstrap/check.rs

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Implementation of compiling the compiler and standard library, in "check" mode.
12+
13+
use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, add_to_sysroot};
14+
use builder::{RunConfig, Builder, ShouldRun, Step};
15+
use {Build, Compiler, Mode};
16+
use cache::Interned;
17+
use std::path::PathBuf;
18+
19+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
20+
pub struct Std {
21+
pub target: Interned<String>,
22+
}
23+
24+
impl Step for Std {
25+
type Output = ();
26+
const DEFAULT: bool = true;
27+
28+
fn should_run(run: ShouldRun) -> ShouldRun {
29+
run.path("src/libstd").krate("std")
30+
}
31+
32+
fn make_run(run: RunConfig) {
33+
run.builder.ensure(Std {
34+
target: run.target,
35+
});
36+
}
37+
38+
fn run(self, builder: &Builder) {
39+
let build = builder.build;
40+
let target = self.target;
41+
let compiler = builder.compiler(0, build.build);
42+
43+
let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
44+
println!("Checking std artifacts ({} -> {})", &compiler.host, target);
45+
46+
let out_dir = build.stage_out(compiler, Mode::Libstd);
47+
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
48+
let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check");
49+
std_cargo(build, &compiler, target, &mut cargo);
50+
run_cargo(build,
51+
&mut cargo,
52+
&libstd_stamp(build, compiler, target),
53+
true);
54+
let libdir = builder.sysroot_libdir(compiler, target);
55+
add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
56+
}
57+
}
58+
59+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
60+
pub struct Rustc {
61+
pub target: Interned<String>,
62+
}
63+
64+
impl Step for Rustc {
65+
type Output = ();
66+
const ONLY_HOSTS: bool = true;
67+
const DEFAULT: bool = true;
68+
69+
fn should_run(run: ShouldRun) -> ShouldRun {
70+
run.path("src/librustc").krate("rustc-main")
71+
}
72+
73+
fn make_run(run: RunConfig) {
74+
run.builder.ensure(Rustc {
75+
target: run.target,
76+
});
77+
}
78+
79+
/// Build the compiler.
80+
///
81+
/// This will build the compiler for a particular stage of the build using
82+
/// the `compiler` targeting the `target` architecture. The artifacts
83+
/// created will also be linked into the sysroot directory.
84+
fn run(self, builder: &Builder) {
85+
let build = builder.build;
86+
let compiler = builder.compiler(0, build.build);
87+
let target = self.target;
88+
89+
let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
90+
println!("Checking compiler artifacts ({} -> {})", &compiler.host, target);
91+
92+
let stage_out = builder.stage_out(compiler, Mode::Librustc);
93+
build.clear_if_dirty(&stage_out, &libstd_stamp(build, compiler, target));
94+
build.clear_if_dirty(&stage_out, &libtest_stamp(build, compiler, target));
95+
96+
let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
97+
rustc_cargo(build, target, &mut cargo);
98+
run_cargo(build,
99+
&mut cargo,
100+
&librustc_stamp(build, compiler, target),
101+
true);
102+
let libdir = builder.sysroot_libdir(compiler, target);
103+
add_to_sysroot(&libdir, &librustc_stamp(build, compiler, target));
104+
}
105+
}
106+
107+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
108+
pub struct Test {
109+
pub target: Interned<String>,
110+
}
111+
112+
impl Step for Test {
113+
type Output = ();
114+
const DEFAULT: bool = true;
115+
116+
fn should_run(run: ShouldRun) -> ShouldRun {
117+
run.path("src/libtest").krate("test")
118+
}
119+
120+
fn make_run(run: RunConfig) {
121+
run.builder.ensure(Test {
122+
target: run.target,
123+
});
124+
}
125+
126+
fn run(self, builder: &Builder) {
127+
let build = builder.build;
128+
let target = self.target;
129+
let compiler = builder.compiler(0, build.build);
130+
131+
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
132+
println!("Checking test artifacts ({} -> {})", &compiler.host, target);
133+
let out_dir = build.stage_out(compiler, Mode::Libtest);
134+
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
135+
let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check");
136+
test_cargo(build, &compiler, target, &mut cargo);
137+
run_cargo(build,
138+
&mut cargo,
139+
&libtest_stamp(build, compiler, target),
140+
true);
141+
let libdir = builder.sysroot_libdir(compiler, target);
142+
add_to_sysroot(&libdir, &libtest_stamp(build, compiler, target));
143+
}
144+
}
145+
146+
/// Cargo's output path for the standard library in a given stage, compiled
147+
/// by a particular compiler for the specified target.
148+
pub fn libstd_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
149+
build.cargo_out(compiler, Mode::Libstd, target).join(".libstd-check.stamp")
150+
}
151+
152+
/// Cargo's output path for libtest in a given stage, compiled by a particular
153+
/// compiler for the specified target.
154+
pub fn libtest_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
155+
build.cargo_out(compiler, Mode::Libtest, target).join(".libtest-check.stamp")
156+
}
157+
158+
/// Cargo's output path for librustc in a given stage, compiled by a particular
159+
/// compiler for the specified target.
160+
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
161+
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
162+
}
163+

src/bootstrap/compile.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ impl Step for Std {
108108
std_cargo(build, &compiler, target, &mut cargo);
109109
run_cargo(build,
110110
&mut cargo,
111-
&libstd_stamp(build, compiler, target));
111+
&libstd_stamp(build, compiler, target),
112+
false);
112113

113114
builder.ensure(StdLink {
114115
compiler: builder.compiler(compiler.stage, build.build),
@@ -360,7 +361,8 @@ impl Step for Test {
360361
test_cargo(build, &compiler, target, &mut cargo);
361362
run_cargo(build,
362363
&mut cargo,
363-
&libtest_stamp(build, compiler, target));
364+
&libtest_stamp(build, compiler, target),
365+
false);
364366

365367
builder.ensure(TestLink {
366368
compiler: builder.compiler(compiler.stage, build.build),
@@ -488,7 +490,8 @@ impl Step for Rustc {
488490
rustc_cargo(build, target, &mut cargo);
489491
run_cargo(build,
490492
&mut cargo,
491-
&librustc_stamp(build, compiler, target));
493+
&librustc_stamp(build, compiler, target),
494+
false);
492495

493496
builder.ensure(RustcLink {
494497
compiler: builder.compiler(compiler.stage, build.build),
@@ -755,7 +758,7 @@ impl Step for Assemble {
755758
///
756759
/// For a particular stage this will link the file listed in `stamp` into the
757760
/// `sysroot_dst` provided.
758-
fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
761+
pub fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
759762
t!(fs::create_dir_all(&sysroot_dst));
760763
for path in read_stamp_file(stamp) {
761764
copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
@@ -785,7 +788,7 @@ fn stderr_isatty() -> bool {
785788
}
786789
}
787790

788-
fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
791+
pub fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path, is_check: bool) {
789792
// Instruct Cargo to give us json messages on stdout, critically leaving
790793
// stderr as piped so we can get those pretty colors.
791794
cargo.arg("--message-format").arg("json")
@@ -836,7 +839,8 @@ fn run_cargo(build: &Build, cargo: &mut Command, stamp: &Path) {
836839
// Skip files like executables
837840
if !filename.ends_with(".rlib") &&
838841
!filename.ends_with(".lib") &&
839-
!is_dylib(&filename) {
842+
!is_dylib(&filename) &&
843+
!(is_check && filename.ends_with(".rmeta")) {
840844
continue
841845
}
842846

src/bootstrap/flags.rs

+23
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ pub enum Subcommand {
4848
Build {
4949
paths: Vec<PathBuf>,
5050
},
51+
Check {
52+
paths: Vec<PathBuf>,
53+
},
5154
Doc {
5255
paths: Vec<PathBuf>,
5356
},
@@ -88,6 +91,7 @@ Usage: x.py <subcommand> [options] [<paths>...]
8891
8992
Subcommands:
9093
build Compile either the compiler or libraries
94+
check Compile either the compiler or libraries, using cargo check
9195
test Build and run some test suites
9296
bench Build and run some benchmarks
9397
doc Build documentation
@@ -128,6 +132,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
128132
// there on out.
129133
let subcommand = args.iter().find(|&s|
130134
(s == "build")
135+
|| (s == "check")
131136
|| (s == "test")
132137
|| (s == "bench")
133138
|| (s == "doc")
@@ -217,6 +222,21 @@ Arguments:
217222
arguments would), and then use the compiler built in stage 0 to build
218223
src/libtest and its dependencies.
219224
Once this is done, build/$ARCH/stage1 contains a usable compiler.");
225+
}
226+
"check" => {
227+
subcommand_help.push_str("\n
228+
Arguments:
229+
This subcommand accepts a number of paths to directories to the crates
230+
and/or artifacts to compile. For example:
231+
232+
./x.py check src/libcore
233+
./x.py check src/libcore src/libproc_macro
234+
235+
If no arguments are passed then the complete artifacts are compiled: std, test, and rustc. Note
236+
also that since we use `cargo check`, by default this will automatically enable incremental
237+
compilation, so there's no need to pass it separately, though it won't hurt. We also completely
238+
ignore the stage passed, as there's no way to compile in non-stage 0 without actually building
239+
the compiler.");
220240
}
221241
"test" => {
222242
subcommand_help.push_str("\n
@@ -286,6 +306,9 @@ Arguments:
286306
"build" => {
287307
Subcommand::Build { paths: paths }
288308
}
309+
"check" => {
310+
Subcommand::Check { paths: paths }
311+
}
289312
"test" => {
290313
Subcommand::Test {
291314
paths,

src/bootstrap/lib.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ use util::{exe, libdir, OutputFolder, CiEnv};
150150
mod cc_detect;
151151
mod channel;
152152
mod check;
153+
mod test;
153154
mod clean;
154155
mod compile;
155156
mod metadata;
@@ -449,12 +450,6 @@ impl Build {
449450
out
450451
}
451452

452-
/// Get the directory for incremental by-products when using the
453-
/// given compiler.
454-
fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
455-
self.out.join(&*compiler.host).join(format!("stage{}-incremental", compiler.stage))
456-
}
457-
458453
/// Returns the root directory for all output generated in a particular
459454
/// stage when running with a particular host compiler.
460455
///

0 commit comments

Comments
 (0)