about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/crates.mk2
-rw-r--r--mk/dist.mk1
-rw-r--r--mk/tests.mk2
-rw-r--r--src/bootstrap/bootstrap.py2
-rw-r--r--src/bootstrap/build/check.rs53
-rw-r--r--src/bootstrap/build/clean.rs2
-rw-r--r--src/bootstrap/build/compile.rs9
-rw-r--r--src/bootstrap/build/dist.rs53
-rw-r--r--src/bootstrap/build/flags.rs5
-rw-r--r--src/bootstrap/build/mod.rs117
-rw-r--r--src/bootstrap/build/native.rs27
-rw-r--r--src/bootstrap/build/sanity.rs19
-rw-r--r--src/bootstrap/build/step.rs68
-rw-r--r--src/test/auxiliary/rbmtp_cross_crate_lib.rs (renamed from src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs)0
-rw-r--r--src/test/auxiliary/tdticc_coherence_lib.rs (renamed from src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs)0
-rw-r--r--src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs4
-rw-r--r--src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs4
-rw-r--r--src/tools/compiletest/Cargo.lock70
-rw-r--r--src/tools/compiletest/Cargo.toml15
-rw-r--r--src/tools/compiletest/build.rs13
-rw-r--r--src/tools/compiletest/src/common.rs (renamed from src/compiletest/common.rs)4
-rw-r--r--src/tools/compiletest/src/errors.rs (renamed from src/compiletest/errors.rs)0
-rw-r--r--src/tools/compiletest/src/header.rs (renamed from src/compiletest/header.rs)0
-rw-r--r--src/tools/compiletest/src/main.rs (renamed from src/compiletest/compiletest.rs)19
-rw-r--r--src/tools/compiletest/src/procsrv.rs (renamed from src/compiletest/procsrv.rs)0
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs (renamed from src/compiletest/raise_fd_limit.rs)0
-rw-r--r--src/tools/compiletest/src/runtest.rs (renamed from src/compiletest/runtest.rs)6
-rw-r--r--src/tools/compiletest/src/util.rs (renamed from src/compiletest/util.rs)0
28 files changed, 432 insertions, 63 deletions
diff --git a/mk/crates.mk b/mk/crates.mk
index dafda75f5fe..4003e092034 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -133,7 +133,7 @@ TOOL_DEPS_rustdoc := rustdoc
 TOOL_DEPS_rustc := rustc_driver
 TOOL_DEPS_rustbook := std rustdoc
 TOOL_DEPS_error_index_generator := rustdoc syntax serialize
-TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
+TOOL_SOURCE_compiletest := $(S)src/tools/compiletest/src/main.rs
 TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
 TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
 TOOL_SOURCE_rustbook := $(S)src/tools/rustbook/main.rs
diff --git a/mk/dist.mk b/mk/dist.mk
index 12739006083..48e01a25334 100644
--- a/mk/dist.mk
+++ b/mk/dist.mk
@@ -50,7 +50,6 @@ PKG_FILES := \
     $(addprefix $(S)src/,                      \
       bootstrap                                \
       build_helper                             \
-      compiletest                              \
       doc                                      \
       driver                                   \
       etc                                      \
diff --git a/mk/tests.mk b/mk/tests.mk
index 2e7b85f5728..41b078efafc 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -611,7 +611,7 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
         --run-lib-path $$(TLIB$(1)_T_$(2)_H_$(3)) \
         --rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
         --rustdoc-path $$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
-        --llvm-bin-path $(CFG_LLVM_INST_DIR_$(CFG_BUILD))/bin \
+        --llvm-filecheck $(CFG_LLVM_INST_DIR_$(CFG_BUILD))/bin/FileCheck \
         --aux-base $$(S)src/test/auxiliary/ \
         --stage-id stage$(1)-$(2) \
         --target $(2) \
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 84b8ad333c1..d852bd82416 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -335,11 +335,11 @@ sys.stdout.flush()
 
 # Run the bootstrap
 args = [os.path.join(rb.build_dir, "bootstrap/debug/bootstrap")]
-args.extend(sys.argv[1:])
 args.append('--src')
 args.append(rb.rust_root)
 args.append('--build')
 args.append(rb.build)
+args.extend(sys.argv[1:])
 env = os.environ.copy()
 env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
 rb.run(args, env)
diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs
index 6aad49bc988..f145a7149fb 100644
--- a/src/bootstrap/build/check.rs
+++ b/src/bootstrap/build/check.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::fs;
+use std::path::PathBuf;
 
 use build::{Build, Compiler};
 
@@ -49,3 +50,55 @@ pub fn tidy(build: &Build, stage: u32, host: &str) {
     build.run(build.tool_cmd(&compiler, "tidy")
                    .arg(build.src.join("src")));
 }
+
+fn testdir(build: &Build, host: &str) -> PathBuf {
+    build.out.join(host).join("test")
+}
+
+pub fn compiletest(build: &Build,
+                   compiler: &Compiler,
+                   target: &str,
+                   mode: &str,
+                   suite: &str) {
+    let mut cmd = build.tool_cmd(compiler, "compiletest");
+
+    cmd.arg("--compile-lib-path").arg(build.rustc_libdir(compiler));
+    cmd.arg("--run-lib-path").arg(build.sysroot_libdir(compiler, target));
+    cmd.arg("--rustc-path").arg(build.compiler_path(compiler));
+    cmd.arg("--rustdoc-path").arg(build.rustdoc(compiler));
+    cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
+    cmd.arg("--aux-base").arg(build.src.join("src/test/auxiliary"));
+    cmd.arg("--build-base").arg(testdir(build, compiler.host).join(suite));
+    cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
+    cmd.arg("--mode").arg(mode);
+    cmd.arg("--target").arg(target);
+    cmd.arg("--host").arg(compiler.host);
+    cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
+
+    let linkflag = format!("-Lnative={}", build.test_helpers_out(target).display());
+    cmd.arg("--host-rustcflags").arg("-Crpath");
+    cmd.arg("--target-rustcflags").arg(format!("-Crpath {}", linkflag));
+
+    // FIXME: needs android support
+    cmd.arg("--android-cross-path").arg("");
+    // FIXME: CFG_PYTHON should probably be detected more robustly elsewhere
+    cmd.arg("--python").arg("python");
+
+    if let Some(ref vers) = build.gdb_version {
+        cmd.arg("--gdb-version").arg(vers);
+    }
+    if let Some(ref vers) = build.lldb_version {
+        cmd.arg("--lldb-version").arg(vers);
+    }
+    if let Some(ref dir) = build.lldb_python_dir {
+        cmd.arg("--lldb-python-dir").arg(dir);
+    }
+
+    cmd.args(&build.flags.args);
+
+    if build.config.verbose || build.flags.verbose {
+        cmd.arg("--verbose");
+    }
+
+    build.run(&mut cmd);
+}
diff --git a/src/bootstrap/build/clean.rs b/src/bootstrap/build/clean.rs
index 796d70bdecf..1f6538f5eae 100644
--- a/src/bootstrap/build/clean.rs
+++ b/src/bootstrap/build/clean.rs
@@ -25,8 +25,8 @@ pub fn clean(build: &Build) {
             rm_rf(build, &out.join(format!("stage{}", stage)));
             rm_rf(build, &out.join(format!("stage{}-std", stage)));
             rm_rf(build, &out.join(format!("stage{}-rustc", stage)));
-            rm_rf(build, &out.join(format!("stage{}-test", stage)));
             rm_rf(build, &out.join(format!("stage{}-tools", stage)));
+            rm_rf(build, &out.join(format!("stage{}-test", stage)));
         }
     }
 }
diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs
index a67f1ba48b5..7a582d853d8 100644
--- a/src/bootstrap/build/compile.rs
+++ b/src/bootstrap/build/compile.rs
@@ -191,14 +191,7 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
     if !build.unstable_features {
         cargo.env("CFG_DISABLE_UNSTABLE_FEATURES", "1");
     }
-    let target_config = build.config.target_config.get(target);
-    if let Some(ref s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
-        cargo.env("LLVM_CONFIG", s);
-    } else {
-        let llvm_config = build.llvm_out(&build.config.build).join("bin")
-                               .join(exe("llvm-config", target));
-        cargo.env("LLVM_CONFIG", llvm_config);
-    }
+    cargo.env("LLVM_CONFIG", build.llvm_config(target));
     if build.config.llvm_static_stdcpp {
         cargo.env("LLVM_STATIC_STDCPP",
                   compiler_file(build.cxx(target), "libstdc++.a"));
diff --git a/src/bootstrap/build/dist.rs b/src/bootstrap/build/dist.rs
index 6ae652bd66d..f2e3117fa97 100644
--- a/src/bootstrap/build/dist.rs
+++ b/src/bootstrap/build/dist.rs
@@ -195,29 +195,7 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
         cp_r(&build.src.join("man"), &image.join("share/man/man1"));
 
         // Debugger scripts
-        let cp_debugger_script = |file: &str| {
-            let dst = image.join("lib/rustlib/etc");
-            t!(fs::create_dir_all(&dst));
-            install(&build.src.join("src/etc/").join(file), &dst, 0o644);
-        };
-        if host.contains("windows") {
-            // no debugger scripts
-        } else if host.contains("darwin") {
-            // lldb debugger scripts
-            install(&build.src.join("src/etc/rust-lldb"), &image.join("bin"),
-                    0o755);
-
-            cp_debugger_script("lldb_rust_formatters.py");
-            cp_debugger_script("debugger_pretty_printers_common.py");
-        } else {
-            // gdb debugger scripts
-            install(&build.src.join("src/etc/rust-gdb"), &image.join("bin"),
-                    0o755);
-
-            cp_debugger_script("gdb_load_rust_pretty_printers.py");
-            cp_debugger_script("gdb_rust_pretty_printing.py");
-            cp_debugger_script("debugger_pretty_printers_common.py");
-        }
+        debugger_scripts(build, &image, host);
 
         // Misc license info
         let cp = |file: &str| {
@@ -231,6 +209,35 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
     }
 }
 
+pub fn debugger_scripts(build: &Build,
+                        sysroot: &Path,
+                        host: &str) {
+    let cp_debugger_script = |file: &str| {
+        let dst = sysroot.join("lib/rustlib/etc");
+        t!(fs::create_dir_all(&dst));
+        install(&build.src.join("src/etc/").join(file), &dst, 0o644);
+    };
+    if host.contains("windows") {
+        // no debugger scripts
+    } else if host.contains("darwin") {
+        // lldb debugger scripts
+        install(&build.src.join("src/etc/rust-lldb"), &sysroot.join("bin"),
+                0o755);
+
+        cp_debugger_script("lldb_rust_formatters.py");
+        cp_debugger_script("debugger_pretty_printers_common.py");
+    } else {
+        // gdb debugger scripts
+        install(&build.src.join("src/etc/rust-gdb"), &sysroot.join("bin"),
+                0o755);
+
+        cp_debugger_script("gdb_load_rust_pretty_printers.py");
+        cp_debugger_script("gdb_rust_pretty_printing.py");
+        cp_debugger_script("debugger_pretty_printers_common.py");
+    }
+}
+
+
 pub fn std(build: &Build, compiler: &Compiler, target: &str) {
     println!("Dist std stage{} ({} -> {})", compiler.stage, compiler.host,
              target);
diff --git a/src/bootstrap/build/flags.rs b/src/bootstrap/build/flags.rs
index d91dfe0903d..67f33e29cae 100644
--- a/src/bootstrap/build/flags.rs
+++ b/src/bootstrap/build/flags.rs
@@ -62,11 +62,6 @@ impl Flags {
             usage(0);
         }
 
-        if m.free.len() > 0 {
-            println!("free arguments are not currently accepted");
-            usage(1);
-        }
-
         let cfg_file = m.opt_str("config").map(PathBuf::from).or_else(|| {
             if fs::metadata("config.toml").is_ok() {
                 Some(PathBuf::from("config.toml"))
diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs
index 4f0bfb84344..e755416f17f 100644
--- a/src/bootstrap/build/mod.rs
+++ b/src/bootstrap/build/mod.rs
@@ -80,6 +80,11 @@ pub struct Build {
     package_vers: String,
     bootstrap_key: String,
 
+    // Probed tools at runtime
+    gdb_version: Option<String>,
+    lldb_version: Option<String>,
+    lldb_python_dir: Option<String>,
+
     // Runtime state filled in later on
     cc: HashMap<String, (gcc::Tool, PathBuf)>,
     cxx: HashMap<String, gcc::Tool>,
@@ -128,6 +133,9 @@ impl Build {
             cc: HashMap::new(),
             cxx: HashMap::new(),
             compiler_rt_built: RefCell::new(HashMap::new()),
+            gdb_version: None,
+            lldb_version: None,
+            lldb_python_dir: None,
         }
     }
 
@@ -160,6 +168,9 @@ impl Build {
                 CompilerRt { _dummy } => {
                     native::compiler_rt(self, target.target);
                 }
+                TestHelpers { _dummy } => {
+                    native::test_helpers(self, target.target);
+                }
                 Libstd { compiler } => {
                     compile::std(self, target.target, &compiler);
                 }
@@ -200,6 +211,9 @@ impl Build {
                 ToolTidy { stage } => {
                     compile::tool(self, stage, target.target, "tidy");
                 }
+                ToolCompiletest { stage } => {
+                    compile::tool(self, stage, target.target, "compiletest");
+                }
                 DocBook { stage } => {
                     doc::rustbook(self, stage, target.target, "book", &doc_out);
                 }
@@ -236,12 +250,75 @@ impl Build {
                 CheckTidy { stage } => {
                     check::tidy(self, stage, target.target);
                 }
+                CheckRPass { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "run-pass", "run-pass");
+                }
+                CheckCFail { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "compile-fail", "compile-fail");
+                }
+                CheckPFail { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "parse-fail", "parse-fail");
+                }
+                CheckRFail { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "run-fail", "run-fail");
+                }
+                CheckPretty { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "pretty", "pretty");
+                }
+                CheckCodegen { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "codegen", "codegen");
+                }
+                CheckCodegenUnits { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "codegen-units", "codegen-units");
+                }
+                CheckDebuginfo { compiler } => {
+                    if target.target.contains("msvc") ||
+                       target.target.contains("android") {
+                        // nothing to do
+                    } else if target.target.contains("apple") {
+                        check::compiletest(self, &compiler, target.target,
+                                           "debuginfo-lldb", "debuginfo");
+                    } else {
+                        check::compiletest(self, &compiler, target.target,
+                                           "debuginfo-gdb", "debuginfo");
+                    }
+                }
+                CheckRustdoc { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "rustdoc", "rustdoc");
+                }
+                CheckRPassValgrind { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "run-pass-valgrind", "run-pass-valgrind");
+                }
+                CheckRPassFull { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "run-pass", "run-pass-fulldeps");
+                }
+                CheckCFailFull { compiler } => {
+                    check::compiletest(self, &compiler, target.target,
+                                       "compile-fail", "compile-fail-fulldeps")
+                }
 
                 DistDocs { stage } => dist::docs(self, stage, target.target),
                 DistMingw { _dummy } => dist::mingw(self, target.target),
                 DistRustc { stage } => dist::rustc(self, stage, target.target),
                 DistStd { compiler } => dist::std(self, &compiler, target.target),
 
+                DebuggerScripts { stage } => {
+                    let compiler = Compiler::new(stage, target.target);
+                    dist::debugger_scripts(self,
+                                           &self.sysroot(&compiler),
+                                           target.target);
+                }
+
                 Dist { .. } |
                 Doc { .. } | // pseudo-steps
                 Check { .. } => {}
@@ -388,6 +465,7 @@ impl Build {
             self.cargo_out(compiler, Mode::Libstd, host).join("deps"),
             self.cargo_out(compiler, Mode::Libtest, host).join("deps"),
             self.cargo_out(compiler, Mode::Librustc, host).join("deps"),
+            self.cargo_out(compiler, Mode::Tool, host).join("deps"),
         ];
         add_lib_path(paths, &mut cmd);
         return cmd
@@ -442,7 +520,8 @@ impl Build {
         let suffix = match mode {
             Mode::Libstd => "-std",
             Mode::Libtest => "-test",
-            Mode::Tool | Mode::Librustc => "-rustc",
+            Mode::Tool => "-tools",
+            Mode::Librustc => "-rustc",
         };
         self.out.join(compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
@@ -463,11 +542,44 @@ impl Build {
         self.out.join(target).join("llvm")
     }
 
+    /// Returns the path to `llvm-config` for the specified target
+    fn llvm_config(&self, target: &str) -> PathBuf {
+        let target_config = self.config.target_config.get(target);
+        if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+            s.clone()
+        } else {
+            self.llvm_out(&self.config.build).join("bin")
+                .join(exe("llvm-config", target))
+        }
+    }
+
+    /// Returns the path to `llvm-config` for the specified target
+    fn llvm_filecheck(&self, target: &str) -> PathBuf {
+        let target_config = self.config.target_config.get(target);
+        if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
+            s.parent().unwrap().join(exe("FileCheck", target))
+        } else {
+            let base = self.llvm_out(&self.config.build).join("build");
+            let exe = exe("FileCheck", target);
+            if self.config.build.contains("msvc") {
+                base.join("Release/bin").join(exe)
+            } else {
+                base.join("bin").join(exe)
+            }
+        }
+    }
+
     /// Root output directory for compiler-rt compiled for `target`
     fn compiler_rt_out(&self, target: &str) -> PathBuf {
         self.out.join(target).join("compiler-rt")
     }
 
+    /// Root output directory for rust_test_helpers library compiled for
+    /// `target`
+    fn test_helpers_out(&self, target: &str) -> PathBuf {
+        self.out.join(target).join("rust-test-helpers")
+    }
+
     fn add_rustc_lib_path(&self, compiler: &Compiler, cmd: &mut Command) {
         // Windows doesn't need dylib path munging because the dlls for the
         // compiler live next to the compiler and the system will find them
@@ -510,8 +622,11 @@ impl Build {
     }
 
     fn cflags(&self, target: &str) -> Vec<String> {
+        // Filter out -O and /O (the optimization flags) that we picked up from
+        // gcc-rs because the build scripts will determine that for themselves.
         let mut base = self.cc[target].0.args().iter()
                            .map(|s| s.to_string_lossy().into_owned())
+                           .filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
                            .collect::<Vec<_>>();
 
         // If we're compiling on OSX then we add a few unconditional flags
diff --git a/src/bootstrap/build/native.rs b/src/bootstrap/build/native.rs
index 91bc0924b1f..59c928ab7b7 100644
--- a/src/bootstrap/build/native.rs
+++ b/src/bootstrap/build/native.rs
@@ -14,9 +14,10 @@ use std::fs;
 
 use build_helper::output;
 use cmake;
+use gcc;
 
 use build::Build;
-use build::util::{exe, staticlib};
+use build::util::{exe, staticlib, up_to_date};
 
 pub fn llvm(build: &Build, target: &str) {
     // If we're using a custom LLVM bail out here, but we can only use a
@@ -152,9 +153,7 @@ pub fn compiler_rt(build: &Build, target: &str) {
     }
     let _ = fs::remove_dir_all(&dst);
     t!(fs::create_dir_all(&dst));
-    let build_llvm_config = build.llvm_out(&build.config.build)
-                                 .join("bin")
-                                 .join(exe("llvm-config", &build.config.build));
+    let build_llvm_config = build.llvm_config(&build.config.build);
     let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
     cfg.target(target)
        .host(&build.config.build)
@@ -171,3 +170,23 @@ pub fn compiler_rt(build: &Build, target: &str) {
        .build_target(&build_target);
     cfg.build();
 }
+
+pub fn test_helpers(build: &Build, target: &str) {
+    let dst = build.test_helpers_out(target);
+    let src = build.src.join("src/rt/rust_test_helpers.c");
+    if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
+        return
+    }
+
+    println!("Building test helpers");
+    t!(fs::create_dir_all(&dst));
+    let mut cfg = gcc::Config::new();
+    cfg.cargo_metadata(false)
+       .out_dir(&dst)
+       .target(target)
+       .host(&build.config.build)
+       .opt_level(0)
+       .debug(false)
+       .file(build.src.join("src/rt/rust_test_helpers.c"))
+       .compile("librust_test_helpers.a");
+}
diff --git a/src/bootstrap/build/sanity.rs b/src/bootstrap/build/sanity.rs
index 50fd9c24538..09e6e467b06 100644
--- a/src/bootstrap/build/sanity.rs
+++ b/src/bootstrap/build/sanity.rs
@@ -66,6 +66,12 @@ pub fn check(build: &mut Build) {
         need_cmd(build.cxx(host).as_ref());
     }
 
+    // Externally configured LLVM requires FileCheck to exist
+    let filecheck = build.llvm_filecheck(&build.config.build);
+    if !filecheck.starts_with(&build.out) && !filecheck.exists() {
+        panic!("filecheck executable {:?} does not exist", filecheck);
+    }
+
     for target in build.config.target.iter() {
         // Either can't build or don't want to run jemalloc on these targets
         if target.contains("rumprun") ||
@@ -134,4 +140,17 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
                    target);
         }
     }
+
+    let run = |cmd: &mut Command| {
+        cmd.output().map(|output| {
+            String::from_utf8_lossy(&output.stdout)
+                   .lines().next().unwrap()
+                   .to_string()
+        })
+    };
+    build.gdb_version = run(Command::new("gdb").arg("--version")).ok();
+    build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
+    if build.lldb_version.is_some() {
+        build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
+    }
 }
diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs
index 07cfb96c30d..a22b28a6cdd 100644
--- a/src/bootstrap/build/step.rs
+++ b/src/bootstrap/build/step.rs
@@ -52,6 +52,7 @@ macro_rules! targets {
             (tool_error_index, ToolErrorIndex { stage: u32 }),
             (tool_cargotest, ToolCargoTest { stage: u32 }),
             (tool_tidy, ToolTidy { stage: u32 }),
+            (tool_compiletest, ToolCompiletest { stage: u32 }),
 
             // Steps for long-running native builds. Ideally these wouldn't
             // actually exist and would be part of build scripts, but for now
@@ -61,6 +62,8 @@ macro_rules! targets {
             // with braces are unstable so we just pick something that works.
             (llvm, Llvm { _dummy: () }),
             (compiler_rt, CompilerRt { _dummy: () }),
+            (test_helpers, TestHelpers { _dummy: () }),
+            (debugger_scripts, DebuggerScripts { stage: u32 }),
 
             // Steps for various pieces of documentation that we can generate,
             // the 'doc' step is just a pseudo target to depend on a bunch of
@@ -81,6 +84,18 @@ macro_rules! targets {
             (check_linkcheck, CheckLinkcheck { stage: u32 }),
             (check_cargotest, CheckCargoTest { stage: u32 }),
             (check_tidy, CheckTidy { stage: u32 }),
+            (check_rpass, CheckRPass { compiler: Compiler<'a> }),
+            (check_rfail, CheckRFail { compiler: Compiler<'a> }),
+            (check_cfail, CheckCFail { compiler: Compiler<'a> }),
+            (check_pfail, CheckPFail { compiler: Compiler<'a> }),
+            (check_codegen, CheckCodegen { compiler: Compiler<'a> }),
+            (check_codegen_units, CheckCodegenUnits { compiler: Compiler<'a> }),
+            (check_debuginfo, CheckDebuginfo { compiler: Compiler<'a> }),
+            (check_rustdoc, CheckRustdoc { compiler: Compiler<'a> }),
+            (check_pretty, CheckPretty { compiler: Compiler<'a> }),
+            (check_rpass_valgrind, CheckRPassValgrind { compiler: Compiler<'a> }),
+            (check_rpass_full, CheckRPassFull { compiler: Compiler<'a> }),
+            (check_cfail_full, CheckCFailFull { compiler: Compiler<'a> }),
 
             // Distribution targets, creating tarballs
             (dist, Dist { stage: u32 }),
@@ -278,6 +293,8 @@ impl<'a> Step<'a> {
                 vec![self.llvm(()).target(&build.config.build)]
             }
             Source::Llvm { _dummy } => Vec::new(),
+            Source::TestHelpers { _dummy } => Vec::new(),
+            Source::DebuggerScripts { stage: _ } => Vec::new(),
 
             // Note that all doc targets depend on artifacts from the build
             // architecture, not the target (which is where we're generating
@@ -310,9 +327,23 @@ impl<'a> Step<'a> {
                      self.doc_std(stage),
                      self.doc_error_index(stage)]
             }
-            Source::Check { stage, compiler: _ } => {
-                vec![self.check_linkcheck(stage),
-                     self.dist(stage)]
+            Source::Check { stage, compiler } => {
+                vec![
+                    self.check_rpass(compiler),
+                    self.check_cfail(compiler),
+                    self.check_rfail(compiler),
+                    self.check_pfail(compiler),
+                    self.check_codegen(compiler),
+                    self.check_codegen_units(compiler),
+                    self.check_debuginfo(compiler),
+                    self.check_rustdoc(compiler),
+                    self.check_pretty(compiler),
+                    self.check_rpass_valgrind(compiler),
+                    self.check_rpass_full(compiler),
+                    self.check_cfail_full(compiler),
+                    self.check_linkcheck(stage),
+                    self.dist(stage),
+                ]
             }
             Source::CheckLinkcheck { stage } => {
                 vec![self.tool_linkchecker(stage), self.doc(stage)]
@@ -324,6 +355,34 @@ impl<'a> Step<'a> {
             Source::CheckTidy { stage } => {
                 vec![self.tool_tidy(stage)]
             }
+            Source::CheckRFail { compiler } |
+            Source::CheckPFail { compiler } |
+            Source::CheckCodegen { compiler } |
+            Source::CheckCodegenUnits { compiler } |
+            Source::CheckRustdoc { compiler } |
+            Source::CheckPretty { compiler } |
+            Source::CheckCFail { compiler } |
+            Source::CheckRPassValgrind { compiler } |
+            Source::CheckRPass { compiler } => {
+                vec![
+                    self.libtest(compiler),
+                    self.tool_compiletest(compiler.stage),
+                    self.test_helpers(()),
+                ]
+            }
+            Source::CheckDebuginfo { compiler } => {
+                vec![
+                    self.libtest(compiler),
+                    self.tool_compiletest(compiler.stage),
+                    self.test_helpers(()),
+                    self.debugger_scripts(compiler.stage),
+                ]
+            }
+            Source::CheckRPassFull { compiler } |
+            Source::CheckCFailFull { compiler } => {
+                vec![self.librustc(compiler),
+                     self.tool_compiletest(compiler.stage)]
+            }
 
             Source::ToolLinkchecker { stage } |
             Source::ToolTidy { stage } => {
@@ -336,6 +395,9 @@ impl<'a> Step<'a> {
             Source::ToolCargoTest { stage } => {
                 vec![self.libstd(self.compiler(stage))]
             }
+            Source::ToolCompiletest { stage } => {
+                vec![self.libtest(self.compiler(stage))]
+            }
 
             Source::DistDocs { stage } => vec![self.doc(stage)],
             Source::DistMingw { _dummy: _ } => Vec::new(),
diff --git a/src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs b/src/test/auxiliary/rbmtp_cross_crate_lib.rs
index f49ac4fc8e4..f49ac4fc8e4 100644
--- a/src/test/auxiliary/regions_bounded_method_type_parameters_cross_crate_lib.rs
+++ b/src/test/auxiliary/rbmtp_cross_crate_lib.rs
diff --git a/src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs b/src/test/auxiliary/tdticc_coherence_lib.rs
index 2e425ac96c5..2e425ac96c5 100644
--- a/src/test/auxiliary/typeck_default_trait_impl_cross_crate_coherence_lib.rs
+++ b/src/test/auxiliary/tdticc_coherence_lib.rs
diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs
index 82d05c5d716..1eb36e34ab3 100644
--- a/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs
+++ b/src/test/compile-fail/regions-bounded-method-type-parameters-cross-crate.rs
@@ -8,11 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:regions_bounded_method_type_parameters_cross_crate_lib.rs
+// aux-build:rbmtp_cross_crate_lib.rs
 
 // Check explicit region bounds on methods in the cross crate case.
 
-extern crate regions_bounded_method_type_parameters_cross_crate_lib as lib;
+extern crate rbmtp_cross_crate_lib as lib;
 
 use lib::Inv;
 use lib::MaybeOwned;
diff --git a/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs b/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs
index b1febae7680..b918b0dde47 100644
--- a/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs
+++ b/src/test/compile-fail/typeck-default-trait-impl-cross-crate-coherence.rs
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// aux-build:typeck_default_trait_impl_cross_crate_coherence_lib.rs
+// aux-build:tdticc_coherence_lib.rs
 
 // Test that we do not consider associated types to be sendable without
 // some applicable trait bound (and we don't ICE).
 
 #![feature(optin_builtin_traits)]
 
-extern crate typeck_default_trait_impl_cross_crate_coherence_lib as lib;
+extern crate tdticc_coherence_lib as lib;
 
 use lib::DefaultedTrait;
 
diff --git a/src/tools/compiletest/Cargo.lock b/src/tools/compiletest/Cargo.lock
new file mode 100644
index 00000000000..3b79636a2db
--- /dev/null
+++ b/src/tools/compiletest/Cargo.lock
@@ -0,0 +1,70 @@
+[root]
+name = "compiletest"
+version = "0.0.0"
+dependencies = [
+ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "env_logger"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.62 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "log"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "memchr"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "mempool"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "regex"
+version = "0.1.62"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mempool 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "utf8-ranges"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
new file mode 100644
index 00000000000..359efe8af62
--- /dev/null
+++ b/src/tools/compiletest/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "compiletest"
+version = "0.0.0"
+build = "build.rs"
+
+# Curiously, this will segfault if compiled with opt-level=3 on 64-bit MSVC when
+# running the compile-fail test suite when a should-fail test panics. But hey if
+# this is removed and it gets past the bots, sounds good to me.
+[profile.release]
+opt-level = 2
+
+[dependencies]
+log = "0.3"
+env_logger = "0.3"
diff --git a/src/tools/compiletest/build.rs b/src/tools/compiletest/build.rs
new file mode 100644
index 00000000000..d5164b9b759
--- /dev/null
+++ b/src/tools/compiletest/build.rs
@@ -0,0 +1,13 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    println!("cargo:rustc-cfg=cargobuild");
+}
diff --git a/src/compiletest/common.rs b/src/tools/compiletest/src/common.rs
index a6960ff1785..6ffc1e9ea11 100644
--- a/src/compiletest/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -86,8 +86,8 @@ pub struct Config {
     // The python executable
     pub python: String,
 
-    // The llvm binaries path
-    pub llvm_bin_path: Option<PathBuf>,
+    // The llvm FileCheck binary path
+    pub llvm_filecheck: Option<PathBuf>,
 
     // The valgrind path
     pub valgrind_path: Option<String>,
diff --git a/src/compiletest/errors.rs b/src/tools/compiletest/src/errors.rs
index 418a0bc7121..418a0bc7121 100644
--- a/src/compiletest/errors.rs
+++ b/src/tools/compiletest/src/errors.rs
diff --git a/src/compiletest/header.rs b/src/tools/compiletest/src/header.rs
index ef93fcfa013..ef93fcfa013 100644
--- a/src/compiletest/header.rs
+++ b/src/tools/compiletest/src/header.rs
diff --git a/src/compiletest/compiletest.rs b/src/tools/compiletest/src/main.rs
index 8d2558e4344..e92b0c87280 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_type = "bin"]
+#![crate_name = "compiletest"]
 
 #![feature(box_syntax)]
-#![feature(libc)]
 #![feature(rustc_private)]
 #![feature(test)]
 #![feature(question_mark)]
+#![feature(libc)]
 
 #![deny(warnings)]
 
@@ -25,6 +25,9 @@ extern crate getopts;
 #[macro_use]
 extern crate log;
 
+#[cfg(cargobuild)]
+extern crate env_logger;
+
 use std::env;
 use std::fs;
 use std::io;
@@ -43,7 +46,13 @@ pub mod common;
 pub mod errors;
 mod raise_fd_limit;
 
-pub fn main() {
+fn main() {
+    #[cfg(cargobuild)]
+    fn log_init() { env_logger::init().unwrap(); }
+    #[cfg(not(cargobuild))]
+    fn log_init() {}
+    log_init();
+
     let config = parse_config(env::args().collect());
 
     if config.valgrind_path.is_none() && config.force_valgrind {
@@ -64,7 +73,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
           reqopt("", "python", "path to python to use for doc tests", "PATH"),
           optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM"),
           optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind"),
-          optopt("", "llvm-bin-path", "path to directory holding llvm binaries", "DIR"),
+          optopt("", "llvm-filecheck", "path to LLVM's FileCheck binary", "DIR"),
           reqopt("", "src-base", "directory to scan for test files", "PATH"),
           reqopt("", "build-base", "directory to deposit test outputs", "PATH"),
           reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
@@ -134,7 +143,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         python: matches.opt_str("python").unwrap(),
         valgrind_path: matches.opt_str("valgrind-path"),
         force_valgrind: matches.opt_present("force-valgrind"),
-        llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::from(&s)),
+        llvm_filecheck: matches.opt_str("llvm-filecheck").map(|s| PathBuf::from(&s)),
         src_base: opt_path(matches, "src-base"),
         build_base: opt_path(matches, "build-base"),
         aux_base: opt_path(matches, "aux-base"),
diff --git a/src/compiletest/procsrv.rs b/src/tools/compiletest/src/procsrv.rs
index f418edf6686..f418edf6686 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/tools/compiletest/src/procsrv.rs
diff --git a/src/compiletest/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index 0cf90ec95f3..0cf90ec95f3 100644
--- a/src/compiletest/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
diff --git a/src/compiletest/runtest.rs b/src/tools/compiletest/src/runtest.rs
index af482f781ab..6358d19ff09 100644
--- a/src/compiletest/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1845,7 +1845,7 @@ fn compile_test_and_save_ir(config: &Config, props: &TestProps,
 
 fn check_ir_with_filecheck(config: &Config, testpaths: &TestPaths) -> ProcRes {
     let irfile = output_base_name(config, testpaths).with_extension("ll");
-    let prog = config.llvm_bin_path.as_ref().unwrap().join("FileCheck");
+    let prog = config.llvm_filecheck.as_ref().unwrap();
     let proc_args = ProcArgs {
         // FIXME (#9639): This needs to handle non-utf8 paths
         prog: prog.to_str().unwrap().to_owned(),
@@ -1858,8 +1858,8 @@ fn check_ir_with_filecheck(config: &Config, testpaths: &TestPaths) -> ProcRes {
 fn run_codegen_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
     assert!(props.revisions.is_empty(), "revisions not relevant here");
 
-    if config.llvm_bin_path.is_none() {
-        fatal(None, "missing --llvm-bin-path");
+    if config.llvm_filecheck.is_none() {
+        fatal(None, "missing --llvm-filecheck");
     }
 
     let mut proc_res = compile_test_and_save_ir(config, props, testpaths);
diff --git a/src/compiletest/util.rs b/src/tools/compiletest/src/util.rs
index 69b839c5b7d..69b839c5b7d 100644
--- a/src/compiletest/util.rs
+++ b/src/tools/compiletest/src/util.rs