impl<'a> Step<'a> for Linkcheck<'a> {
type Output = ();
+ const ONLY_HOSTS: bool = true;
+ const DEFAULT: bool = true;
/// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
///
let host = self.host;
println!("Linkcheck ({})", host);
- let compiler = Compiler::new(0, host);
+
+ builder.default_doc(None);
let _time = util::timeit();
- try_run(build, build.tool_cmd(&compiler, "linkchecker")
+ try_run(build, builder.tool_cmd(Tool::Linkchecker)
.arg(build.out.join(host).join("doc")));
}
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/linkchecker")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, _target: &str) {
+ if path.is_some() {
+ builder.ensure(Linkcheck { host });
+ } else {
+ if builder.build.config.docs {
+ builder.ensure(Linkcheck { host });
+ }
+ }
+ }
}
// rules.test("check-cargotest", "src/tools/cargotest")
impl<'a> Step<'a> for Cargotest<'a> {
type Output = ();
+ const ONLY_HOSTS: bool = true;
/// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
///
/// test` to ensure that we don't regress the test suites there.
fn run(self, builder: &Builder) {
let build = builder.build;
- let stage = self.stage;
- let host = self.host;
- let compiler = Compiler::new(stage, host);
+ let compiler = builder.compiler(self.stage, host);
+ builder.ensure(compile::Rustc { compiler, target: compiler.host });
// Note that this is a short, cryptic, and not scoped directory name. This
// is currently to minimize the length of path on Windows where we otherwise
t!(fs::create_dir_all(&out_dir));
let _time = util::timeit();
- let mut cmd = Command::new(build.tool(&Compiler::new(0, host), "cargotest"));
- build.prepare_tool_cmd(&compiler, &mut cmd);
+ let mut cmd = builder.tool_cmd(Tool::CargoTest);
try_run(build, cmd.arg(&build.initial_cargo)
.arg(&out_dir)
.env("RUSTC", build.compiler_path(&compiler))
impl<'a> Step<'a> for Cargo<'a> {
type Output = ();
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("cargo") // FIXME: Why is this not src/tools/cargo?
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
+ builder.ensure(TestCargo {
+ compiler: builder.compiler(builder.top_stage, host),
+ target,
+ });
+ }
/// Runs `cargo test` for `cargo` packaged with Rust.
fn run(self, builder: &Builder) {
let build = builder.build;
- let stage = self.stage;
- let ref compiler = Compiler::new(stage, host);
+ let compiler = builder.compiler(self.stage, self.host);
// Configure PATH to find the right rustc. NB. we have to use PATH
// and not RUSTC because the Cargo test suite has tests that will
// fail if rustc is not spelled `rustc`.
let path = build.sysroot(compiler).join("bin");
let old_path = env::var_os("PATH").unwrap_or_default();
- let newpath = env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("");
+ let newpath = env::join_paths(
+ iter::once(path).chain(env::split_paths(&old_path))
+ ).expect("");
- let mut cargo = build.cargo(compiler, Mode::Tool, host, "test");
+ let mut cargo = build.cargo(compiler, Mode::Tool, self.host, "test");
cargo.arg("--manifest-path").arg(build.src.join("src/tools/cargo/Cargo.toml"));
if !build.fail_fast {
cargo.arg("--no-fail-fast");
try_run(build, cargo.env("PATH", newpath));
=======
try_run(build, cargo.env("PATH", newpath));
- let host = self.host;
}
>>>>>>> adabe3889e... Move code into Step trait implementations.
}
impl<'a> Step<'a> for Tidy<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD: bool = true;
/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
///
let _folder = build.fold_output(|| "tidy");
println!("tidy check ({})", host);
- let compiler = Compiler::new(0, host);
- let mut cmd = build.tool_cmd(&compiler, "tidy");
+ let mut cmd = build.tool_cmd(Tool::Tidy);
cmd.arg(build.src.join("src"));
if !build.config.vendor {
cmd.arg("--no-vendor");
}
try_run(build, &mut cmd);
}
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/tidy")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
+ builder.ensure(Tidy {
+ host: &builder.build.build,
+ });
+ }
}
fn testdir(build: &Build, host: &str) -> PathBuf {
suite: &'a str,
}
+static COMPILETESTS: &[(bool, &str, &str, &str)] = &[
+ // default, path, mode, suite
+ (true, "src/test/codegen", "codegen", "codegen"),
+ (true, "src/test/codegen-units", "codegen-units", "codegen-units"),
+ (true, "src/test/compile-fail", "compile-fail", "compile-fail"),
+ (true, "src/test/incremental", "incremental", "incremental"),
+ (true, "src/test/mir-opt", "mir-opt", "mir-opt"),
+ (true, "src/test/parse-fail", "parse-fail", "parse-fail"),
+ (true, "src/test/run-fail", "run-fail", "run-fail"),
+ (true, "src/test/run-pass", "run-pass", "run-pass"),
+ (true, "src/test/run-pass-valgrind", "run-pass-valgrind", "run-pass-valgrind"),
+ (true, "src/test/ui", "ui", "ui"),
+ (false, "src/test/debuginfo-lldb", "debuginfo-lldb", "debuginfo"),
+ (false, "src/test/debuginfo-gdb", "debuginfo-gdb", "debuginfo"),
+
+ // FIXME: What this runs varies depending on the native platform being apple
+ (true, "src/test/debuginfo", "debuginfo-XXX", "debuginfo"),
+
+ (true, "src/test/ui-fulldeps", "ui", "ui-fulldeps"),
+ (true, "src/test/run-pass-fulldeps", "run-pass", "run-pass-fulldeps"),
+ (true, "src/test/run-fail-fulldeps", "run-fail", "run-fail-fulldeps"),
+ (true, "src/test/compile-fail-fulldeps", "compile-fail", "compile-fail-fulldeps"),
+ (true, "src/test/run-make", "run-make", "run-make"),
+ (true, "src/test/rustdoc", "rustdoc", "rustdoc"),
+
+ (false, "src/test/pretty", "pretty", "pretty"),
+ (false, "src/test/run-pass/pretty", "pretty", "run-pass"),
+ (false, "src/test/run-fail/pretty", "pretty", "run-fail"),
+ (false, "src/test/run-pass-valgrind/pretty", "pretty", "run-pass-valgrind"),
+ (false, "src/test/run-pass-fulldeps/pretty", "pretty", "run-pass-fulldeps"),
+ (false, "src/test/run-fail-fulldeps/pretty", "pretty", "run-fail-fulldeps"),
+];
+
+
impl<'a> Step<'a> for Compiletest<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ // Note that this is general, while a few more cases are skipped inside
+ // run() itself. This is to avoid duplication across should_run and
+ // make_run.
+ COMPILETESTS.iter().any(|&(_, test_path, _, _)| {
+ path.ends_with(test_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ let compiler = builder.compiler(builder.top_stage, host);
+
+ let test = path.map(|path| {
+ COMPILETESTS.iter().find(|&&(_, test_path, _, _)| {
+ 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 { // specific test
+ builder.ensure(Compiletest {
+ compiler, target, mode: test.2, suite: test.3
+ });
+ } else { // default tests
+ for &(default, _, mode, suite) in COMPILETESTS {
+ if default {
+ builder.ensure(Compiletest {
+ compiler, target, mode, suite
+ });
+ }
+ }
+ }
+ }
/// Executes the `compiletest` tool to run a suite of tests.
///
let target = self.target;
let mode = self.mode;
let suite = self.suite;
+
+ // Skip codegen tests if they aren't enabled in configuration.
+ if !build.config.codegen_tests && suite == "codegen" {
+ return;
+ }
+
+ if suite == "debuginfo" {
+ if mode == "debuginfo-XXX" {
+ return if build.build.contains("apple") {
+ builder.ensure(Compiletest {
+ mode: "debuginfo-lldb",
+ ..self
+ })
+ } else {
+ builder.ensure(Compiletest {
+ mode: "debuginfo-gdb",
+ ..self
+ })
+ };
+ }
+
+ // Skip debuginfo tests on MSVC
+ if build.build.contains("msvc") {
+ return;
+ }
+
+ builder.ensure(dist::DebuggerScripts {
+ sysroot: &builder.sysroot(compiler),
+ host: compiler.host
+ });
+ }
+
+ if suite.ends_with("fulldeps") ||
+ // FIXME: Does pretty need librustc compiled? Note that there are
+ // fulldeps test suites with mode = pretty as well.
+ mode == "pretty" ||
+ mode == "rustdoc" ||
+ mode == "run-make" {
+ builder.ensure(compile::Rustc { compiler, target });
+ }
+
+ builder.ensure(compile::Test { compiler, target });
+ builder.ensure(native::TestHelpers { target });
+
+ if mode == "debuginfo-gdb" {
+ builder.ensure(RemoteCopyLibs { compiler, target });
+ }
+
let _folder = build.fold_output(|| format!("test_{}", suite));
println!("Check compiletest suite={} mode={} ({} -> {})",
suite, mode, compiler.host, target);
- let mut cmd = Command::new(build.tool(&Compiler::new(0, compiler.host),
- "compiletest"));
- build.prepare_tool_cmd(compiler, &mut cmd);
+ let mut cmd = builder.tool_cmd(Tool::Compiletest);
// compiletest currently has... a lot of arguments, so let's just pass all
// of them!
}
if build.remote_tested(target) {
- cmd.arg("--remote-test-client")
- .arg(build.tool(&Compiler::new(0, &build.build),
- "remote-test-client"));
+ cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
}
// Running a C compiler on MSVC requires a few env vars to be set, to be
impl<'a> Step<'a> for ErrorIndex<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/error_index_generator")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
+ builder.ensure(ErrorIndex {
+ compiler: builder.compiler(builder.top_stage, host),
+ });
+ }
/// Run the error index generator tool to execute the tests located in the error
/// index.
let build = builder.build;
let compiler = self.compiler;
+ builder.ensure(compile::Std { compiler, target: compiler.host });
+
let _folder = build.fold_output(|| "test_error_index");
println!("Testing error-index stage{}", compiler.stage);
let output = dir.join("error-index.md");
let _time = util::timeit();
- build.run(build.tool_cmd(&Compiler::new(0, compiler.host),
- "error_index_generator")
+ build.run(build.tool_cmd(Tool::ErrorIndex)
.arg("markdown")
.arg(&output)
.env("CFG_BUILD", &build.build));
}
}
+// for (krate, path, _default) in krates("rustc-main") {
+// rules.test(&krate.test_step, path)
+// .dep(|s| s.name("librustc"))
+// .dep(|s| s.name("remote-copy-libs"))
+// .host(true)
+// .run(move |s| check::krate(build, &s.compiler(), s.target,
+// Mode::Librustc, TestKind::Test,
+// Some(&krate.name)));
+// }
+// rules.test("check-rustc-all", "path/to/nowhere")
+// .dep(|s| s.name("librustc"))
+// .dep(|s| s.name("remote-copy-libs"))
+// .default(true)
+// .host(true)
+// .run(move |s| check::krate(build, &s.compiler(), s.target,
+// Mode::Librustc, TestKind::Test, None));
+#[derive(Serialize)]
+pub struct KrateLibrustc<'a> {
+ compiler: Compiler<'a>,
+ target: &'a str,
+ test_kind: TestKind,
+ krate: Option<&'a str>,
+}
+
+impl<'a> Step<'a> for KrateLibrustc<'a> {
+ type Output = ();
+ const NAME: &'static str = "check librustc";
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ builder.crates("rustc-main").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ let compiler = builder.compiler(builder.top_stage, host);
+
+ let run = |name: Option<&str>| {
+ let test_kind = if builder.kind == Kind::Test {
+ TestKind::Test
+ } else if builder.kind == Kind::Bench {
+ TestKind::Bench
+ } else {
+ panic!("unexpected builder.kind in Krate: {:?}", builder.kind);
+ };
+
+ builder.ensure(KrateLibrustc {
+ compiler,
+ target,
+ test_kind: test_kind,
+ krate: name,
+ });
+ };
+
+ if let Some(path) = path {
+ for (name, krate_path) in builder.crates("rustc-main") {
+ if path.ends_with(krate_path) {
+ run(Some(name));
+ }
+ }
+ } else {
+ run(None);
+ }
+ }
+
+
+ fn run(self, builder: &Builder) {
+ builder.ensure(Krate {
+ compiler: self.compiler,
+ target: self.target,
+ mode: Mode::Librustc,
+ test_kind: self.test_kind,
+ krate: self.krate,
+ });
+ }
+}
+
+
// for (krate, path, _default) in krates("std") {
// rules.test(&krate.test_step, path)
// .dep(|s| s.name("libtest"))
// .default(true)
// .run(move |s| check::krate(build, &s.compiler(), s.target,
// Mode::Libtest, TestKind::Test, None));
-// for (krate, path, _default) in krates("rustc-main") {
-// rules.test(&krate.test_step, path)
-// .dep(|s| s.name("librustc"))
-// .dep(|s| s.name("remote-copy-libs"))
-// .host(true)
-// .run(move |s| check::krate(build, &s.compiler(), s.target,
-// Mode::Librustc, TestKind::Test,
-// Some(&krate.name)));
-// }
-// rules.test("check-rustc-all", "path/to/nowhere")
-// .dep(|s| s.name("librustc"))
-// .dep(|s| s.name("remote-copy-libs"))
-// .default(true)
-// .host(true)
-// .run(move |s| check::krate(build, &s.compiler(), s.target,
-// Mode::Librustc, TestKind::Test, None));
#[derive(Serialize)]
pub struct Krate<'a> {
impl<'a> Step<'a> for Krate<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ builder.crates("std").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ }) ||
+ builder.crates("test").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ let compiler = builder.compiler(builder.top_stage, host);
+
+ let run = |mode: Mode, name: Option<&str>| {
+ let test_kind = if builder.kind == Kind::Test {
+ TestKind::Test
+ } else if builder.kind == Kind::Bench {
+ TestKind::Bench
+ } else {
+ panic!("unexpected builder.kind in Krate: {:?}", builder.kind);
+ };
+
+ builder.ensure(Krate {
+ compiler, target,
+ mode: mode,
+ test_kind: test_kind,
+ krate: name,
+ });
+ };
+
+ if let Some(path) = path {
+ for (name, krate_path) in builder.crates("std") {
+ if path.ends_with(krate_path) {
+ run(Mode::Libstd, Some(name));
+ }
+ }
+ for (name, krate_path) in builder.crates("test") {
+ if path.ends_with(krate_path) {
+ run(Mode::Libtest, Some(name));
+ }
+ }
+ } else {
+ run(Mode::Libstd, None);
+ run(Mode::Libtest, None);
+ }
+ }
/// Run all unit tests plus documentation tests for an entire crate DAG defined
/// by a `Cargo.toml`
let test_kind = self.test_kind;
let krate = self.krate;
+ builder.ensure(compile::Test { compiler, target });
+ builder.ensure(RemoteCopyLibs { compiler, target });
let (name, path, features, root) = match mode {
Mode::Libstd => {
("libstd", "src/libstd", build.std_features(), "std")
// stage1. Reflect that here by updating the compiler that we're working
// with automatically.
let compiler = if build.force_use_stage1(compiler, target) {
- Compiler::new(1, compiler.host)
+ builder.compiler(1, compiler.host)
} else {
compiler.clone()
};
krate_emscripten(build, &compiler, target, mode);
} else if build.remote_tested(target) {
build.run(&mut cargo);
- krate_remote(build, &compiler, target, mode);
+ krate_remote(builder, &compiler, target, mode);
} else {
cargo.args(&build.flags.cmd.test_args());
try_run(build, &mut cargo);
}
}
-fn krate_remote(build: &Build,
+fn krate_remote(build: &Builder,
compiler: &Compiler,
target: &str,
mode: Mode) {
let out_dir = build.cargo_out(compiler, mode, target);
let tests = find_tests(&out_dir.join("deps"), target);
- let tool = build.tool(&Compiler::new(0, &build.build),
- "remote-test-client");
+ let tool = builder.tool_exe(Tool::RemoteTestClient);
for test in tests {
let mut cmd = Command::new(&tool);
cmd.arg("run")
return
}
+ builder.ensure(compile::Test { compiler, target });
+
println!("REMOTE copy libs to emulator ({})", target);
t!(fs::create_dir_all(build.out.join("tmp")));
- let server = build.cargo_out(compiler, Mode::Tool, target)
- .join(exe("remote-test-server", target));
+ // FIXME: This builds the tool for the native build triple
+ // (build.build); that is probably wrong. Should build for target.
+ let server = builder.tool_exe(Tool::RemoteTestServer);
// Spawn the emulator and wait for it to come online
- let tool = build.tool(&Compiler::new(0, &build.build),
- "remote-test-client");
+ let tool = builder.tool_exe(Tool::RemoteTestClient);
let mut cmd = Command::new(&tool);
cmd.arg("spawn-emulator")
.arg(target)
return
}
+ builder.ensure(dist::PlainSourceTarball);
+ builder.ensure(dist::Src);
+
println!("Distcheck");
let dir = build.out.join("tmp").join("distcheck");
let _ = fs::remove_dir_all(&dir);
impl<'a> for Step<'a> Bootstrap {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD: bool = true;
/// Test the build system itself
fn run(self, builder: &Builder) {
cmd.arg("--").args(&build.flags.cmd.test_args());
try_run(build, &mut cmd);
}
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/bootstrap")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
+ builder.ensure(Bootstrap);
+ }
}
rule
}
+// rules.build("libstd", "src/libstd")
+// .dep(|s| s.name("rustc").target(s.host))
+// .dep(|s| s.name("libstd-link"));
// for (krate, path, _default) in krates("std") {
// rules.build(&krate.build_step, path)
// .dep(|s| s.name("startup-objects"))
impl<'a> Step<'a> for Std<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/libstd") ||
+ builder.crates("std").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
+ builder.ensure(Std {
+ compiler: builder.compiler(builder.top_stage, host),
+ target,
+ })
+ }
/// Build the standard library.
///
let build = builder.build;
let target = self.target;
let compiler = self.compiler;
- let libdir = build.sysroot_libdir(compiler, target);
- t!(fs::create_dir_all(&libdir));
+
+ builder.ensure(StartupObjects { compiler, target });
+
+ if build.force_use_stage1(compiler, target) {
+ let from = builder.compiler(1, &build.build);
+ builder.ensure(Std {
+ compiler: from,
+ target: target,
+ });
+ println!("Uplifting stage1 std ({} -> {})", from.host, target);
+ builder.ensure(StdLink {
+ compiler: from,
+ target_compiler: compiler,
+ target: target,
+ });
+ return;
+ }
let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
build.clear_if_dirty(&out_dir, &build.compiler_path(compiler));
- let mut cargo = build.cargo(compiler, Mode::Libstd, target, "build");
+ let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
let mut features = build.std_features();
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
// config.toml equivalent) is used
cargo.env("LLVM_CONFIG", build.llvm_config(target));
}
+
cargo.arg("--features").arg(features)
.arg("--manifest-path")
.arg(build.src.join("src/libstd/Cargo.toml"));
run_cargo(build,
&mut cargo,
&libstd_stamp(build, &compiler, target));
+
+ builder.ensure(StdLink {
+ compiler: builder.compiler(compiler.stage, &build.build),
+ target_compiler: compiler,
+ target: target,
+ });
}
}
// .dep(|s| s.name("create-sysroot").target(s.host));
#[derive(Serialize)]
-pub struct StdLink<'a> {
+struct StdLink<'a> {
pub compiler: Compiler<'a>,
pub target_compiler: Compiler<'a>,
pub target: &'a str,
impl<'a> Step<'a> for StartupObjects<'a> {
type Output = ();
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/rtstartup")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
+ builder.ensure(StartupObjects {
+ compiler: builder.compiler(builder.top_stage, host),
+ target,
+ })
+ }
+
/// Build and prepare startup objects like rsbegin.o and rsend.o
///
/// These are primarily used on Windows right now for linking executables/dlls.
impl<'a> Step<'a> for Test<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/libtest") ||
+ builder.crates("test").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
+ builder.ensure(Test {
+ compiler: builder.compiler(builder.top_stage, host),
+ target,
+ })
+ }
/// Build libtest.
///
let build = builder.build;
let target = self.target;
let compiler = self.compiler;
+
+ builder.ensure(Std { compiler, target });
+
+ if build.force_use_stage1(compiler, target) {
+ builder.ensure(Test {
+ compiler: builder.compiler(1, &build.build),
+ target: target,
+ });
+ println!("Uplifting stage1 test ({} -> {})", &build.build, target);
+ builder.ensure(TestLink {
+ compiler: builder.compiler(1, &build.build),
+ target_compiler: compiler,
+ target: target,
+ });
+ return;
+ }
+
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
compiler.host, target);
run_cargo(build,
&mut cargo,
&libtest_stamp(build, compiler, target));
+
+ builder.ensure(TestLink {
+ compiler: builder.compiler(1, &build.build),
+ target_compiler: compiler,
+ target: target,
+ });
}
}
impl<'a> Step<'a> for Rustc<'a> {
type Output = ();
+ const ONLY_HOSTS: bool = true;
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/librustc") ||
+ builder.crates("rustc-main").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
+ builder.ensure(Rustc {
+ compiler: builder.compiler(builder.top_stage, host),
+ target,
+ })
+ }
/// Build the compiler.
///
let build = builder.build;
let compiler = self.compiler;
let target = self.target;
+
+ builder.ensure(Test { compiler, target });
+
+ // Build LLVM for our target. This will implicitly build the host LLVM
+ // if necessary.
+ builder.ensure(native::Llvm { target });
+
+ if build.force_use_stage1(compiler, target) {
+ builder.ensure(Rustc {
+ compiler: builder.compiler(1, &build.build),
+ target: target,
+ });
+ println!("Uplifting stage1 rustc ({} -> {})", &build.build, target);
+ builder.ensure(RustcLink {
+ compiler: builder.compiler(1, &build.build),
+ target_compiler: compiler,
+ target,
+ });
+ return;
+ }
+
+ // Ensure that build scripts have a std to link against.
+ builder.ensure(Std {
+ compiler: builder.compiler(self.compiler.stage, &build.build),
+ target: &build.build,
+ });
+
let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
println!("Building stage{} compiler artifacts ({} -> {})",
compiler.stage, compiler.host, target);
run_cargo(build,
&mut cargo,
&librustc_stamp(build, compiler, target));
+
+ builder.ensure(RustcLink {
+ compiler: builder.compiler(compiler.stage, &build.build),
+ target_compiler: compiler,
+ target,
+ });
}
}
// compile::rustc_link)
// .dep(|s| s.name("libtest-link"));
#[derive(Serialize)]
-pub struct RustcLink<'a> {
+struct RustcLink<'a> {
pub compiler: Compiler<'a>,
pub target_compiler: Compiler<'a>,
pub target: &'a str,
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
-fn libstd_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn libstd_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Libstd, target).join(".libstd.stamp")
}
/// Cargo's output path for libtest in a given stage, compiled by a particular
/// compiler for the specified target.
-fn libtest_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn libtest_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Libtest, target).join(".libtest.stamp")
}
/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
-fn librustc_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn librustc_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
}
}
impl<'a> Step<'a> for Sysroot<'a> {
- type Output = ();
+ type Output = PathBuf;
/// Returns the sysroot for the `compiler` specified that *this build system
/// generates*.
/// That is, the sysroot for the stage0 compiler is not what the compiler
/// thinks it is by default, but it's the same as the default for stages
/// 1-3.
- fn run(self, builder: &Builder) {
+ fn run(self, builder: &Builder) -> PathBuf {
let build = builder.build;
let compiler = self.compiler;
- let sysroot = build.sysroot(compiler);
+ let sysroot = if compiler.stage == 0 {
+ build.out.join(compiler.host).join("stage0-sysroot")
+ } else {
+ build.out.join(compiler.host).join(format!("stage{}", compiler.stage))
+ };
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
+ sysroot
}
}
#[derive(Serialize)]
pub struct Assemble<'a> {
- pub stage: u32,
- pub host: &'a str,
+ /// The compiler which we will produce in this step. Assemble itself will
+ /// take care of ensuring that the necessary prerequisites to do so exist,
+ /// that is, this target can be a stage2 compiler and Assemble will build
+ /// previous stages for you.
+ pub target_compiler: Compiler<'a>,
}
impl<'a> Step<'a> for Assemble<'a> {
/// compiler.
fn run(self, builder: &Builder) {
let build = builder.build;
- let stage = self.stage;
- let host = self.host;
- // nothing to do in stage0
- if stage == 0 {
- return
+ let target_compiler = self.target_compiler;
+
+ if target_compiler.stage == 0 {
+ assert_eq!(build.build, target_compiler.host,
+ "Cannot obtain compiler for non-native build triple at stage 0");
+ // The stage 0 compiler for the build triple is always pre-built.
+ return target_compiler;
}
- println!("Copying stage{} compiler ({})", stage, host);
+ // Get the compiler that we'll use to bootstrap ourselves.
+ let build_compiler = if target_compiler.host != build.build {
+ // Build a compiler for the host platform. We cannot use the stage0
+ // compiler for the host platform for this because it doesn't have
+ // the libraries we need. FIXME: Perhaps we should download those
+ // libraries? It would make builds faster...
+ builder.ensure(Assemble {
+ target_compiler: Compiler {
+ // FIXME: It may be faster if we build just a stage 1
+ // compiler and then use that to bootstrap this compiler
+ // forward.
+ stage: target_compiler.stage - 1,
+ host: &build.build
+ },
+ })
+ } else {
+ // Build the compiler we'll use to build the stage requested. This
+ // may build more than one compiler (going down to stage 0).
+ builder.ensure(Assemble {
+ target_compiler: target_compiler.with_stage(target_compiler.stage - 1),
+ })
+ };
- // The compiler that we're assembling
- let target_compiler = Compiler::new(stage, host);
+ // Build the libraries for this compiler to link to (i.e., the libraries
+ // it uses at runtime). NOTE: Crates the target compiler compiles don't
+ // link to these. (FIXME: Is that correct? It seems to be correct most
+ // of the time but I think we do link to these for stage2/bin compilers
+ // when not performing a full bootstrap).
+ builder.ensure(Rustc { compiler: build_compiler, target: target_compiler.host });
- // The compiler that compiled the compiler we're assembling
- let build_compiler = Compiler::new(stage - 1, &build.build);
+ let stage = target_compiler.stage;
+ let host = target_compiler.host;
+ println!("Assembling stage{} compiler ({})", stage, host);
// Link in all dylibs to the libdir
let sysroot = build.sysroot(&target_compiler);
impl<'a> Step<'a> for Docs<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/doc")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure(Docs {
+ stage: builder.top_stage,
+ host: target,
+ });
+ }
/// Builds the `rust-docs` installer component.
///
let stage = self.stage;
let host = self.host;
+ builder.default_doc(None);
+
println!("Dist docs stage{} ({})", stage, host);
if !build.config.docs {
println!("\tskipping - docs disabled");
impl<'a> Step<'a> for Mingw<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+
+ fn should_run(_builder: &Builder, _path: &Path) -> bool {
+ false
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
+ builder.ensure(Mingw {
+ host: host,
+ });
+ }
/// Build the `rust-mingw` installer component.
///
fn run(self, builder: &Builder) {
let build = builder.build;
let host = self.host;
+
+ if !host.contains("pc-windows-gnu") {
+ return;
+ }
+
println!("Dist mingw ({})", host);
let name = pkgname(build, "rust-mingw");
let image = tmpdir(build).join(format!("{}-{}-image", name, host));
impl<'a> Step<'a> for Rustc<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/librustc")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
+ builder.ensure(Rustc {
+ stage: builder.top_stage,
+ host: host,
+ });
+ }
/// Creates the `rustc` installer component.
fn run(self, builder: &builder) {
let _ = fs::remove_dir_all(&overlay);
// Prepare the rustc "image", what will actually end up getting installed
- prepare_image(build, stage, host, &image);
+ prepare_image(builder, stage, host, &image);
// Prepare the overlay which is part of the tarball but won't actually be
// installed
t!(fs::remove_dir_all(&image));
t!(fs::remove_dir_all(&overlay));
- fn prepare_image(build: &Build, stage: u32, host: &str, image: &Path) {
- let src = build.sysroot(&Compiler::new(stage, host));
+ fn prepare_image(builder: &Builder, stage: u32, host: &str, image: &Path) {
+ let build = builder.build;
+ let src = build.sysroot(builder.compiler(stage, host));
let libdir = libdir(host);
// Copy rustc/rustdoc binaries
cp_r(&build.src.join("man"), &image.join("share/man/man1"));
// Debugger scripts
- debugger_scripts(build, &image, host);
+ builder.ensure(DebuggerScripts {
+ sysroot: &image,
+ host: host,
+ });
// Misc license info
let cp = |file: &str| {
}
}
-
-
//rules.test("debugger-scripts", "src/etc/lldb_batchmode.py")
// .run(move |s| dist::debugger_scripts(build, &build.sysroot(&s.compiler()),
// s.target));
impl<'a> Step<'a> for DebuggerScripts<'a> {
type Output = ();
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/etc/lldb_batchmode.py")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
+ builder.ensure(DebuggerScripts {
+ // FIXME: builder.top_stage is likely wrong in some cases.
+ sysroot: &builder.sysroot(builder.compiler(builder.top_stage, host)),
+ host: host,
+ });
+ }
+
/// Copies debugger scripts for `host` into the `sysroot` specified.
fn run(self, builder: &Builder) {
let build = builder.build;
impl<'a> Step<'a> for Analysis<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("analysis")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.extended {
+ return;
+ }
+ builder.ensure(Analysis {
+ compiler: builder.compiler(builder.top_stage, host),
+ target: target,
+ });
+ }
/// Creates a tarball of save-analysis metadata, if available.
fn run(self, builder: &Builder) {
// Package save-analysis from stage1 if not doing a full bootstrap, as the
// stage2 artifacts is simply copied from stage1 in that case.
let compiler = if build.force_use_stage1(compiler, target) {
- Compiler::new(1, compiler.host)
+ builder.compiler(1, compiler.host)
} else {
compiler.clone()
};
let name = pkgname(build, "rust-analysis");
let image = tmpdir(build).join(format!("{}-{}-image", name, target));
- let src = build.stage_out(&compiler, Mode::Libstd).join(target).join("release").join("deps");
+ let src = build.stage_out(compiler, Mode::Libstd)
+ .join(target).join("release").join("deps");
let image_src = src.join("save-analysis");
let dst = image.join("lib/rustlib").join(target).join("analysis");
impl<'a> Step<'a> for Src {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_BUILD: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
+ builder.ensure(Src);
+ }
/// Creates the `rust-src` installer component
fn run(self, builder: &Builder) {
impl<'a> Step<'a> for PlainSourceTarball {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_BUILD: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, _target: &str) {
+ if path.is_none() && !builder.build.config.rust_dist_src {
+ return;
+ }
+
+ builder.ensure(PlainSourceTarball);
+ }
/// Creates the plain source tarball
fn run(self, builder: &Builder) {
impl<'a> Step<'a> for Cargo<'a> {
type Output = ();
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("cargo")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure(Cargo {
+ stage: builder.top_stage,
+ target: target,
+ });
+ }
fn run(self, builder: &Builder) {
let build = builder.build;
let stage = self.stage;
let target = self.target;
+
+ builder.ensure(tool::Cargo { stage, target });
+
println!("Dist cargo stage{} ({})", stage, target);
- let compiler = Compiler::new(stage, &build.build);
+ let compiler = builder.compiler(stage, &build.build);
let src = build.src.join("src/tools/cargo");
let etc = src.join("src/etc");
impl<'a> Step<'a> for Rls<'a> {
type Output = ();
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("rls")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure(Rls {
+ stage: builder.top_stage,
+ target: target,
+ });
+ }
fn run(self, builder: &Builder) {
let build = builder.build;
let stage = self.stage;
let target = self.target;
assert!(build.config.extended);
+
+ builder.ensure(tool::Rls { stage, target });
+
println!("Dist RLS stage{} ({})", stage, target);
- let compiler = Compiler::new(stage, &build.build);
+ let compiler = builder.compiler(stage, &build.build);
let src = build.src.join("src/tools/rls");
let release_num = build.release_num("rls");
impl<'a> Step<'a> for Extended<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("cargo")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.extended {
+ return;
+ }
+ builder.ensure(Extended {
+ compiler: builder.compiler(builder.top_stage, host),
+ target: target,
+ });
+ }
/// Creates a combined installer for the specified target in the provided stage.
fn run(self, builder: &Builder) {
let build = builder.build;
let stage = self.stage;
let target = self.target;
+ let compiler = builder.compiler(stage, &build.build);
+
+ builder.ensure(Std { compiler, target });
+ builder.ensure(Rustc { stage, host });
+ builder.ensure(Mingw { host });
+ builder.ensure(Docs { stage, host });
+ builder.ensure(Cargo { stage, target });
+ builder.ensure(Rls { stage, target });
+ builder.ensure(Analysis { compiler, target });
println!("Dist extended stage{} ({})", stage, target);
impl<'a> Step<'a> for HashSign {
type Output = ();
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_HOSTS: bool = true;
+ const ONLY_BUILD: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("hash-and-sign")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
+ builder.ensure(HashSign);
+ }
fn run(self, builder: &Builder) {
let build = builder.build;
- let compiler = Compiler::new(0, &build.build);
- let mut cmd = build.tool_cmd(&compiler, "build-manifest");
+ let mut cmd = builder.tool_cmd(Tool::BuildManifest);
let sign = build.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
});
use util::{cp_r, symlink_dir};
use build_helper::up_to_date;
-// rules.doc("doc-nomicon", "src/doc/nomicon")
-// .dep(move |s| {
-// s.name("tool-rustbook")
-// .host(&build.build)
-// .target(&build.build)
-// .stage(0)
-// })
-// .default(build.config.docs)
-// .run(move |s| doc::rustbook(build, s.target, "nomicon"));
-// rules.doc("doc-reference", "src/doc/reference")
-// .dep(move |s| {
-// s.name("tool-rustbook")
-// .host(&build.build)
-// .target(&build.build)
-// .stage(0)
-// })
-// .default(build.config.docs)
-// .run(move |s| doc::rustbook(build, s.target, "reference"));
+macro_rules! book {
+ ($($name:ident, $path:expr, $book_name:expr;)+) => {
+ $(
+ #[derive(Serialize)]
+ pub struct $name<'a> {
+ target: &'a str,
+ }
+
+ impl<'a> Step<'a> for $name<'a> {
+ type Output = ();
+ const NAME: &'static str = concat!(stringify!($book_name), " - book");
+ const DEFAULT: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with($path)
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.docs {
+ // Not a default rule if docs are disabled.
+ return;
+ }
+
+ builder.ensure($name {
+ target,
+ });
+ }
+
+ fn run(self, builder: &Builder) {
+ builder.ensure(Rustbook {
+ target: self.target,
+ name: $book_name,
+ })
+ }
+ }
+ )+
+ }
+}
+
+book!(
+ // rules.doc("doc-nomicon", "src/doc/nomicon")
+ // .dep(move |s| {
+ // s.name("tool-rustbook")
+ // .host(&build.build)
+ // .target(&build.build)
+ // .stage(0)
+ // })
+ // .default(build.config.docs)
+ // .run(move |s| doc::rustbook(build, s.target, "nomicon"));
+ Nomicon, "src/doc/book", "nomicon";
+ // rules.doc("doc-reference", "src/doc/reference")
+ // .dep(move |s| {
+ // s.name("tool-rustbook")
+ // .host(&build.build)
+ // .target(&build.build)
+ // .stage(0)
+ // })
+ // .default(build.config.docs)
+ // .run(move |s| doc::rustbook(build, s.target, "reference"));
+ Reference, "src/doc/reference", "reference";
+);
#[derive(Serialize)]
-pub struct Rustbook<'a> {
+struct Rustbook<'a> {
target: &'a str,
name: &'a str,
}
/// This will not actually generate any documentation if the documentation has
/// already been generated.
fn run(self, builder: &Builder) {
- let build = builder.build;
- let target = self.target;
- let name = self.name;
- let src = build.src.join("src/doc");
- rustbook_src(build, target, name, &src);
+ let src = builder.build.src.join("src/doc");
+ builder.ensure(RustbookSrc {
+ target: self.target,
+ name: self.name,
+ src: &src,
+ });
}
}
// s.target,
// "unstable-book",
// &build.md_doc_out(s.target)));
+#[derive(Serialize)]
+pub struct UnstableBook<'a> {
+ target: &'a str,
+}
+
+impl<'a> Step<'a> for UnstableBook<'a> {
+ type Output = ();
+ const NAME: &'static str = "unstable book documentation";
+ const DEFAULT: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/doc/unstable-book")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.docs {
+ // Not a default rule if docs are disabled.
+ return;
+ }
+
+ builder.ensure(UnstableBook {
+ target,
+ });
+ }
+
+ fn run(self, builder: &Builder) {
+ builder.ensure(UnstableBookGen {
+ target: self.target,
+ });
+ builder.ensure(RustbookSrc {
+ target: self.target,
+ name: "unstable-book",
+ src: &builder.build.md_doc_out(self.target),
+ })
+ }
+}
#[derive(Serialize)]
pub struct RustbookSrc<'a> {
t!(fs::create_dir_all(&out));
let out = out.join(name);
- let compiler = Compiler::new(0, &build.build);
let src = src.join(name);
let index = out.join("index.html");
- let rustbook = build.tool(&compiler, "rustbook");
+ let rustbook = builder.tool_exe(Tool::Rustbook);
if up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
return
}
println!("Rustbook ({}) - {}", target, name);
let _ = fs::remove_dir_all(&out);
- build.run(build.tool_cmd(&compiler, "rustbook")
+ build.run(builder.tool_cmd(Tool::Rustbook)
.arg("build")
.arg(&src)
.arg("-d")
let target = self.target;
let name = self.name;
// build book first edition
- rustbook(build, target, &format!("{}/first-edition", name));
+ builder.ensure(Rustbook {
+ target: target,
+ name: &format!("{}/first-edition", name),
+ });
// build book second edition
- rustbook(build, target, &format!("{}/second-edition", name));
+ builder.ensure(Rustbook {
+ target: target,
+ name: &format!("{}/second-edition", name),
+ });
// build the index page
let index = format!("{}/index.md", name);
impl<'a> Step<'a> for Standalone<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/doc")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.docs {
+ // Not a default rule if docs are disabled.
+ return;
+ }
+
+ builder.ensure(Standalone {
+ target,
+ });
+ }
/// Generates all standalone documentation as compiled by the rustdoc in `stage`
/// for the `target` into `out`.
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = Compiler::new(0, &build.build);
+ let compiler = builder.compiler(0, &build.build);
let favicon = build.src.join("src/doc/favicon.inc");
let footer = build.src.join("src/doc/footer.inc");
impl<'a> Step<'a> for Std<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ builder.crates("std").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ let run = || {
+ builder.ensure(Std {
+ stage: builder.top_stage,
+ target
+ });
+ };
+
+ if let Some(path) = path {
+ for (_, krate_path) in builder.crates("std") {
+ if path.ends_with(krate_path) {
+ run();
+ }
+ }
+ } else {
+ if builder.build.config.docs {
+ run();
+ }
+ }
+ }
/// Compile all standard library documentation.
///
println!("Documenting stage{} std ({})", stage, target);
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = Compiler::new(stage, &build.build);
- let compiler = if build.force_use_stage1(&compiler, target) {
- Compiler::new(1, compiler.host)
+ let compiler = builder.compiler(stage, &build.build);
+ let compiler = if build.force_use_stage1(compiler, target) {
+ builder.compiler(1, compiler.host)
} else {
compiler
};
+
+ builder.ensure(compile::Std { compiler, target });
let out_dir = build.stage_out(&compiler, Mode::Libstd)
.join(target).join("doc");
let rustdoc = build.rustdoc(&compiler);
impl<'a> Step<'a> for Test<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ builder.crates("test").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ let run = || {
+ builder.ensure(Test {
+ stage: builder.top_stage,
+ target
+ });
+ };
+
+ if let Some(path) = path {
+ for (_, krate_path) in builder.crates("test") {
+ if path.ends_with(krate_path) {
+ run();
+ }
+ }
+ } else {
+ if builder.build.config.docs {
+ run();
+ }
+ }
+ }
/// Compile all libtest documentation.
///
println!("Documenting stage{} test ({})", stage, target);
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = Compiler::new(stage, &build.build);
- let compiler = if build.force_use_stage1(&compiler, target) {
- Compiler::new(1, compiler.host)
+ let compiler = builder.compiler(stage, &build.build);
+ let compiler = if build.force_use_stage1(compiler, target) {
+ builder.compiler(1, compiler.host)
} else {
compiler
};
+
+ // Build libstd docs so that we generate relative links
+ builder.ensure(Std { stage, target });
+
+ builder.ensure(compile::Test { compiler, target });
let out_dir = build.stage_out(&compiler, Mode::Libtest)
.join(target).join("doc");
let rustdoc = build.rustdoc(&compiler);
impl<'a> Step<'a> for Rustc<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(builder: &Builder, path: &Path) -> bool {
+ builder.crates("rustc-main").into_iter().any(|(_, krate_path)| {
+ path.ends_with(krate_path)
+ })
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ let run = || {
+ builder.ensure(Rustc {
+ stage: builder.top_stage,
+ target
+ });
+ };
+
+ if let Some(path) = path {
+ for (_, krate_path) in builder.crates("rustc-main") {
+ if path.ends_with(krate_path) {
+ run();
+ }
+ }
+ } else {
+ if builder.build.config.compiler_docs {
+ run();
+ }
+ }
+ }
/// Generate all compiler documentation.
///
println!("Documenting stage{} compiler ({})", stage, target);
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = Compiler::new(stage, &build.build);
- let compiler = if build.force_use_stage1(&compiler, target) {
- Compiler::new(1, compiler.host)
+ let compiler = builder.compiler(stage, &build.build);
+ let compiler = if build.force_use_stage1(compiler, target) {
+ builder.compiler(1, compiler.host)
} else {
compiler
};
+
+ // Build libstd docs so that we generate relative links
+ builder.ensure(Std { stage, target });
+
+ builder.ensure(compile::Rustc { compiler, target });
let out_dir = build.stage_out(&compiler, Mode::Librustc)
.join(target).join("doc");
let rustdoc = build.rustdoc(&compiler);
impl<'a> Step<'a> for ErrorIndex<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/error_index_generator")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.docs {
+ // Not a default rule if docs are disabled.
+ return;
+ }
+
+ builder.ensure(ErrorIndex {
+ target,
+ });
+ }
/// Generates the HTML rendered error-index by running the
/// `error_index_generator` tool.
fn run(self, builder: &Builder) {
let builder = builder.build;
let target = self.target;
+
+ builder.ensure(compile::Rustc {
+ compiler: builder.compiler(0, &build.build),
+ target,
+ });
+
println!("Documenting error index ({})", target);
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(0, &build.build);
- let mut index = build.tool_cmd(&compiler, "error_index_generator");
+ let mut index = builder.tool_cmd(Tool::ErrorIndex);
index.arg("html");
index.arg(out.join("error-index.html"));
impl<'a> Step<'a> for UnstableBookGen<'a> {
type Output = ();
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/doc/unstable-book")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.docs {
+ // Not a default rule if docs are disabled.
+ return;
+ }
+
+ builder.ensure(UnstableBookGen {
+ target,
+ });
+ }
fn run(self, builder: &Builder) {
let build = builder.build;
let target = self.target;
+
+ builder.ensure(compile::Std {
+ compiler: builder.compiler(builder.top_stage, &build.build),
+ target,
+ });
+
println!("Generating unstable book md files ({})", target);
let out = build.md_doc_out(target).join("unstable-book");
t!(fs::create_dir_all(&out));
}
ret
}
-/*
-rules.install("install-docs", "src/doc")
- .default(build.config.docs)
- .only_host_build(true)
- .dep(|s| s.name("dist-docs"))
- .run(move |s| install::Installer::new(build).install_docs(s.stage, s.target));
-rules.install("install-std", "src/libstd")
- .default(true)
- .only_host_build(true)
- .dep(|s| s.name("dist-std"))
- .run(move |s| install::Installer::new(build).install_std(s.stage));
-rules.install("install-cargo", "cargo")
- .default(build.config.extended)
- .host(true)
- .only_host_build(true)
- .dep(|s| s.name("dist-cargo"))
- .run(move |s| install::Installer::new(build).install_cargo(s.stage, s.target));
-rules.install("install-rls", "rls")
- .default(build.config.extended)
- .host(true)
- .only_host_build(true)
- .dep(|s| s.name("dist-rls"))
- .run(move |s| install::Installer::new(build).install_rls(s.stage, s.target));
-rules.install("install-analysis", "analysis")
- .default(build.config.extended)
- .only_host_build(true)
- .dep(|s| s.name("dist-analysis"))
- .run(move |s| install::Installer::new(build).install_analysis(s.stage, s.target));
-rules.install("install-src", "src")
- .default(build.config.extended)
- .host(true)
- .only_build(true)
- .only_host_build(true)
- .dep(|s| s.name("dist-src"))
- .run(move |s| install::Installer::new(build).install_src(s.stage));
-rules.install("install-rustc", "src/librustc")
- .default(true)
- .host(true)
- .only_host_build(true)
- .dep(|s| s.name("dist-rustc"))
- .run(move |s| install::Installer::new(build).install_rustc(s.stage, s.target));
-*/
+
+macro_rules! install {
+ ($($name:ident,
+ $path:expr,
+ $default_cond:expr,
+ only_hosts: $only_hosts:expr,
+ ($sel:ident, $builder:ident),
+ $run_item:block $(, $c:ident)*;)+) => {
+ $(#[derive(Serialize)]
+ pub struct $name<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+ pub host: &'a str,
+ }
+
+ impl<'a> Step<'a> for $name<'a> {
+ type Output = ();
+ const NAME: &'static str = concat!("install ", stringify!($name));
+ const DEFAULT: bool = true;
+ const ONLY_BUILD_TARGETS: bool = true;
+ const ONLY_HOSTS: bool = $only_hosts;
+ $(const $c: bool = true;)*
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with($path)
+ }
+
+ fn make_run($builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ if path.is_none() && !($default_cond) {
+ return;
+ }
+ $builder.ensure($name {
+ stage: $builder.top_stage,
+ target,
+ host,
+ });
+ }
+
+ fn run($sel, $builder: &Builder) {
+ $run_item
+ }
+ })+
+ }
+}
+
+install!(
+ // rules.install("install-docs", "src/doc")
+ // .default(build.config.docs)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-docs"))
+ // .run(move |s| install::Installer::new(build).install_docs(s.stage, s.target));
+ Docs, "src/doc", builder.build.config.docs, only_hosts: false, (self, builder), {
+ builder.ensure(dist::Docs { stage: self.stage, host: self.host });
+ Installer::new(builder.build).install_docs(self.stage, self.target);
+ };
+ // rules.install("install-std", "src/libstd")
+ // .default(true)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-std"))
+ // .run(move |s| install::Installer::new(build).install_std(s.stage));
+ Std, "src/libstd", true, only_hosts: true, (self, builder), {
+ builder.ensure(dist::Std {
+ compiler: builder.compiler(self.stage, self.host),
+ target: self.target
+ });
+ Installer::new(builder.build).install_std(self.stage);
+ };
+ // rules.install("install-cargo", "cargo")
+ // .default(build.config.extended)
+ // .host(true)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-cargo"))
+ // .run(move |s| install::Installer::new(build).install_cargo(s.stage, s.target));
+ Cargo, "cargo", builder.build.config.extended, only_hosts: true, (self, builder), {
+ builder.ensure(dist::Cargo { stage: self.stage, target: self.target });
+ Installer::new(builder.build).install_cargo(self.stage, self.target);
+ };
+ // rules.install("install-rls", "rls")
+ // .default(build.config.extended)
+ // .host(true)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-rls"))
+ // .run(move |s| install::Installer::new(build).install_rls(s.stage, s.target));
+ Rls, "rls", builder.build.config.extended, only_hosts: true, (self, builder), {
+ builder.ensure(dist::Rls { stage: self.stage, target: self.target });
+ Installer::new(builder.build).install_rls(self.stage, self.target);
+ };
+ // rules.install("install-analysis", "analysis")
+ // .default(build.config.extended)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-analysis"))
+ // .run(move |s| install::Installer::new(build).install_analysis(s.stage, s.target));
+ Analysis, "analysis", builder.build.config.extended, only_hosts: false, (self, builder), {
+ builder.ensure(dist::Analysis {
+ compiler: builder.compiler(self.stage, self.host),
+ target: self.target
+ });
+ Installer::new(builder.build).install_analysis(self.stage, self.target);
+ };
+ // rules.install("install-src", "src")
+ // .default(build.config.extended)
+ // .host(true)
+ // .only_build(true)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-src"))
+ // .run(move |s| install::Installer::new(build).install_src(s.stage));
+ Src, "src", builder.build.config.extended, only_hosts: true, (self, builder), {
+ builder.ensure(dist::Src);
+ Installer::new(builder.build).install_src(self.stage);
+ }, ONLY_BUILD;
+ // rules.install("install-rustc", "src/librustc")
+ // .default(true)
+ // .host(true)
+ // .only_host_build(true)
+ // .dep(|s| s.name("dist-rustc"))
+ // .run(move |s| install::Installer::new(build).install_rustc(s.stage, s.target));
+ Rustc, "src/librustc", builder.build.config.extended, only_hosts: true, (self, builder), {
+ builder.ensure(dist::Rustc { stage: self.stage, host: self.host });
+ Installer::new(builder.build).install_rustc(self.stage, self.target);
+ };
+);
use util;
use build_helper::up_to_date;
-/j/ rules.build("llvm", "src/llvm")
+// rules.build("llvm", "src/llvm")
// .host(true)
// .dep(move |s| {
// if s.target == build.build {
impl<'a> Step<'a> for Llvm<'a> {
type Output = ();
+ const ONLY_HOSTS: bool = true;
/// Compile LLVM for `target`.
fn run(self, builder: &Builder) {
// http://llvm.org/docs/HowToCrossCompileLLVM.html
if target != build.build {
+ builder.ensure(Llvm { target: &build.build });
// FIXME: if the llvm root for the build triple is overridden then we
// should use llvm-tblgen from there, also should verify that it
// actually exists most of the time in normal installs of LLVM.
impl<'a> Step<'a> for TestHelpers<'a> {
type Output = ();
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/rt/rust_test_helpers.c")
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure(TestHelpers { target })
+ }
+
/// Compiles the `rust_test_helpers.c` library which we used in various
/// `run-pass` test suites for ABI testing.
fn run(self, builder: &Builder) {
#[derive(Serialize)]
pub struct Openssl<'a> {
- target: &'a str,
+ pub target: &'a str,
}
impl<'a> Step<'a> for Openssl<'a> {
type Output = ();
+ fn should_run(_builder: &Builder, _path: &Path) -> bool {
+ false
+ }
+
fn run(self, builder: &Builder) {
let build = bulder.build;
let target = self.target;
use Mode;
use builder::{Step, Builder};
use util::{exe, add_lib_path};
-use compile::{self, stamp, Rustc};
+use compile::{self, libtest_stamp, libstd_stamp, librustc_stamp, Rustc};
use native;
use channel::GitInfo;
let target = self.target;
let mode = self.mode;
- let compiler = Compiler::new(stage, &build.build);
+ let compiler = builder.compiler(stage, &build.build);
let stamp = match mode {
Mode::Libstd => libstd_stamp(build, &compiler, target),
}
}
-// rules.build("tool-rustbook", "src/tools/rustbook")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("librustc-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
-// rules.build("tool-error-index", "src/tools/error_index_generator")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("librustc-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
-// rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
-// rules.build("tool-tidy", "src/tools/tidy")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
-// rules.build("tool-linkchecker", "src/tools/linkchecker")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
-// rules.build("tool-cargotest", "src/tools/cargotest")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
-// rules.build("tool-compiletest", "src/tools/compiletest")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libtest-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
-// rules.build("tool-build-manifest", "src/tools/build-manifest")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
-// rules.build("tool-remote-test-server", "src/tools/remote-test-server")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
-// rules.build("tool-remote-test-client", "src/tools/remote-test-client")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
-// rules.build("tool-rust-installer", "src/tools/rust-installer")
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
-// rules.build("tool-cargo", "src/tools/cargo")
-// .host(true)
-// .default(build.config.extended)
-// .dep(|s| s.name("maybe-clean-tools"))
-// .dep(|s| s.name("libstd-tool"))
-// .dep(|s| s.stage(0).host(s.target).name("openssl"))
-// .dep(move |s| {
-// // Cargo depends on procedural macros, which requires a full host
-// // compiler to be available, so we need to depend on that.
-// s.name("librustc-link")
-// .target(&build.build)
-// .host(&build.build)
-// })
-// .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
-// rules.build("tool-rls", "src/tools/rls")
-// .host(true)
-// .default(build.config.extended)
-// .dep(|s| s.name("librustc-tool"))
-// .dep(|s| s.stage(0).host(s.target).name("openssl"))
-// .dep(move |s| {
-// // rls, like cargo, uses procedural macros
-// s.name("librustc-link")
-// .target(&build.build)
-// .host(&build.build)
-// })
-// .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
-//
-
#[derive(Serialize)]
-pub struct Tool<'a> {
+pub struct ToolBuild<'a> {
pub stage: u32,
pub target: &'a str,
pub tool: &'a str,
+ pub mode: Mode,
}
-impl<'a> Step<'a> for Tool<'a> {
- type Output = ();
+impl<'a> Step<'a> for ToolBuild<'a> {
+ type Output = PathBuf;
/// Build a tool in `src/tools`
///
/// This will build the specified tool with the specified `host` compiler in
/// `stage` into the normal cargo output directory.
- fn run(self, builder: &Builder) {
+ fn run(self, builder: &Builder) -> PathBuf {
let build = builder.build;
let stage = self.stage;
let target = self.target;
let tool = self.tool;
+ let compiler = builder.compiler(stage, &build.build);
+ builder.ensure(CleanTools { stage, target, mode: self.mode });
+ match self.mode {
+ Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
+ Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
+ Mode::Librustc => builder.ensure(compile::Rustc { compiler, target }),
+ Mode::Tool => panic!("unexpected Mode::Tool for tool build")
+ }
+
let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
println!("Building stage{} tool {} ({})", stage, tool, target);
- let compiler = Compiler::new(stage, &build.build);
-
let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
let dir = build.src.join("src/tools").join(tool);
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
}
build.run(&mut cargo);
+ build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, compiler.host))
+ }
+}
+
+macro_rules! tool {
+ ($($name:ident, $path:expr, $tool_name:expr, $mode:expr;)+) => {
+ #[derive(Copy, Clone)]
+ pub enum Tool {
+ $(
+ $name,
+ )+
+ }
+
+ impl<'a> Builder<'a> {
+ pub fn tool_exe(&self, tool: Tool) -> PathBuf {
+ match tool {
+ $(Tool::$name =>
+ self.ensure($name {
+ stage: 0,
+ target: &self.build.build,
+ }),
+ )+
+ }
+ }
+ }
+
+ $(
+ #[derive(Serialize)]
+ pub struct $name<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+ }
+
+ impl<'a> Step<'a> for $name<'a> {
+ type Output = PathBuf;
+ const NAME: &'static str = concat!(stringify!($name), " tool");
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with($path)
+ }
+
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure($name {
+ stage: builder.top_stage,
+ target,
+ });
+ }
+
+ fn run(self, builder: &Builder) -> PathBuf {
+ builder.ensure(ToolBuild {
+ stage: self.stage,
+ target: self.target,
+ tool: $tool_name,
+ mode: $mode,
+ })
+ }
+ }
+ )+
+ }
+}
+
+tool!(
+ // rules.build("tool-rustbook", "src/tools/rustbook")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("librustc-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
+ Rustbook, "src/tools/rustbook", "rustbook", Mode::Librustc;
+ // rules.build("tool-error-index", "src/tools/error_index_generator")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("librustc-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
+ ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::Librustc;
+ // rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
+ UnstableBook, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
+ // rules.build("tool-tidy", "src/tools/tidy")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
+ Tidy, "src/tools/tidy", "tidy", Mode::Libstd;
+ // rules.build("tool-linkchecker", "src/tools/linkchecker")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
+ Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::Libstd;
+ // rules.build("tool-cargotest", "src/tools/cargotest")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
+ CargoTest, "src/tools/cargotest", "cargotest", Mode::Libstd;
+ // rules.build("tool-compiletest", "src/tools/compiletest")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libtest-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
+ Compiletest, "src/tools/compiletest", "compiletest", Mode::Libtest;
+ // rules.build("tool-build-manifest", "src/tools/build-manifest")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
+ BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd;
+ // rules.build("tool-remote-test-server", "src/tools/remote-test-server")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
+ RemoteTestServer, "src/tools/remote-test-server", "remote-test-server", Mode::Libstd;
+ // rules.build("tool-remote-test-client", "src/tools/remote-test-client")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
+ RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd;
+ // rules.build("tool-rust-installer", "src/tools/rust-installer")
+ // .dep(|s| s.name("maybe-clean-tools"))
+ // .dep(|s| s.name("libstd-tool"))
+ // .run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
+ RustInstaller, "src/tools/rust-installer", "rust-installer", Mode::Libstd;
+);
+
+// rules.build("tool-cargo", "src/tools/cargo")
+// .host(true)
+// .default(build.config.extended)
+// .dep(|s| s.name("maybe-clean-tools"))
+// .dep(|s| s.name("libstd-tool"))
+// .dep(|s| s.stage(0).host(s.target).name("openssl"))
+// .dep(move |s| {
+// // Cargo depends on procedural macros, which requires a full host
+// // compiler to be available, so we need to depend on that.
+// s.name("librustc-link")
+// .target(&build.build)
+// .host(&build.build)
+// })
+// .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
+#[derive(Serialize)]
+pub struct Cargo<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+}
+
+impl<'a> Step<'a> for Cargo<'a> {
+ type Output = PathBuf;
+ const NAME: &'static str = "cargo tool";
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/cargo")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.extended {
+ return;
+ }
+ builder.ensure(Cargo {
+ stage: builder.top_stage,
+ target,
+ });
+ }
+
+ fn run(self, builder: &Builder) -> PathBuf {
+ builder.ensure(native::Openssl {
+ target: self.target,
+ });
+ // Cargo depends on procedural macros, which requires a full host
+ // compiler to be available, so we need to depend on that.
+ builder.ensure(Rustc {
+ compiler: builder.compiler(builder.top_stage, &builder.build.build),
+ target: &builder.build.build,
+ });
+ builder.ensure(ToolBuild {
+ stage: self.stage,
+ target: self.target,
+ tool: "cargo",
+ mode: Mode::Libstd,
+ })
+ }
+}
+
+// rules.build("tool-rls", "src/tools/rls")
+// .host(true)
+// .default(build.config.extended)
+// .dep(|s| s.name("librustc-tool"))
+// .dep(|s| s.stage(0).host(s.target).name("openssl"))
+// .dep(move |s| {
+// // rls, like cargo, uses procedural macros
+// s.name("librustc-link")
+// .target(&build.build)
+// .host(&build.build)
+// })
+// .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
+//
+#[derive(Serialize)]
+pub struct Rls<'a> {
+ pub stage: u32,
+ pub target: &'a str,
+}
+
+impl<'a> Step<'a> for Rls<'a> {
+ type Output = PathBuf;
+ const NAME: &'static str = "RLS tool";
+ const DEFAULT: bool = true;
+ const ONLY_HOSTS: bool = true;
+
+ fn should_run(_builder: &Builder, path: &Path) -> bool {
+ path.ends_with("src/tools/rls")
+ }
+
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
+ if path.is_none() && !builder.build.config.extended {
+ return;
+ }
+ builder.ensure(Cargo {
+ stage: builder.top_stage,
+ target,
+ });
+ }
+
+ fn run(self, builder: &Builder) -> PathBuf {
+ builder.ensure(native::Openssl {
+ target: self.target,
+ });
+ // RLS depends on procedural macros, which requires a full host
+ // compiler to be available, so we need to depend on that.
+ builder.ensure(Rustc {
+ compiler: builder.compiler(builder.top_stage, &builder.build.build),
+ target: &builder.build.build,
+ });
+ builder.ensure(ToolBuild {
+ stage: self.stage,
+ target: self.target,
+ tool: "rls",
+ mode: Mode::Librustc,
+ })
}
}