about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2017-07-04 17:53:53 -0600
committerMark Simulacrum <mark.simulacrum@gmail.com>2017-07-20 11:23:57 -0600
commit0a1b5e8bc01061f54716005fd8ea37cc4997bfd9 (patch)
tree51c9b77a43f2534c3e8359cb9f2b7c73f765fa96 /src/bootstrap
parentae98ebfcb9ad5a5384fd229a6ee91315b02ca969 (diff)
downloadrust-0a1b5e8bc01061f54716005fd8ea37cc4997bfd9.tar.gz
rust-0a1b5e8bc01061f54716005fd8ea37cc4997bfd9.zip
Move rule configs out of step
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/check.rs231
-rw-r--r--src/bootstrap/compile.rs252
-rw-r--r--src/bootstrap/dist.rs102
-rw-r--r--src/bootstrap/doc.rs95
-rw-r--r--src/bootstrap/install.rs42
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/bootstrap/native.rs15
7 files changed, 737 insertions, 1 deletions
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index e4b0e2fb9ca..5e553cf8d6f 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -81,6 +81,12 @@ fn try_run_quiet(build: &Build, cmd: &mut Command) {
     }
 }
 
+// rules.test("check-linkchecker", "src/tools/linkchecker")
+//      .dep(|s| s.name("tool-linkchecker").stage(0))
+//      .dep(|s| s.name("default:doc"))
+//      .default(build.config.docs)
+//      .host(true)
+//      .run(move |s| check::linkcheck(build, s.target));
 /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
 ///
 /// This tool in `src/tools` will verify the validity of all our links in the
@@ -94,6 +100,11 @@ pub fn linkcheck(build: &Build, host: &str) {
                         .arg(build.out.join(host).join("doc")));
 }
 
+// rules.test("check-cargotest", "src/tools/cargotest")
+//      .dep(|s| s.name("tool-cargotest").stage(0))
+//      .dep(|s| s.name("librustc"))
+//      .host(true)
+//      .run(move |s| check::cargotest(build, s.stage, s.target));
 /// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
 ///
 /// This tool in `src/tools` will check out a few Rust projects and run `cargo
@@ -116,6 +127,10 @@ pub fn cargotest(build: &Build, stage: u32, host: &str) {
                       .env("RUSTDOC", build.rustdoc(&compiler)));
 }
 
+//rules.test("check-cargo", "cargo")
+//     .dep(|s| s.name("tool-cargo"))
+//     .host(true)
+//     .run(move |s| check::cargo(build, s.stage, s.target));
 /// Runs `cargo test` for `cargo` packaged with Rust.
 pub fn cargo(build: &Build, stage: u32, host: &str) {
     let compiler = &Compiler::new(stage, host);
@@ -160,6 +175,12 @@ fn path_for_cargo(build: &Build, compiler: &Compiler) -> OsString {
     env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")
 }
 
+//rules.test("check-tidy", "src/tools/tidy")
+//     .dep(|s| s.name("tool-tidy").stage(0))
+//     .default(true)
+//     .host(true)
+//     .only_build(true)
+//     .run(move |s| check::tidy(build, s.target));
 /// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
 ///
 /// This tool in `src/tools` checks up on various bits and pieces of style and
@@ -184,6 +205,104 @@ fn testdir(build: &Build, host: &str) -> PathBuf {
     build.out.join(host).join("test")
 }
 
+//    // ========================================================================
+//    // Test targets
+//    //
+//    // Various unit tests and tests suites we can run
+//    {
+//        let mut suite = |name, path, mode, dir| {
+//            rules.test(name, path)
+//                 .dep(|s| s.name("libtest"))
+//                 .dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
+//                 .dep(|s| s.name("test-helpers"))
+//                 .dep(|s| s.name("remote-copy-libs"))
+//                 .default(mode != "pretty") // pretty tests don't run everywhere
+//                 .run(move |s| {
+//                     check::compiletest(build, &s.compiler(), s.target, mode, dir)
+//                 });
+//        };
+//
+//        suite("check-ui", "src/test/ui", "ui", "ui");
+//        suite("check-rpass", "src/test/run-pass", "run-pass", "run-pass");
+//        suite("check-cfail", "src/test/compile-fail", "compile-fail", "compile-fail");
+//        suite("check-pfail", "src/test/parse-fail", "parse-fail", "parse-fail");
+//        suite("check-rfail", "src/test/run-fail", "run-fail", "run-fail");
+//        suite("check-rpass-valgrind", "src/test/run-pass-valgrind",
+//              "run-pass-valgrind", "run-pass-valgrind");
+//        suite("check-mir-opt", "src/test/mir-opt", "mir-opt", "mir-opt");
+//        if build.config.codegen_tests {
+//            suite("check-codegen", "src/test/codegen", "codegen", "codegen");
+//        }
+//        suite("check-codegen-units", "src/test/codegen-units", "codegen-units",
+//              "codegen-units");
+//        suite("check-incremental", "src/test/incremental", "incremental",
+//              "incremental");
+//    }
+//
+//    if build.build.contains("msvc") {
+//        // nothing to do for debuginfo tests
+//    } else {
+//        rules.test("check-debuginfo-lldb", "src/test/debuginfo-lldb")
+//             .dep(|s| s.name("libtest"))
+//             .dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
+//             .dep(|s| s.name("test-helpers"))
+//             .dep(|s| s.name("debugger-scripts"))
+//             .run(move |s| check::compiletest(build, &s.compiler(), s.target,
+//                                         "debuginfo-lldb", "debuginfo"));
+//        rules.test("check-debuginfo-gdb", "src/test/debuginfo-gdb")
+//             .dep(|s| s.name("libtest"))
+//             .dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
+//             .dep(|s| s.name("test-helpers"))
+//             .dep(|s| s.name("debugger-scripts"))
+//             .dep(|s| s.name("remote-copy-libs"))
+//             .run(move |s| check::compiletest(build, &s.compiler(), s.target,
+//                                         "debuginfo-gdb", "debuginfo"));
+//        let mut rule = rules.test("check-debuginfo", "src/test/debuginfo");
+//        rule.default(true);
+//        if build.build.contains("apple") {
+//            rule.dep(|s| s.name("check-debuginfo-lldb"));
+//        } else {
+//            rule.dep(|s| s.name("check-debuginfo-gdb"));
+//        }
+//    }
+//
+//
+//
+//    {
+//        let mut suite = |name, path, mode, dir| {
+//            rules.test(name, path)
+//                 .dep(|s| s.name("librustc"))
+//                 .dep(|s| s.name("test-helpers"))
+//                 .dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
+//                 .default(mode != "pretty")
+//                 .host(true)
+//                 .run(move |s| {
+//                     check::compiletest(build, &s.compiler(), s.target, mode, dir)
+//                 });
+//        };
+//
+//        suite("check-ui-full", "src/test/ui-fulldeps", "ui", "ui-fulldeps");
+//        suite("check-rpass-full", "src/test/run-pass-fulldeps",
+//              "run-pass", "run-pass-fulldeps");
+//        suite("check-rfail-full", "src/test/run-fail-fulldeps",
+//              "run-fail", "run-fail-fulldeps");
+//        suite("check-cfail-full", "src/test/compile-fail-fulldeps",
+//              "compile-fail", "compile-fail-fulldeps");
+//        suite("check-rmake", "src/test/run-make", "run-make", "run-make");
+//        suite("check-rustdoc", "src/test/rustdoc", "rustdoc", "rustdoc");
+//        suite("check-pretty", "src/test/pretty", "pretty", "pretty");
+//        suite("check-pretty-rpass", "src/test/run-pass/pretty", "pretty",
+//              "run-pass");
+//        suite("check-pretty-rfail", "src/test/run-fail/pretty", "pretty",
+//              "run-fail");
+//        suite("check-pretty-valgrind", "src/test/run-pass-valgrind/pretty", "pretty",
+//              "run-pass-valgrind");
+//        suite("check-pretty-rpass-full", "src/test/run-pass-fulldeps/pretty",
+//              "pretty", "run-pass-fulldeps");
+//        suite("check-pretty-rfail-full", "src/test/run-fail-fulldeps/pretty",
+//              "pretty", "run-fail-fulldeps");
+//    }
+
 /// Executes the `compiletest` tool to run a suite of tests.
 ///
 /// Compiles all tests with `compiler` for `target` with the specified
@@ -338,6 +457,11 @@ pub fn compiletest(build: &Build,
     try_run(build, &mut cmd);
 }
 
+// rules.test("check-docs", "src/doc")
+//     .dep(|s| s.name("libtest"))
+//     .default(true)
+//     .host(true)
+//     .run(move |s| check::docs(build, &s.compiler()));
 /// Run `rustdoc --test` for all documentation in `src/doc`.
 ///
 /// This will run all tests in our markdown documentation (e.g. the book)
@@ -370,6 +494,12 @@ pub fn docs(build: &Build, compiler: &Compiler) {
     }
 }
 
+//rules.test("check-error-index", "src/tools/error_index_generator")
+//     .dep(|s| s.name("libstd"))
+//     .dep(|s| s.name("tool-error-index").host(s.host).stage(0))
+//     .default(true)
+//     .host(true)
+//     .run(move |s| check::error_index(build, &s.compiler()));
 /// Run the error index generator tool to execute the tests located in the error
 /// index.
 ///
@@ -420,6 +550,68 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
     }
 }
 
+//    for (krate, path, _default) in krates("std") {
+//        rules.test(&krate.test_step, path)
+//             .dep(|s| s.name("libtest"))
+//             .dep(|s| s.name("remote-copy-libs"))
+//             .run(move |s| check::krate(build, &s.compiler(), s.target,
+//                                        Mode::Libstd, TestKind::Test,
+//                                        Some(&krate.name)));
+//    }
+//    rules.test("check-std-all", "path/to/nowhere")
+//         .dep(|s| s.name("libtest"))
+//         .dep(|s| s.name("remote-copy-libs"))
+//         .default(true)
+//         .run(move |s| check::krate(build, &s.compiler(), s.target,
+//                                    Mode::Libstd, TestKind::Test, None));
+//
+//    // std benchmarks
+//    for (krate, path, _default) in krates("std") {
+//        rules.bench(&krate.bench_step, path)
+//             .dep(|s| s.name("libtest"))
+//             .dep(|s| s.name("remote-copy-libs"))
+//             .run(move |s| check::krate(build, &s.compiler(), s.target,
+//                                        Mode::Libstd, TestKind::Bench,
+//                                        Some(&krate.name)));
+//    }
+//    rules.bench("bench-std-all", "path/to/nowhere")
+//         .dep(|s| s.name("libtest"))
+//         .dep(|s| s.name("remote-copy-libs"))
+//         .default(true)
+//         .run(move |s| check::krate(build, &s.compiler(), s.target,
+//                                    Mode::Libstd, TestKind::Bench, None));
+//
+//    for (krate, path, _default) in krates("test") {
+//        rules.test(&krate.test_step, path)
+//             .dep(|s| s.name("libtest"))
+//             .dep(|s| s.name("remote-copy-libs"))
+//             .run(move |s| check::krate(build, &s.compiler(), s.target,
+//                                        Mode::Libtest, TestKind::Test,
+//                                        Some(&krate.name)));
+//    }
+//    rules.test("check-test-all", "path/to/nowhere")
+//         .dep(|s| s.name("libtest"))
+//         .dep(|s| s.name("remote-copy-libs"))
+//         .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));
+
 /// Run all unit tests plus documentation tests for an entire crate DAG defined
 /// by a `Cargo.toml`
 ///
@@ -596,6 +788,34 @@ fn find_tests(dir: &Path, target: &str) -> Vec<PathBuf> {
     dst
 }
 
+//    // Some test suites are run inside emulators or on remote devices, and most
+//    // of our test binaries are linked dynamically which means we need to ship
+//    // the standard library and such to the emulator ahead of time. This step
+//    // represents this and is a dependency of all test suites.
+//    //
+//    // Most of the time this step is a noop (the `check::emulator_copy_libs`
+//    // only does work if necessary). For some steps such as shipping data to
+//    // QEMU we have to build our own tools so we've got conditional dependencies
+//    // on those programs as well. Note that the remote test client is built for
+//    // the build target (us) and the server is built for the target.
+//    rules.test("remote-copy-libs", "path/to/nowhere")
+//         .dep(|s| s.name("libtest"))
+//         .dep(move |s| {
+//             if build.remote_tested(s.target) {
+//                s.name("tool-remote-test-client").target(s.host).stage(0)
+//             } else {
+//                 Step::noop()
+//             }
+//         })
+//         .dep(move |s| {
+//             if build.remote_tested(s.target) {
+//                s.name("tool-remote-test-server")
+//             } else {
+//                 Step::noop()
+//             }
+//         })
+//         .run(move |s| check::remote_copy_libs(build, &s.compiler(), s.target));
+//
 pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
     if !build.remote_tested(target) {
         return
@@ -632,6 +852,11 @@ pub fn remote_copy_libs(build: &Build, compiler: &Compiler, target: &str) {
     }
 }
 
+//rules.test("check-distcheck", "distcheck")
+//     .dep(|s| s.name("dist-plain-source-tarball"))
+//     .dep(|s| s.name("dist-src"))
+//     .run(move |_| check::distcheck(build));
+
 /// Run "distcheck", a 'make check' from a tarball
 pub fn distcheck(build: &Build) {
     if build.build != "x86_64-unknown-linux-gnu" {
@@ -684,6 +909,12 @@ pub fn distcheck(build: &Build) {
                      .current_dir(&dir));
 }
 
+//rules.test("check-bootstrap", "src/bootstrap")
+//     .default(true)
+//     .host(true)
+//     .only_build(true)
+//     .run(move |_| check::bootstrap(build));
+//
 /// Test the build system itself
 pub fn bootstrap(build: &Build) {
     let mut cmd = Command::new(&build.initial_cargo);
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 5a3106c7d5e..4a972ebf8df 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -32,6 +32,121 @@ use channel::GitInfo;
 use util::{exe, libdir, is_dylib, copy};
 use {Build, Compiler, Mode};
 
+//    for (krate, path, _default) in krates("std") {
+//        rules.build(&krate.build_step, path)
+//             .dep(|s| s.name("startup-objects"))
+//             .dep(move |s| s.name("rustc").host(&build.build).target(s.host))
+//             .run(move |s| compile::std(build, s.target, &s.compiler()));
+//    }
+//    for (krate, path, _default) in krates("test") {
+//        rules.build(&krate.build_step, path)
+//             .dep(|s| s.name("libstd-link"))
+//             .run(move |s| compile::test(build, s.target, &s.compiler()));
+//    }
+//    for (krate, path, _default) in krates("rustc-main") {
+//        rules.build(&krate.build_step, path)
+//             .dep(|s| s.name("libtest-link"))
+//             .dep(move |s| s.name("llvm").host(&build.build).stage(0))
+//             .dep(|s| s.name("may-run-build-script"))
+//             .run(move |s| compile::rustc(build, s.target, &s.compiler()));
+//    }
+//
+//    // Crates which have build scripts need to rely on this rule to ensure that
+//    // the necessary prerequisites for a build script are linked and located in
+//    // place.
+//    rules.build("may-run-build-script", "path/to/nowhere")
+//         .dep(move |s| {
+//             s.name("libstd-link")
+//              .host(&build.build)
+//              .target(&build.build)
+//         });
+
+//    // ========================================================================
+//    // Crate compilations
+//    //
+//    // Tools used during the build system but not shipped
+//    // These rules are "pseudo rules" that don't actually do any work
+//    // themselves, but represent a complete sysroot with the relevant compiler
+//    // linked into place.
+//    //
+//    // That is, depending on "libstd" means that when the rule is completed then
+//    // the `stage` sysroot for the compiler `host` will be available with a
+//    // standard library built for `target` linked in place. Not all rules need
+//    // the compiler itself to be available, just the standard library, so
+//    // there's a distinction between the two.
+//    rules.build("libstd", "src/libstd")
+//         .dep(|s| s.name("rustc").target(s.host))
+//         .dep(|s| s.name("libstd-link"));
+//    rules.build("libtest", "src/libtest")
+//         .dep(|s| s.name("libstd"))
+//         .dep(|s| s.name("libtest-link"))
+//         .default(true);
+//    rules.build("librustc", "src/librustc")
+//         .dep(|s| s.name("libtest"))
+//         .dep(|s| s.name("librustc-link"))
+//         .host(true)
+//         .default(true);
+
+// Helper method to define the rules to link a crate into its place in the
+// sysroot.
+//
+// The logic here is a little subtle as there's a few cases to consider.
+// Not all combinations of (stage, host, target) actually require something
+// to be compiled, but rather libraries could get propagated from a
+// different location. For example:
+//
+// * Any crate with a `host` that's not the build triple will not actually
+//   compile something. A different `host` means that the build triple will
+//   actually compile the libraries, and then we'll copy them over from the
+//   build triple to the `host` directory.
+//
+// * Some crates aren't even compiled by the build triple, but may be copied
+//   from previous stages. For example if we're not doing a full bootstrap
+//   then we may just depend on the stage1 versions of libraries to be
+//   available to get linked forward.
+//
+// * Finally, there are some cases, however, which do indeed comiple crates
+//   and link them into place afterwards.
+//
+// The rule definition below mirrors these three cases. The `dep` method
+// calculates the correct dependency which either comes from stage1, a
+// different compiler, or from actually building the crate itself (the `dep`
+// rule). The `run` rule then mirrors these three cases and links the cases
+// forward into the compiler sysroot specified from the correct location.
+fn crate_rule<'a, 'b>(build: &'a Build,
+                        rules: &'b mut Rules<'a>,
+                        krate: &'a str,
+                        dep: &'a str,
+                        link: fn(&Build, &Compiler, &Compiler, &str))
+                        -> RuleBuilder<'a, 'b> {
+    let mut rule = rules.build(&krate, "path/to/nowhere");
+    rule.dep(move |s| {
+            if build.force_use_stage1(&s.compiler(), s.target) {
+                s.host(&build.build).stage(1)
+            } else if s.host == build.build {
+                s.name(dep)
+            } else {
+                s.host(&build.build)
+            }
+        })
+        .run(move |s| {
+            if build.force_use_stage1(&s.compiler(), s.target) {
+                link(build,
+                        &s.stage(1).host(&build.build).compiler(),
+                        &s.compiler(),
+                        s.target)
+            } else if s.host == build.build {
+                link(build, &s.compiler(), &s.compiler(), s.target)
+            } else {
+                link(build,
+                        &s.host(&build.build).compiler(),
+                        &s.compiler(),
+                        s.target)
+            }
+        });
+        rule
+}
+
 /// Build the standard library.
 ///
 /// This will build the standard library for a particular stage of the build
@@ -93,6 +208,14 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
               &libstd_stamp(build, &compiler, target));
 }
 
+
+// crate_rule(build,
+//            &mut rules,
+//            "libstd-link",
+//            "build-crate-std",
+//            compile::std_link)
+//     .dep(|s| s.name("startup-objects"))
+//     .dep(|s| s.name("create-sysroot").target(s.host));
 /// Link all libstd rlibs/dylibs into the sysroot location.
 ///
 /// Links those artifacts generated by `compiler` to a the `stage` compiler's
@@ -147,6 +270,10 @@ fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) {
     }
 }
 
+// rules.build("startup-objects", "src/rtstartup")
+//      .dep(|s| s.name("create-sysroot").target(s.host))
+//      .run(move |s| compile::build_startup_objects(build, &s.compiler(), s.target));
+
 /// Build and prepare startup objects like rsbegin.o and rsend.o
 ///
 /// These are primarily used on Windows right now for linking executables/dlls.
@@ -209,6 +336,14 @@ pub fn test(build: &Build, target: &str, compiler: &Compiler) {
               &libtest_stamp(build, compiler, target));
 }
 
+
+// crate_rule(build,
+//            &mut rules,
+//            "libtest-link",
+//            "build-crate-test",
+//            compile::test_link)
+//     .dep(|s| s.name("libstd-link"));
+
 /// Same as `std_link`, only for libtest
 pub fn test_link(build: &Build,
                  compiler: &Compiler,
@@ -303,6 +438,12 @@ pub fn rustc(build: &Build, target: &str, compiler: &Compiler) {
               &librustc_stamp(build, compiler, target));
 }
 
+// crate_rule(build,
+//            &mut rules,
+//            "librustc-link",
+//            "build-crate-rustc-main",
+//            compile::rustc_link)
+//     .dep(|s| s.name("libtest-link"));
 /// Same as `std_link`, only for librustc
 pub fn rustc_link(build: &Build,
                   compiler: &Compiler,
@@ -342,12 +483,27 @@ fn compiler_file(compiler: &Path, file: &str) -> PathBuf {
     PathBuf::from(out.trim())
 }
 
+// rules.build("create-sysroot", "path/to/nowhere")
+//      .run(move |s| compile::create_sysroot(build, &s.compiler()));
 pub fn create_sysroot(build: &Build, compiler: &Compiler) {
     let sysroot = build.sysroot(compiler);
     let _ = fs::remove_dir_all(&sysroot);
     t!(fs::create_dir_all(&sysroot));
 }
 
+// the compiler with no target libraries ready to go
+// rules.build("rustc", "src/rustc")
+//      .dep(|s| s.name("create-sysroot").target(s.host))
+//      .dep(move |s| {
+//          if s.stage == 0 {
+//              Step::noop()
+//          } else {
+//              s.name("librustc")
+//               .host(&build.build)
+//               .stage(s.stage - 1)
+//          }
+//      })
+//      .run(move |s| compile::assemble_rustc(build, s.stage, s.target));
 /// Prepare a new compiler from the artifacts in `stage`
 ///
 /// This will assemble a compiler in `build/$host/stage$stage`. The compiler
@@ -418,6 +574,29 @@ fn add_to_sysroot(sysroot_dst: &Path, stamp: &Path) {
     }
 }
 
+//// ========================================================================
+//// Build tools
+////
+//// Tools used during the build system but not shipped
+//// "pseudo rule" which represents completely cleaning out the tools dir in
+//// one stage. This needs to happen whenever a dependency changes (e.g.
+//// libstd, libtest, librustc) and all of the tool compilations above will
+//// be sequenced after this rule.
+//rules.build("maybe-clean-tools", "path/to/nowhere")
+//     .after("librustc-tool")
+//     .after("libtest-tool")
+//     .after("libstd-tool");
+//
+//rules.build("librustc-tool", "path/to/nowhere")
+//     .dep(|s| s.name("librustc"))
+//     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Librustc));
+//rules.build("libtest-tool", "path/to/nowhere")
+//     .dep(|s| s.name("libtest"))
+//     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libtest));
+//rules.build("libstd-tool", "path/to/nowhere")
+//     .dep(|s| s.name("libstd"))
+//     .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libstd));
+//
 /// Build a tool in `src/tools`
 ///
 /// This will build the specified tool with the specified `host` compiler in
@@ -435,6 +614,79 @@ pub fn maybe_clean_tools(build: &Build, stage: u32, target: &str, mode: Mode) {
     build.clear_if_dirty(&out_dir, &stamp);
 }
 
+
+// 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"));
+//
+
 /// Build a tool in `src/tools`
 ///
 /// This will build the specified tool with the specified `host` compiler in
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 8fae1dd99d8..2cf3ca73952 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -18,6 +18,14 @@
 //! out to `rust-installer` still. This may one day be replaced with bits and
 //! pieces of `rustup.rs`!
 
+// /// Helper to depend on a stage0 build-only rust-installer tool.
+// fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> {
+//     step.name("tool-rust-installer")
+//         .host(&build.build)
+//         .target(&build.build)
+//         .stage(0)
+// }
+
 use std::env;
 use std::fs::{self, File};
 use std::io::{Read, Write};
@@ -53,6 +61,12 @@ fn rust_installer(build: &Build) -> Command {
     build.tool_cmd(&Compiler::new(0, &build.build), "rust-installer")
 }
 
+// rules.dist("dist-docs", "src/doc")
+//      .default(true)
+//      .only_host_build(true)
+//      .dep(|s| s.name("default:doc"))
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::docs(build, s.stage, s.target));
 /// Builds the `rust-docs` installer component.
 ///
 /// Slurps up documentation from the `stage`'s `host`.
@@ -222,6 +236,16 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
     }
 }
 
+// rules.dist("dist-mingw", "path/to/nowhere")
+//      .default(true)
+//      .only_host_build(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| {
+//          if s.target.contains("pc-windows-gnu") {
+//              dist::mingw(build, s.target)
+//          }
+//      });
+//
 /// Build the `rust-mingw` installer component.
 ///
 /// This contains all the bits and pieces to run the MinGW Windows targets
@@ -254,6 +278,13 @@ pub fn mingw(build: &Build, host: &str) {
     t!(fs::remove_dir_all(&image));
 }
 
+// rules.dist("dist-rustc", "src/librustc")
+//      .dep(move |s| s.name("rustc").host(&build.build))
+//      .host(true)
+//      .only_host_build(true)
+//      .default(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::rustc(build, s.stage, s.target));
 /// Creates the `rustc` installer component.
 pub fn rustc(build: &Build, stage: u32, host: &str) {
     println!("Dist rustc stage{} ({})", stage, host);
@@ -352,6 +383,9 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
     }
 }
 
+//rules.test("debugger-scripts", "src/etc/lldb_batchmode.py")
+//     .run(move |s| dist::debugger_scripts(build, &build.sysroot(&s.compiler()),
+//                                     s.target));
 /// Copies debugger scripts for `host` into the `sysroot` specified.
 pub fn debugger_scripts(build: &Build,
                         sysroot: &Path,
@@ -386,6 +420,21 @@ pub fn debugger_scripts(build: &Build,
     }
 }
 
+// rules.dist("dist-std", "src/libstd")
+//      .dep(move |s| {
+//          // We want to package up as many target libraries as possible
+//          // for the `rust-std` package, so if this is a host target we
+//          // depend on librustc and otherwise we just depend on libtest.
+//          if build.config.host.iter().any(|t| t == s.target) {
+//              s.name("librustc-link")
+//          } else {
+//              s.name("libtest-link")
+//          }
+//      })
+//      .default(true)
+//      .only_host_build(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::std(build, &s.compiler(), s.target));
 /// Creates the `rust-std` installer component as compiled by `compiler` for the
 /// target `target`.
 pub fn std(build: &Build, compiler: &Compiler, target: &str) {
@@ -436,6 +485,12 @@ pub fn rust_src_installer(build: &Build) -> PathBuf {
     distdir(build).join(&format!("{}.tar.gz", name))
 }
 
+// rules.dist("dist-analysis", "analysis")
+//      .default(build.config.extended)
+//      .dep(|s| s.name("dist-std"))
+//      .only_host_build(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::analysis(build, &s.compiler(), s.target));
 /// Creates a tarball of save-analysis metadata, if available.
 pub fn analysis(build: &Build, compiler: &Compiler, target: &str) {
     assert!(build.config.extended);
@@ -520,6 +575,13 @@ fn copy_src_dirs(build: &Build, src_dirs: &[&str], exclude_dirs: &[&str], dst_di
     }
 }
 
+// rules.dist("dist-src", "src")
+//      .default(true)
+//      .host(true)
+//      .only_build(true)
+//      .only_host_build(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |_| dist::rust_src(build));
 /// Creates the `rust-src` installer component
 pub fn rust_src(build: &Build) {
     println!("Dist src");
@@ -587,6 +649,13 @@ pub fn rust_src(build: &Build) {
 
 const CARGO_VENDOR_VERSION: &str = "0.1.4";
 
+// rules.dist("dist-plain-source-tarball", "src")
+//      .default(build.config.rust_dist_src)
+//      .host(true)
+//      .only_build(true)
+//      .only_host_build(true)
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |_| dist::plain_source_tarball(build));
 /// Creates the plain source tarball
 pub fn plain_source_tarball(build: &Build) {
     println!("Create plain source tarball");
@@ -704,6 +773,12 @@ fn write_file(path: &Path, data: &[u8]) {
     t!(vf.write_all(data));
 }
 
+// rules.dist("dist-cargo", "cargo")
+//      .host(true)
+//      .only_host_build(true)
+//      .dep(|s| s.name("tool-cargo"))
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::cargo(build, s.stage, s.target));
 pub fn cargo(build: &Build, stage: u32, target: &str) {
     println!("Dist cargo stage{} ({})", stage, target);
     let compiler = Compiler::new(stage, &build.build);
@@ -764,6 +839,12 @@ pub fn cargo(build: &Build, stage: u32, target: &str) {
     build.run(&mut cmd);
 }
 
+// rules.dist("dist-rls", "rls")
+//      .host(true)
+//      .only_host_build(true)
+//      .dep(|s| s.name("tool-rls"))
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::rls(build, s.stage, s.target));
 pub fn rls(build: &Build, stage: u32, target: &str) {
     assert!(build.config.extended);
     println!("Dist RLS stage{} ({})", stage, target);
@@ -813,6 +894,20 @@ pub fn rls(build: &Build, stage: u32, target: &str) {
     build.run(&mut cmd);
 }
 
+// rules.dist("dist-extended", "extended")
+//      .default(build.config.extended)
+//      .host(true)
+//      .only_host_build(true)
+//      .dep(|d| d.name("dist-std"))
+//      .dep(|d| d.name("dist-rustc"))
+//      .dep(|d| d.name("dist-mingw"))
+//      .dep(|d| d.name("dist-docs"))
+//      .dep(|d| d.name("dist-cargo"))
+//      .dep(|d| d.name("dist-rls"))
+//      .dep(|d| d.name("dist-analysis"))
+//      .dep(move |s| tool_rust_installer(build, s))
+//      .run(move |s| dist::extended(build, s.stage, s.target));
+
 /// Creates a combined installer for the specified target in the provided stage.
 pub fn extended(build: &Build, stage: u32, target: &str) {
     println!("Dist extended stage{} ({})", stage, target);
@@ -1198,6 +1293,13 @@ fn add_env(build: &Build, cmd: &mut Command, target: &str) {
     }
 }
 
+// rules.dist("dist-sign", "hash-and-sign")
+//      .host(true)
+//      .only_build(true)
+//      .only_host_build(true)
+//      .dep(move |s| s.name("tool-build-manifest").target(&build.build).stage(0))
+//      .run(move |_| dist::hash_and_sign(build));
+//
 pub fn hash_and_sign(build: &Build) {
     let compiler = Compiler::new(0, &build.build);
     let mut cmd = build.tool_cmd(&compiler, "build-manifest");
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 7dbc3e55539..432fdb6a3cb 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -27,6 +27,24 @@ use {Build, Compiler, Mode};
 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"));
 /// Invoke `rustbook` for `target` for the doc book `name`.
 ///
 /// This will not actually generate any documentation if the documentation has
@@ -36,6 +54,21 @@ pub fn rustbook(build: &Build, target: &str, name: &str) {
     rustbook_src(build, target, name, &src);
 }
 
+//rules.doc("doc-unstable-book", "src/doc/unstable-book")
+//     .dep(move |s| {
+//         s.name("tool-rustbook")
+//          .host(&build.build)
+//          .target(&build.build)
+//          .stage(0)
+//     })
+//     .dep(move |s| s.name("doc-unstable-book-gen"))
+//     .default(build.config.docs)
+//     .run(move |s| doc::rustbook_src(build,
+//                                     s.target,
+//                                     "unstable-book",
+//                                     &build.md_doc_out(s.target)));
+
+
 /// Invoke `rustbook` for `target` for the doc book `name` from the `src` path.
 ///
 /// This will not actually generate any documentation if the documentation has
@@ -61,6 +94,15 @@ pub fn rustbook_src(build: &Build, target: &str, name: &str, src: &Path) {
                    .arg(out));
 }
 
+// rules.doc("doc-book", "src/doc/book")
+//      .dep(move |s| {
+//          s.name("tool-rustbook")
+//           .host(&build.build)
+//           .target(&build.build)
+//           .stage(0)
+//      })
+//      .default(build.config.docs)
+//      .run(move |s| doc::book(build, s.target, "book"));
 /// Build the book and associated stuff.
 ///
 /// We need to build:
@@ -137,6 +179,15 @@ fn invoke_rustdoc(build: &Build, target: &str, markdown: &str) {
     build.run(&mut cmd);
 }
 
+// rules.doc("doc-standalone", "src/doc")
+//      .dep(move |s| {
+//          s.name("rustc")
+//           .host(&build.build)
+//           .target(&build.build)
+//           .stage(0)
+//      })
+//      .default(build.config.docs)
+//      .run(move |s| doc::standalone(build, s.target));
 /// Generates all standalone documentation as compiled by the rustdoc in `stage`
 /// for the `target` into `out`.
 ///
@@ -209,6 +260,12 @@ pub fn standalone(build: &Build, target: &str) {
     }
 }
 
+// for (krate, path, default) in krates("std") {
+//     rules.doc(&krate.doc_step, path)
+//          .dep(|s| s.name("libstd-link"))
+//          .default(default && build.config.docs)
+//          .run(move |s| doc::std(build, s.stage, s.target));
+// }
 /// Compile all standard library documentation.
 ///
 /// This will generate all documentation for the standard library and its
@@ -268,6 +325,14 @@ pub fn std(build: &Build, stage: u32, target: &str) {
     cp_r(&my_out, &out);
 }
 
+// for (krate, path, default) in krates("test") {
+//     rules.doc(&krate.doc_step, path)
+//          .dep(|s| s.name("libtest-link"))
+//          // Needed so rustdoc generates relative links to std.
+//          .dep(|s| s.name("doc-crate-std"))
+//          .default(default && build.config.compiler_docs)
+//          .run(move |s| doc::test(build, s.stage, s.target));
+// }
 /// Compile all libtest documentation.
 ///
 /// This will generate all documentation for libtest and its dependencies. This
@@ -298,6 +363,17 @@ pub fn test(build: &Build, stage: u32, target: &str) {
     cp_r(&my_out, &out);
 }
 
+
+// for (krate, path, default) in krates("rustc-main") {
+//     rules.doc(&krate.doc_step, path)
+//          .dep(|s| s.name("librustc-link"))
+//          // Needed so rustdoc generates relative links to std.
+//          .dep(|s| s.name("doc-crate-std"))
+//          .host(true)
+//          .default(default && build.config.docs)
+//          .run(move |s| doc::rustc(build, s.stage, s.target));
+// }
+//
 /// Generate all compiler documentation.
 ///
 /// This will generate all documentation for the compiler libraries and their
@@ -345,6 +421,13 @@ pub fn rustc(build: &Build, stage: u32, target: &str) {
     cp_r(&my_out, &out);
 }
 
+// rules.doc("doc-error-index", "src/tools/error_index_generator")
+//      .dep(move |s| s.name("tool-error-index").target(&build.build).stage(0))
+//      .dep(move |s| s.name("librustc-link"))
+//      .default(build.config.docs)
+//      .host(true)
+//      .run(move |s| doc::error_index(build, s.target));
+
 /// Generates the HTML rendered error-index by running the
 /// `error_index_generator` tool.
 pub fn error_index(build: &Build, target: &str) {
@@ -362,6 +445,18 @@ pub fn error_index(build: &Build, target: &str) {
     build.run(&mut index);
 }
 
+// rules.doc("doc-unstable-book-gen", "src/tools/unstable-book-gen")
+//      .dep(move |s| {
+//          s.name("tool-unstable-book-gen")
+//           .host(&build.build)
+//           .target(&build.build)
+//           .stage(0)
+//      })
+//      .dep(move |s| s.name("libstd-link"))
+//      .default(build.config.docs)
+//      .host(true)
+//      .run(move |s| doc::unstable_book_gen(build, s.target));
+
 pub fn unstable_book_gen(build: &Build, target: &str) {
     println!("Generating unstable book md files ({})", target);
     let out = build.md_doc_out(target).join("unstable-book");
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 8e2ef527b16..638b0613bf2 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -148,3 +148,45 @@ fn add_destdir(path: &Path, destdir: &Option<PathBuf>) -> PathBuf {
     }
     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));
+*/
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index e06de5bac4b..e51bb5b65a9 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -106,7 +106,6 @@ mod flags;
 mod install;
 mod native;
 mod sanity;
-mod step;
 pub mod util;
 
 #[cfg(windows)]
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 20eec97d8e5..d28060559ac 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -33,6 +33,16 @@ use Build;
 use util;
 use build_helper::up_to_date;
 
+/ rules.build("llvm", "src/llvm")
+//      .host(true)
+//      .dep(move |s| {
+//          if s.target == build.build {
+//              Step::noop()
+//          } else {
+//              s.target(&build.build)
+//          }
+//      })
+//      .run(move |s| native::llvm(build, s.target));
 /// Compile LLVM for `target`.
 pub fn llvm(build: &Build, target: &str) {
     // If we're using a custom LLVM bail out here, but we can only use a
@@ -216,6 +226,8 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
     panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
 }
 
+//rules.build("test-helpers", "src/rt/rust_test_helpers.c")
+//     .run(move |s| native::test_helpers(build, s.target));
 /// Compiles the `rust_test_helpers.c` library which we used in various
 /// `run-pass` test suites for ABI testing.
 pub fn test_helpers(build: &Build, target: &str) {
@@ -253,6 +265,9 @@ const OPENSSL_VERS: &'static str = "1.0.2k";
 const OPENSSL_SHA256: &'static str =
     "6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0";
 
+//rules.build("openssl", "path/to/nowhere")
+//     .run(move |s| native::openssl(build, s.target));
+
 pub fn openssl(build: &Build, target: &str) {
     let out = match build.openssl_dir(target) {
         Some(dir) => dir,