diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 6f27402233f98..b6ff5786186f3 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -115,9 +115,9 @@ fn main() { cmd.env("RUSTC_BREAK_ON_ICE", "1"); if let Some(target) = target { - // The stage0 compiler has a special sysroot distinct from what we - // actually downloaded, so we just always pass the `--sysroot` option. - cmd.arg("--sysroot").arg(&sysroot); + if !sysroot.is_empty() { + cmd.arg("--sysroot").arg(&sysroot); + } // When we build Rust dylibs they're all intended for intermediate // usage, so make sure we pass the -Cprefer-dynamic flag instead of diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 487440becf630..ff88872697531 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -311,6 +311,8 @@ def __init__(self): self._download_url = 'https://static.rust-lang.org' self.rustc_channel = '' self.build = '' + self.host = '' + self.check = False self.build_dir = os.path.join(os.getcwd(), "build") self.clean = False self.config_toml = '' @@ -357,6 +359,16 @@ def download_stage0(self): rustc_channel, self.build) self._download_stage0_helper(filename, "rust-mingw") + # Download the target libaries used for checking the compiler + if self.check and self.host != '' and self.build != self.host and \ + self.rustc().startswith(self.bin_root()): + lib_path = os.path.join(self.bin_root(), "lib", "rustlib", self.host, "lib") + if not os.path.exists(lib_path): + filename = "rust-std-{}-{}.tar.gz".format( + rustc_channel, self.host) + pattern = "rust-std-{}".format(self.host) + self._download_stage0_helper(filename, pattern) + if self.cargo().startswith(self.bin_root()) and \ (not os.path.exists(self.cargo()) or self.program_out_of_date(self.cargo_stamp())): @@ -366,6 +378,8 @@ def download_stage0(self): with open(self.cargo_stamp(), 'w') as cargo_stamp: cargo_stamp.write(self.date) + shutil.rmtree(os.path.join(self.build_dir, "cache"), ignore_errors=True) + def _download_stage0_helper(self, filename, pattern): cache_dst = os.path.join(self.build_dir, "cache") rustc_cache = os.path.join(cache_dst, self.date) @@ -451,7 +465,7 @@ def rustc_stamp(self): >>> rb = RustBuild() >>> rb.build_dir = "build" - >>> rb.rustc_stamp() == os.path.join("build", "stage0", ".rustc-stamp") + >>> rb.rustc_stamp() == os.path.join("build", "base", ".rustc-stamp") True """ return os.path.join(self.bin_root(), '.rustc-stamp') @@ -461,7 +475,7 @@ def cargo_stamp(self): >>> rb = RustBuild() >>> rb.build_dir = "build" - >>> rb.cargo_stamp() == os.path.join("build", "stage0", ".cargo-stamp") + >>> rb.cargo_stamp() == os.path.join("build", "base", ".cargo-stamp") True """ return os.path.join(self.bin_root(), '.cargo-stamp') @@ -478,16 +492,19 @@ def bin_root(self): >>> rb = RustBuild() >>> rb.build_dir = "build" - >>> rb.bin_root() == os.path.join("build", "stage0") + >>> rb.bin_root() == os.path.join("build", "base") True When the 'build' property is given should be a nested directory: >>> rb.build = "devel" - >>> rb.bin_root() == os.path.join("build", "devel", "stage0") + >>> rb.bin_root() == os.path.join("build", "base", "devel") True """ - return os.path.join(self.build_dir, self.build, "stage0") + if self.build == "": + return os.path.join(self.build_dir, "base") + else: + return os.path.join(self.build_dir, "base", self.build) def get_toml(self, key): """Returns the value of the given key in config.toml, otherwise returns None @@ -710,6 +727,7 @@ def bootstrap(help_triggered): parser = argparse.ArgumentParser(description='Build rust') parser.add_argument('--config') parser.add_argument('--build') + parser.add_argument('--host') parser.add_argument('--src') parser.add_argument('--clean', action='store_true') parser.add_argument('-v', '--verbose', action='count', default=0) @@ -773,6 +791,8 @@ def bootstrap(help_triggered): build.update_submodules() # Fetch/build the bootstrap + build.host = args.host or '' + build.check = 'check' in sys.argv build.build = args.build or build.build_triple() build.download_stage0() sys.stdout.flush() diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 84d2940066931..21c9cd872e49d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -326,7 +326,7 @@ impl<'a> Builder<'a> { }}; } match kind { - Kind::Build => describe!(compile::Std, compile::Test, compile::Rustc, + Kind::Build => describe!(check::Test, compile::Std, compile::Test, compile::Rustc, compile::StartupObjects, tool::BuildManifest, tool::Rustbook, tool::ErrorIndex, tool::UnstableBookGen, tool::Tidy, tool::Linkchecker, tool::CargoTest, tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient, @@ -624,6 +624,13 @@ impl<'a> Builder<'a> { } let want_rustdoc = self.doc_tests != DocTests::No; + let sysroot = if compiler.stage == 0 && !(mode == Mode::Libstd || mode == Mode::Libtest) { + // Use the bootstrap compiler's sysroot for stage0 + // unless we are checking libstd and libtest + INTERNER.intern_path(PathBuf::new()) + } else { + self.sysroot(compiler) + }; // Customize the compiler we're running. Specify the compiler to cargo // as our shim and then pass it some various options used to configure @@ -637,7 +644,7 @@ impl<'a> Builder<'a> { .env("RUSTC_STAGE", stage.to_string()) .env("RUSTC_DEBUG_ASSERTIONS", self.config.rust_debug_assertions.to_string()) - .env("RUSTC_SYSROOT", self.sysroot(compiler)) + .env("RUSTC_SYSROOT", sysroot) .env("RUSTC_LIBDIR", self.rustc_libdir(compiler)) .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) @@ -1225,10 +1232,6 @@ mod __test { }, ]); assert_eq!(first(builder.cache.all::()), &[ - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, compile::Test { compiler: Compiler { host: a, stage: 1 }, target: a, @@ -1310,10 +1313,6 @@ mod __test { ]); assert_eq!(first(builder.cache.all::()), &[ - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, compile::Test { compiler: Compiler { host: a, stage: 1 }, target: a, @@ -1326,10 +1325,6 @@ mod __test { compiler: Compiler { host: b, stage: 2 }, target: a, }, - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: b, - }, compile::Test { compiler: Compiler { host: a, stage: 1 }, target: b, @@ -1403,10 +1398,6 @@ mod __test { ]); assert_eq!(first(builder.cache.all::()), &[ - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, compile::Test { compiler: Compiler { host: a, stage: 1 }, target: a, @@ -1419,10 +1410,6 @@ mod __test { compiler: Compiler { host: b, stage: 2 }, target: a, }, - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: b, - }, compile::Test { compiler: Compiler { host: a, stage: 1 }, target: b, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index a516af58b1eab..89efc5c1e5abd 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -175,6 +175,8 @@ impl Step for Test { let compiler = builder.compiler(0, builder.config.build); let target = self.target; + builder.ensure(Std { target }); + let out_dir = builder.stage_out(compiler, Mode::Libtest); builder.clear_if_dirty(&out_dir, &libstd_stamp(builder, compiler, target)); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 231ed9d40d2de..0d011eaa9ab90 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -438,7 +438,9 @@ impl Step for TestLink { #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Rustc { + /// The target which our new compiler will run on pub target: Interned, + /// The compiler we're using to compile rustc pub compiler: Compiler, } @@ -467,7 +469,9 @@ impl Step for Rustc { let compiler = self.compiler; let target = self.target; - builder.ensure(Test { compiler, target }); + if compiler.stage != 0 { + builder.ensure(Test { compiler, target }); + } if builder.force_use_stage1(compiler, target) { builder.ensure(Rustc { @@ -485,13 +489,18 @@ impl Step for Rustc { } // Ensure that build scripts have a std to link against. - builder.ensure(Std { - compiler: builder.compiler(self.compiler.stage, builder.config.build), - target: builder.config.build, - }); + if compiler.stage != 0 { + builder.ensure(Std { + compiler: builder.compiler(self.compiler.stage, builder.config.build), + target: builder.config.build, + }); + } let cargo_out = builder.cargo_out(compiler, Mode::Librustc, target); - builder.clear_if_dirty(&cargo_out, &libstd_stamp(builder, compiler, target)); - builder.clear_if_dirty(&cargo_out, &libtest_stamp(builder, compiler, target)); + + if compiler.stage != 0 { + builder.clear_if_dirty(&cargo_out, &libstd_stamp(builder, compiler, target)); + builder.clear_if_dirty(&cargo_out, &libtest_stamp(builder, compiler, target)); + } let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build"); rustc_cargo(builder, &mut cargo); @@ -843,17 +852,9 @@ impl Step for Sysroot { /// Returns the sysroot for the `compiler` specified that *this build system /// generates*. - /// - /// That is, the sysroot for the stage0 compiler is not what the compiler - /// thinks it is by default, but it's the same as the default for stages - /// 1-3. fn run(self, builder: &Builder) -> Interned { let compiler = self.compiler; - let sysroot = if compiler.stage == 0 { - builder.out.join(&compiler.host).join("stage0-sysroot") - } else { - builder.out.join(&compiler.host).join(format!("stage{}", compiler.stage)) - }; + let sysroot = builder.out.join(&compiler.host).join(format!("stage{}", compiler.stage)); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); INTERNER.intern_path(sysroot) @@ -883,8 +884,9 @@ impl Step for Assemble { /// compiler. fn run(self, builder: &Builder) -> Compiler { let target_compiler = self.target_compiler; + let stage = target_compiler.stage; - if target_compiler.stage == 0 { + if stage == 0 { assert_eq!(builder.config.build, target_compiler.host, "Cannot obtain compiler for non-native build triple at stage 0"); // The stage 0 compiler for the build triple is always pre-built. @@ -921,8 +923,10 @@ impl Step for Assemble { for stage in 0..min(target_compiler.stage, builder.config.keep_stage.unwrap()) { let target_compiler = builder.compiler(stage, target_compiler.host); let target = target_compiler.host; - builder.ensure(StdLink { compiler, target_compiler, target }); - builder.ensure(TestLink { compiler, target_compiler, target }); + if stage != 1 { + builder.ensure(StdLink { compiler, target_compiler, target }); + builder.ensure(TestLink { compiler, target_compiler, target }); + } builder.ensure(RustcLink { compiler, target_compiler, target }); } } else { @@ -947,7 +951,6 @@ impl Step for Assemble { None }; - let stage = target_compiler.stage; let host = target_compiler.host; builder.info(&format!("Assembling stage{} compiler ({})", stage, host)); @@ -963,6 +966,16 @@ impl Step for Assemble { } } + if stage == 1 { + // Copy the dynamic libraries from the bootstrap compiler + // which are needed to run the stage1 compiler + copy_libs_from_bootstrap( + builder, + build_compiler, + &sysroot_libdir, + &["std", "test", "term"]); + } + copy_codegen_backends_to_sysroot(builder, build_compiler, target_compiler); @@ -983,6 +996,37 @@ impl Step for Assemble { } } +fn copy_libs_from_bootstrap( + builder: &Builder, + compiler: Compiler, + out_dir: &Path, + libs: &[&str]) +{ + if builder.config.dry_run { + return; + } + + let base_libdir = builder.config + .initial_rustc.parent().unwrap() + .parent().unwrap() + .join("lib").join("rustlib").join(compiler.host).join("lib"); + t!(fs::create_dir_all(&out_dir)); + let mut files: Vec = Vec::new(); + for f in t!(fs::read_dir(&base_libdir)).map(|f| t!(f)) { + let filename = f.file_name().into_string().unwrap(); + let should_copy = is_dylib(&filename) && libs.iter().any(|lib| { + filename.starts_with(&format!("{}-", lib)) || + filename.starts_with(&format!("lib{}-", lib)) + }); + if !should_copy { + continue; + } + let dest = &out_dir.join(filename); + builder.copy(&f.path(), &dest); + files.push(dest.into()); + } +} + /// Link some files into a rustc sysroot. /// /// For a particular stage this will link the file listed in `stamp` into the @@ -1122,6 +1166,11 @@ pub fn run_cargo(builder: &Builder, cargo: &mut Command, stamp: &Path, is_check: deps.push(path_to_add.into()); } + update_stamp_file(builder, stamp, deps) +} + +pub fn update_stamp_file(builder: &Builder, stamp: &Path, mut deps: Vec) -> Vec +{ // Now we want to update the contents of the stamp file, if necessary. First // we read off the previous contents along with its mtime. If our new // contents (the list of files to copy) is different or if any dep's mtime diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 9840682d1379b..21df3e6d5c221 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -364,7 +364,7 @@ impl Config { config.src = Config::path_from_python("SRC"); config.out = Config::path_from_python("BUILD_DIR"); - let stage0_root = config.out.join(&config.build).join("stage0/bin"); + let stage0_root = config.out.join("base").join(&config.build).join("bin"); config.initial_rustc = stage0_root.join(exe("rustc", &config.build)); config.initial_cargo = stage0_root.join(exe("cargo", &config.build)); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e53fef0678613..266486226e68d 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -51,10 +51,6 @@ //! //! The build output will be something like the following: //! -//! Building stage0 std artifacts -//! Copying stage0 std -//! Building stage0 test artifacts -//! Copying stage0 test //! Building stage0 compiler artifacts //! Copying stage0 rustc //! Assembling stage1 compiler @@ -71,12 +67,12 @@ //! //! Let's disect that a little: //! -//! ## Building stage0 {std,test,compiler} artifacts +//! ## Building stage0 compiler artifacts //! //! These steps use the provided (downloaded, usually) compiler to compile the //! local Rust source into libraries we can use. //! -//! ## Copying stage0 {std,test,rustc} +//! ## Copying stage0 rustc //! //! This copies the build output from Cargo into //! `build/$HOST/stage0-sysroot/lib/rustlib/$ARCH/lib`. FIXME: This step's diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 1d53a305193fa..3fcf1e61b3ec0 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -51,8 +51,10 @@ #![feature(iterator_find_map)] #![cfg_attr(windows, feature(libc))] #![cfg_attr(stage0, feature(macro_lifetime_matcher))] +#![cfg_attr(stage0, feature(inclusive_range_methods))] #![feature(macro_vis_matcher)] #![feature(never_type)] +#![feature(nonzero)] #![feature(exhaustive_patterns)] #![feature(non_exhaustive)] #![feature(proc_macro_internals)] diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 0b0bab96dfdfd..da95f2ceb74b8 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -18,6 +18,7 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![cfg_attr(stage0, feature(inclusive_range_methods))] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(custom_attribute)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 9a6705fe9cac3..5d0ed344cc1a1 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -27,6 +27,7 @@ #![feature(specialization)] #![feature(optin_builtin_traits)] #![feature(macro_vis_matcher)] +#![feature(nonzero)] #![feature(allow_internal_unstable)] #![cfg_attr(unix, feature(libc))] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 3bf9453fb513c..14e223d59fa48 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,6 +14,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! */ +#![cfg_attr(stage0, feature(inclusive_range_methods))] #![feature(slice_patterns)] #![feature(slice_sort_by_cached_key)] #![feature(from_ref)] @@ -26,6 +27,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(decl_macro)] #![feature(fs_read_write)] #![feature(macro_vis_matcher)] +#![feature(nonzero)] #![feature(exhaustive_patterns)] #![feature(range_contains)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 8f4911574398b..560741cfd3cdc 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -29,6 +29,7 @@ #![feature(const_fn)] #![feature(fs_read_write)] #![feature(inclusive_range)] +#![cfg_attr(stage0, feature(inclusive_range_methods))] #![feature(slice_patterns)] #[macro_use]