diff options
| author | bors <bors@rust-lang.org> | 2016-12-30 07:34:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-12-30 07:34:19 +0000 |
| commit | 7f2d2afa9196ba6314a29e58d5324dbd9923c75e (patch) | |
| tree | 483907141a5dcd2cfc7e4ea91f7234d77bddf83b /src/bootstrap | |
| parent | 75f5981d4500e52de767d61ec50a34b97be2a301 (diff) | |
| parent | e484197482698ee0bb83a66987a5f64c46ae306b (diff) | |
Auto merge of #38697 - alexcrichton:rollup, r=alexcrichton
Rollup of 25 pull requests - Successful merges: #37149, #38491, #38517, #38559, #38587, #38609, #38611, #38622, #38628, #38630, #38631, #38632, #38635, #38647, #38649, #38655, #38659, #38660, #38662, #38665, #38671, #38674, #38676, #38693, #38695 - Failed merges: #38657, #38680
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/check.rs | 18 | ||||
| -rw-r--r-- | src/bootstrap/compile.rs | 114 | ||||
| -rw-r--r-- | src/bootstrap/config.rs | 7 | ||||
| -rw-r--r-- | src/bootstrap/config.toml.example | 18 | ||||
| -rw-r--r-- | src/bootstrap/doc.rs | 15 | ||||
| -rw-r--r-- | src/bootstrap/lib.rs | 28 | ||||
| -rw-r--r-- | src/bootstrap/mk/Makefile.in | 12 | ||||
| -rw-r--r-- | src/bootstrap/native.rs | 9 | ||||
| -rw-r--r-- | src/bootstrap/step.rs | 218 |
9 files changed, 301 insertions, 138 deletions
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index e7b0afeb8ce..ec0243908ed 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -341,12 +341,22 @@ pub fn krate(build: &Build, println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage, compiler.host, target); + // If we're not doing a full bootstrap but we're testing a stage2 version of + // libstd, then what we're actually testing is the libstd produced in + // 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) + } else { + compiler.clone() + }; + // Build up the base `cargo test` command. // // Pass in some standard flags then iterate over the graph we've discovered // in `cargo metadata` with the maps above and figure out what `-p` // arguments need to get passed. - let mut cargo = build.cargo(compiler, mode, target, test_kind.subcommand()); + let mut cargo = build.cargo(&compiler, mode, target, test_kind.subcommand()); cargo.arg("--manifest-path") .arg(build.src.join(path).join("Cargo.toml")) .arg("--features").arg(features); @@ -380,7 +390,7 @@ pub fn krate(build: &Build, // Note that to run the compiler we need to run with the *host* libraries, // but our wrapper scripts arrange for that to be the case anyway. let mut dylib_path = dylib_path(); - dylib_path.insert(0, build.sysroot_libdir(compiler, target)); + dylib_path.insert(0, build.sysroot_libdir(&compiler, target)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); if target.contains("android") { @@ -399,10 +409,10 @@ pub fn krate(build: &Build, if target.contains("android") { build.run(&mut cargo); - krate_android(build, compiler, target, mode); + krate_android(build, &compiler, target, mode); } else if target.contains("emscripten") { build.run(&mut cargo); - krate_emscripten(build, compiler, target, mode); + krate_emscripten(build, &compiler, target, mode); } else { cargo.args(&build.flags.cmd.test_args()); build.run(&mut cargo); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b268686ca6c..dcccf788935 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -33,17 +33,12 @@ use {Build, Compiler, Mode}; /// This will build the standard library for a particular stage of the build /// using the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. -pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { - println!("Building stage{} std artifacts ({} -> {})", compiler.stage, - compiler.host, target); - +pub fn std(build: &Build, target: &str, compiler: &Compiler) { let libdir = build.sysroot_libdir(compiler, target); - let _ = fs::remove_dir_all(&libdir); t!(fs::create_dir_all(&libdir)); - // Some platforms have startup objects that may be required to produce the - // libstd dynamic library, for example. - build_startup_objects(build, target, &libdir); + println!("Building stage{} std artifacts ({} -> {})", compiler.stage, + compiler.host, target); let out_dir = build.cargo_out(compiler, Mode::Libstd, target); build.clear_if_dirty(&out_dir, &build.compiler_path(compiler)); @@ -65,29 +60,30 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { build.run(&mut cargo); update_mtime(&libstd_stamp(build, &compiler, target)); - std_link(build, target, compiler.stage, compiler.host); } /// Link all libstd rlibs/dylibs into the sysroot location. /// -/// Links those artifacts generated in the given `stage` for `target` produced -/// by `compiler` into `host`'s sysroot. +/// Links those artifacts generated by `compiler` to a the `stage` compiler's +/// sysroot for the specified `host` and `target`. +/// +/// Note that this assumes that `compiler` has already generated the libstd +/// libraries for `target`, and this method will find them in the relevant +/// output directory. pub fn std_link(build: &Build, - target: &str, - stage: u32, - host: &str) { - let compiler = Compiler::new(stage, &build.config.build); - let target_compiler = Compiler::new(compiler.stage, host); + compiler: &Compiler, + target_compiler: &Compiler, + target: &str) { + println!("Copying stage{} std from stage{} ({} -> {} / {})", + target_compiler.stage, + compiler.stage, + compiler.host, + target_compiler.host, + target); let libdir = build.sysroot_libdir(&target_compiler, target); let out_dir = build.cargo_out(&compiler, Mode::Libstd, target); - // If we're linking one compiler host's output into another, then we weren't - // called from the `std` method above. In that case we clean out what's - // already there. - if host != compiler.host { - let _ = fs::remove_dir_all(&libdir); - t!(fs::create_dir_all(&libdir)); - } + t!(fs::create_dir_all(&libdir)); add_to_sysroot(&out_dir, &libdir); if target.contains("musl") && !target.contains("mips") { @@ -110,12 +106,15 @@ fn copy_musl_third_party_objects(build: &Build, target: &str, into: &Path) { /// They don't require any library support as they're just plain old object /// files, so we just use the nightly snapshot compiler to always build them (as /// no other compilers are guaranteed to be available). -fn build_startup_objects(build: &Build, target: &str, into: &Path) { +pub fn build_startup_objects(build: &Build, for_compiler: &Compiler, target: &str) { if !target.contains("pc-windows-gnu") { return } + let compiler = Compiler::new(0, &build.config.build); let compiler_path = build.compiler_path(&compiler); + let into = build.sysroot_libdir(for_compiler, target); + t!(fs::create_dir_all(&into)); for file in t!(fs::read_dir(build.src.join("src/rtstartup"))) { let file = t!(file); @@ -123,7 +122,7 @@ fn build_startup_objects(build: &Build, target: &str, into: &Path) { build.run(cmd.env("RUSTC_BOOTSTRAP", "1") .arg("--target").arg(target) .arg("--emit=obj") - .arg("--out-dir").arg(into) + .arg("--out-dir").arg(&into) .arg(file.path())); } @@ -137,7 +136,7 @@ fn build_startup_objects(build: &Build, target: &str, into: &Path) { /// This will build libtest and supporting libraries for a particular stage of /// the build using the `compiler` targeting the `target` architecture. The /// artifacts created will also be linked into the sysroot directory. -pub fn test<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { +pub fn test(build: &Build, target: &str, compiler: &Compiler) { println!("Building stage{} test artifacts ({} -> {})", compiler.stage, compiler.host, target); let out_dir = build.cargo_out(compiler, Mode::Libtest, target); @@ -147,19 +146,19 @@ pub fn test<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { .arg(build.src.join("src/rustc/test_shim/Cargo.toml")); build.run(&mut cargo); update_mtime(&libtest_stamp(build, compiler, target)); - test_link(build, target, compiler.stage, compiler.host); } -/// Link all libtest rlibs/dylibs into the sysroot location. -/// -/// Links those artifacts generated in the given `stage` for `target` produced -/// by `compiler` into `host`'s sysroot. +/// Same as `std_link`, only for libtest pub fn test_link(build: &Build, - target: &str, - stage: u32, - host: &str) { - let compiler = Compiler::new(stage, &build.config.build); - let target_compiler = Compiler::new(compiler.stage, host); + compiler: &Compiler, + target_compiler: &Compiler, + target: &str) { + println!("Copying stage{} test from stage{} ({} -> {} / {})", + target_compiler.stage, + compiler.stage, + compiler.host, + target_compiler.host, + target); let libdir = build.sysroot_libdir(&target_compiler, target); let out_dir = build.cargo_out(&compiler, Mode::Libtest, target); add_to_sysroot(&out_dir, &libdir); @@ -170,7 +169,7 @@ pub fn test_link(build: &Build, /// This will build the compiler for a particular stage of the build using /// the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. -pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { +pub fn rustc(build: &Build, target: &str, compiler: &Compiler) { println!("Building stage{} compiler artifacts ({} -> {})", compiler.stage, compiler.host, target); @@ -222,20 +221,19 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { cargo.env("CFG_DEFAULT_AR", s); } build.run(&mut cargo); - - rustc_link(build, target, compiler.stage, compiler.host); } -/// Link all librustc rlibs/dylibs into the sysroot location. -/// -/// Links those artifacts generated in the given `stage` for `target` produced -/// by `compiler` into `host`'s sysroot. +/// Same as `std_link`, only for librustc pub fn rustc_link(build: &Build, - target: &str, - stage: u32, - host: &str) { - let compiler = Compiler::new(stage, &build.config.build); - let target_compiler = Compiler::new(compiler.stage, host); + compiler: &Compiler, + target_compiler: &Compiler, + target: &str) { + println!("Copying stage{} rustc from stage{} ({} -> {} / {})", + target_compiler.stage, + compiler.stage, + compiler.host, + target_compiler.host, + target); let libdir = build.sysroot_libdir(&target_compiler, target); let out_dir = build.cargo_out(&compiler, Mode::Librustc, target); add_to_sysroot(&out_dir, &libdir); @@ -259,6 +257,17 @@ fn compiler_file(compiler: &Path, file: &str) -> PathBuf { PathBuf::from(out.trim()) } +pub fn create_sysroot(build: &Build, compiler: &Compiler) { + // nothing to do in stage0 + if compiler.stage == 0 { + return + } + + let sysroot = build.sysroot(compiler); + let _ = fs::remove_dir_all(&sysroot); + t!(fs::create_dir_all(&sysroot)); +} + /// Prepare a new compiler from the artifacts in `stage` /// /// This will assemble a compiler in `build/$host/stage$stage`. The compiler @@ -269,18 +278,17 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) { if stage == 0 { return } + + println!("Copying stage{} compiler ({})", stage, host); + // The compiler that we're assembling let target_compiler = Compiler::new(stage, host); // The compiler that compiled the compiler we're assembling let build_compiler = Compiler::new(stage - 1, &build.config.build); - // Clear out old files - let sysroot = build.sysroot(&target_compiler); - let _ = fs::remove_dir_all(&sysroot); - t!(fs::create_dir_all(&sysroot)); - // Link in all dylibs to the libdir + let sysroot = build.sysroot(&target_compiler); let sysroot_libdir = sysroot.join(libdir(host)); t!(fs::create_dir_all(&sysroot_libdir)); let src_libdir = build.sysroot_libdir(&build_compiler, host); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 6b86e537b7d..9767afd73ca 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -46,6 +46,7 @@ pub struct Config { pub docs: bool, pub vendor: bool, pub target_config: HashMap<String, Target>, + pub full_bootstrap: bool, // llvm codegen options pub llvm_assertions: bool, @@ -54,6 +55,7 @@ pub struct Config { pub llvm_version_check: bool, pub llvm_static_stdcpp: bool, pub llvm_link_shared: bool, + pub llvm_targets: Option<String>, // rust codegen options pub rust_optimize: bool, @@ -134,6 +136,7 @@ struct Build { vendor: Option<bool>, nodejs: Option<String>, python: Option<String>, + full_bootstrap: Option<bool>, } /// TOML representation of various global install decisions. @@ -152,6 +155,7 @@ struct Llvm { release_debuginfo: Option<bool>, version_check: Option<bool>, static_libstdcpp: Option<bool>, + targets: Option<String>, } #[derive(RustcDecodable)] @@ -264,6 +268,7 @@ impl Config { set(&mut config.docs, build.docs); set(&mut config.submodules, build.submodules); set(&mut config.vendor, build.vendor); + set(&mut config.full_bootstrap, build.full_bootstrap); if let Some(ref install) = toml.install { config.prefix = install.prefix.clone(); @@ -285,6 +290,7 @@ impl Config { set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); set(&mut config.llvm_version_check, llvm.version_check); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); + config.llvm_targets = llvm.targets.clone(); } if let Some(ref rust) = toml.rust { @@ -393,6 +399,7 @@ impl Config { ("NINJA", self.ninja), ("CODEGEN_TESTS", self.codegen_tests), ("VENDOR", self.vendor), + ("FULL_BOOTSTRAP", self.full_bootstrap), } match key { diff --git a/src/bootstrap/config.toml.example b/src/bootstrap/config.toml.example index 5fc095137c7..69210c4959b 100644 --- a/src/bootstrap/config.toml.example +++ b/src/bootstrap/config.toml.example @@ -42,6 +42,17 @@ # example. #ninja = false +# LLVM targets to build support for. +# Note: this is NOT related to Rust compilation targets. However, as Rust is +# dependent on LLVM for code generation, turning targets off here WILL lead to +# the resulting rustc being unable to compile for the disabled architectures. +# Also worth pointing out is that, in case support for new targets are added to +# LLVM, enabling them here doesn't mean Rust is automatically gaining said +# support. You'll need to write a target specification at least, and most +# likely, teach rustc about the C ABI of the target. Get in touch with the +# Rust team and file an issue if you need assistance in porting! +#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX" + # ============================================================================= # General build configuration options # ============================================================================= @@ -100,6 +111,13 @@ # Indicate whether the vendored sources are used for Rust dependencies or not #vendor = false +# Typically the build system will build the rust compiler twice. The second +# compiler, however, will simply use its own libraries to link against. If you +# would rather to perform a full bootstrap, compiling the compiler three times, +# then you can set this option to true. You shouldn't ever need to set this +# option to true. +#full-bootstrap = false + # ============================================================================= # General install configuration options # ============================================================================= diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 30c7fefad87..4c4462bf122 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -137,6 +137,11 @@ pub fn std(build: &Build, stage: u32, target: &str) { let out = build.doc_out(target); t!(fs::create_dir_all(&out)); let compiler = Compiler::new(stage, &build.config.build); + let compiler = if build.force_use_stage1(&compiler, target) { + Compiler::new(1, compiler.host) + } else { + compiler + }; let out_dir = build.stage_out(&compiler, Mode::Libstd) .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); @@ -160,6 +165,11 @@ pub fn test(build: &Build, stage: u32, target: &str) { let out = build.doc_out(target); t!(fs::create_dir_all(&out)); let compiler = Compiler::new(stage, &build.config.build); + let compiler = if build.force_use_stage1(&compiler, target) { + Compiler::new(1, compiler.host) + } else { + compiler + }; let out_dir = build.stage_out(&compiler, Mode::Libtest) .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); @@ -182,6 +192,11 @@ pub fn rustc(build: &Build, stage: u32, target: &str) { let out = build.doc_out(target); t!(fs::create_dir_all(&out)); let compiler = Compiler::new(stage, &build.config.build); + let compiler = if build.force_use_stage1(&compiler, target) { + Compiler::new(1, compiler.host) + } else { + compiler + }; let out_dir = build.stage_out(&compiler, Mode::Librustc) .join(target).join("doc"); let rustdoc = build.rustdoc(&compiler); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 665e0c67b7f..49eaed4c67a 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -572,9 +572,7 @@ impl Build { let mut cmd = Command::new(self.tool(&compiler, tool)); let host = compiler.host; let mut paths = vec![ - 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.sysroot_libdir(compiler, compiler.host), self.cargo_out(compiler, Mode::Tool, host).join("deps"), ]; @@ -880,6 +878,30 @@ impl Build { fn python(&self) -> &Path { self.config.python.as_ref().unwrap() } + + /// Tests whether the `compiler` compiling for `target` should be forced to + /// use a stage1 compiler instead. + /// + /// Currently, by default, the build system does not perform a "full + /// bootstrap" by default where we compile the compiler three times. + /// Instead, we compile the compiler two times. The final stage (stage2) + /// just copies the libraries from the previous stage, which is what this + /// method detects. + /// + /// Here we return `true` if: + /// + /// * The build isn't performing a full bootstrap + /// * The `compiler` is in the final stage, 2 + /// * We're not cross-compiling, so the artifacts are already available in + /// stage1 + /// + /// When all of these conditions are met the build will lift artifacts from + /// the previous stage forward. + fn force_use_stage1(&self, compiler: &Compiler, target: &str) -> bool { + !self.config.full_bootstrap && + compiler.stage >= 2 && + self.config.host.iter().any(|h| h == target) + } } impl<'a> Compiler<'a> { diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 0d83a79cf32..a3333369930 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -51,8 +51,16 @@ standalone-docs: $(Q)$(BOOTSTRAP) doc src/doc $(BOOTSTRAP_ARGS) check: $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) -check-cargotest: - $(Q)$(BOOTSTRAP) test src/tools/cargotest $(BOOTSTRAP_ARGS) +check-aux: + $(Q)$(BOOTSTRAP) test \ + src/tools/cargotest \ + src/test/pretty \ + src/test/run-pass/pretty \ + src/test/run-fail/pretty \ + src/test/run-pass-valgrind/pretty \ + src/test/run-pass-fulldeps/pretty \ + src/test/run-fail-fulldeps/pretty \ + $(BOOTSTRAP_ARGS) dist: $(Q)$(BOOTSTRAP) dist $(BOOTSTRAP_ARGS) distcheck: diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 09dbd9f8220..4b6fef8edc1 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -75,13 +75,18 @@ pub fn llvm(build: &Build, target: &str) { (true, true) => "RelWithDebInfo", }; + // NOTE: remember to also update `config.toml.example` when changing the defaults! + let llvm_targets = match build.config.llvm_targets { + Some(ref s) => s, + None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX", + }; + cfg.target(target) .host(&build.config.build) .out_dir(&dst) .profile(profile) .define("LLVM_ENABLE_ASSERTIONS", assertions) - .define("LLVM_TARGETS_TO_BUILD", - "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc") + .define("LLVM_TARGETS_TO_BUILD", llvm_targets) .define("LLVM_INCLUDE_EXAMPLES", "OFF") .define("LLVM_INCLUDE_TESTS", "OFF") .define("LLVM_INCLUDE_DOCS", "OFF") diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 52caa3f0958..7bcfb06f210 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -44,7 +44,7 @@ pub fn run(build: &Build) { rules.run(&steps); } -pub fn build_rules(build: &Build) -> Rules { +pub fn build_rules<'a>(build: &'a Build) -> Rules { let mut rules = Rules::new(build); // This is the first rule that we're going to define for rustbuild, which is @@ -117,6 +117,7 @@ pub fn build_rules(build: &Build) -> Rules { // 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() @@ -151,77 +152,145 @@ pub fn build_rules(build: &Build) -> Rules { // Crate compilations // // Tools used during the build system but not shipped + rules.build("create-sysroot", "path/to/nowhere") + .run(move |s| compile::create_sysroot(build, &s.compiler())); + + // 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("build-crate-std_shim")); + .dep(|s| s.name("rustc").target(s.host)) + .dep(|s| s.name("libstd-link")); rules.build("libtest", "src/libtest") - .dep(|s| s.name("build-crate-test_shim")); + .dep(|s| s.name("libstd")) + .dep(|s| s.name("libtest-link")) + .default(true); rules.build("librustc", "src/librustc") - .dep(|s| s.name("build-crate-rustc-main")); + .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.config.build).stage(1) + } else if s.host == build.config.build { + s.name(dep) + } else { + s.host(&build.config.build) + } + }) + .run(move |s| { + if build.force_use_stage1(&s.compiler(), s.target) { + link(build, + &s.stage(1).host(&build.config.build).compiler(), + &s.compiler(), + s.target) + } else if s.host == build.config.build { + link(build, &s.compiler(), &s.compiler(), s.target) + } else { + link(build, + &s.host(&build.config.build).compiler(), + &s.compiler(), + s.target) + } + }); + return rule + } + + // Similar to the `libstd`, `libtest`, and `librustc` rules above, except + // these rules only represent the libraries being available in the sysroot, + // not the compiler itself. This is done as not all rules need a compiler in + // the sysroot, but may just need the libraries. + // + // All of these rules use the helper definition above. + crate_rule(build, + &mut rules, + "libstd-link", + "build-crate-std_shim", + compile::std_link) + .dep(|s| s.name("startup-objects")) + .dep(|s| s.name("create-sysroot").target(s.host)); + crate_rule(build, + &mut rules, + "libtest-link", + "build-crate-test_shim", + compile::test_link) + .dep(|s| s.name("libstd-link")); + crate_rule(build, + &mut rules, + "librustc-link", + "build-crate-rustc-main", + compile::rustc_link) + .dep(|s| s.name("libtest-link")); + for (krate, path, _default) in krates("std_shim") { rules.build(&krate.build_step, path) + .dep(|s| s.name("startup-objects")) .dep(move |s| s.name("rustc").host(&build.config.build).target(s.host)) - .dep(move |s| { - if s.host == build.config.build { - Step::noop() - } else { - s.host(&build.config.build) - } - }) - .run(move |s| { - if s.host == build.config.build { - compile::std(build, s.target, &s.compiler()) - } else { - compile::std_link(build, s.target, s.stage, s.host) - } - }); + .run(move |s| compile::std(build, s.target, &s.compiler())); } - for (krate, path, default) in krates("test_shim") { + for (krate, path, _default) in krates("test_shim") { rules.build(&krate.build_step, path) - .dep(|s| s.name("libstd")) - .dep(move |s| { - if s.host == build.config.build { - Step::noop() - } else { - s.host(&build.config.build) - } - }) - .default(default) - .run(move |s| { - if s.host == build.config.build { - compile::test(build, s.target, &s.compiler()) - } else { - compile::test_link(build, s.target, s.stage, s.host) - } - }); + .dep(|s| s.name("libstd-link")) + .run(move |s| compile::test(build, s.target, &s.compiler())); } - for (krate, path, default) in krates("rustc-main") { + for (krate, path, _default) in krates("rustc-main") { rules.build(&krate.build_step, path) - .dep(|s| s.name("libtest")) + .dep(|s| s.name("libtest-link")) .dep(move |s| s.name("llvm").host(&build.config.build).stage(0)) - .dep(move |s| { - if s.host == build.config.build { - Step::noop() - } else { - s.host(&build.config.build) - } - }) - .host(true) - .default(default) - .run(move |s| { - if s.host == build.config.build { - compile::rustc(build, s.target, &s.compiler()) - } else { - compile::rustc_link(build, s.target, s.stage, s.host) - } - }); + .run(move |s| compile::rustc(build, s.target, &s.compiler())); } + 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)); + // ======================================================================== // Test targets // // Various unit tests and tests suites we can run { - let mut suite = |name, path, dir, mode| { + 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)) @@ -233,9 +302,9 @@ pub fn build_rules(build: &Build) -> Rules { Step::noop() } }) - .default(true) + .default(mode != "pretty") // pretty tests don't run everywhere .run(move |s| { - check::compiletest(build, &s.compiler(), s.target, dir, mode) + check::compiletest(build, &s.compiler(), s.target, mode, dir) }); }; @@ -254,13 +323,6 @@ pub fn build_rules(build: &Build) -> Rules { suite("check-incremental", "src/test/incremental", "incremental", "incremental"); suite("check-ui", "src/test/ui", "ui", "ui"); - 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-pass/pretty", "pretty", - "run-fail"); - suite("check-pretty-valgrind", "src/test/run-pass-valgrind", "pretty", - "run-pass-valgrind"); } if build.config.build.contains("msvc") { @@ -290,14 +352,15 @@ pub fn build_rules(build: &Build) -> Rules { s.target)); { - let mut suite = |name, path, dir, mode| { + 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)) - .default(true) + .default(mode != "pretty") .host(true) .run(move |s| { - check::compiletest(build, &s.compiler(), s.target, dir, mode) + check::compiletest(build, &s.compiler(), s.target, mode, dir) }); }; @@ -307,9 +370,16 @@ pub fn build_rules(build: &Build) -> Rules { "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-rpass-full", "src/test/run-pass-fulldeps", + 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", + suite("check-pretty-rfail-full", "src/test/run-fail-fulldeps/pretty", "pretty", "run-fail-fulldeps"); } @@ -444,25 +514,25 @@ pub fn build_rules(build: &Build) -> Rules { .run(move |s| doc::standalone(build, s.stage, s.target)); rules.doc("doc-error-index", "src/tools/error_index_generator") .dep(move |s| s.name("tool-error-index").target(&build.config.build)) - .dep(move |s| s.name("librustc")) + .dep(move |s| s.name("librustc-link")) .default(build.config.docs) .host(true) .run(move |s| doc::error_index(build, s.stage, s.target)); for (krate, path, default) in krates("std_shim") { rules.doc(&krate.doc_step, path) - .dep(|s| s.name("libstd")) + .dep(|s| s.name("libstd-link")) .default(default && build.config.docs) .run(move |s| doc::std(build, s.stage, s.target)); } for (krate, path, default) in krates("test_shim") { rules.doc(&krate.doc_step, path) - .dep(|s| s.name("libtest")) + .dep(|s| s.name("libtest-link")) .default(default && build.config.compiler_docs) .run(move |s| doc::test(build, s.stage, s.target)); } for (krate, path, default) in krates("rustc-main") { rules.doc(&krate.doc_step, path) - .dep(|s| s.name("librustc")) + .dep(|s| s.name("librustc-link")) .host(true) .default(default && build.config.compiler_docs) .run(move |s| doc::rustc(build, s.stage, s.target)); @@ -481,9 +551,9 @@ pub fn build_rules(build: &Build) -> Rules { // 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") + s.name("librustc-link") } else { - s.name("libtest") + s.name("libtest-link") } }) .default(true) |
