diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 117ff0e721474..9c58f5b179fd8 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -449,6 +449,7 @@ impl<'a> Builder<'a> { dist::Rls, dist::Rustfmt, dist::Clippy, + dist::Miri, dist::LlvmTools, dist::Lldb, dist::Extended, @@ -461,6 +462,7 @@ impl<'a> Builder<'a> { install::Rls, install::Rustfmt, install::Clippy, + install::Miri, install::Analysis, install::Src, install::Rustc diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 38869bf441a82..edac90b0495f1 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1275,6 +1275,90 @@ impl Step for Clippy { } } +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct Miri { + pub stage: u32, + pub target: Interned, +} + +impl Step for Miri { + type Output = Option; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("miri") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(Miri { + stage: run.builder.top_stage, + target: run.target, + }); + } + + fn run(self, builder: &Builder) -> Option { + let stage = self.stage; + let target = self.target; + assert!(builder.config.extended); + + builder.info(&format!("Dist miri stage{} ({})", stage, target)); + let src = builder.src.join("src/tools/miri"); + let release_num = builder.release_num("miri"); + let name = pkgname(builder, "miri"); + let version = builder.miri_info.version(builder, &release_num); + + let tmp = tmpdir(builder); + let image = tmp.join("miri-image"); + drop(fs::remove_dir_all(&image)); + builder.create_dir(&image); + + // Prepare the image directory + // We expect miri to build, because we've exited this step above if tool + // state for miri isn't testing. + let miri = builder.ensure(tool::Miri { + compiler: builder.compiler(stage, builder.config.build), + target, extra_features: Vec::new() + }).or_else(|| { missing_tool("miri", builder.build.config.missing_tools); None })?; + let cargomiri = builder.ensure(tool::CargoMiri { + compiler: builder.compiler(stage, builder.config.build), + target, extra_features: Vec::new() + }).or_else(|| { missing_tool("cargo miri", builder.build.config.missing_tools); None })?; + + builder.install(&miri, &image.join("bin"), 0o755); + builder.install(&cargomiri, &image.join("bin"), 0o755); + let doc = image.join("share/doc/miri"); + builder.install(&src.join("README.md"), &doc, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); + + // Prepare the overlay + let overlay = tmp.join("miri-overlay"); + drop(fs::remove_dir_all(&overlay)); + t!(fs::create_dir_all(&overlay)); + builder.install(&src.join("README.md"), &overlay, 0o644); + builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644); + builder.install(&src.join("LICENSE-MIT"), &doc, 0o644); + builder.create(&overlay.join("version"), &version); + + // Generate the installer tarball + let mut cmd = rust_installer(builder); + cmd.arg("generate") + .arg("--product-name=Rust") + .arg("--rel-manifest-dir=rustlib") + .arg("--success-message=miri-ready-to-serve.") + .arg("--image-dir").arg(&image) + .arg("--work-dir").arg(&tmpdir(builder)) + .arg("--output-dir").arg(&distdir(builder)) + .arg("--non-installed-overlay").arg(&overlay) + .arg(format!("--package-name={}-{}", name, target)) + .arg("--legacy-manifest-dirs=rustlib,cargo") + .arg("--component-name=miri-preview"); + + builder.run(&mut cmd); + Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target))) + } +} + #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustfmt { pub stage: u32, diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 669aae68c635b..fffb0ba488f6f 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -32,6 +32,9 @@ pub fn install_rls(builder: &Builder, stage: u32, host: Interned) { pub fn install_clippy(builder: &Builder, stage: u32, host: Interned) { install_sh(builder, "clippy", "clippy", stage, Some(host)); } +pub fn install_miri(builder: &Builder, stage: u32, host: Interned) { + install_sh(builder, "miri", "miri", stage, Some(host)); +} pub fn install_rustfmt(builder: &Builder, stage: u32, host: Interned) { install_sh(builder, "rustfmt", "rustfmt", stage, Some(host)); @@ -217,6 +220,14 @@ install!((self, builder, _config), builder.info(&format!("skipping Install clippy stage{} ({})", self.stage, self.target)); } }; + Miri, "miri", Self::should_build(_config), only_hosts: true, { + if builder.ensure(dist::Clippy { stage: self.stage, target: self.target }).is_some() || + Self::should_install(builder) { + install_miri(builder, self.stage, self.target); + } else { + builder.info(&format!("skipping Install miri stage{} ({})", self.stage, self.target)); + } + }; Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, { if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() || Self::should_install(builder) { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e460ef5a44e92..2a91aab7c4ac2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -253,6 +253,7 @@ pub struct Build { cargo_info: channel::GitInfo, rls_info: channel::GitInfo, clippy_info: channel::GitInfo, + miri_info: channel::GitInfo, rustfmt_info: channel::GitInfo, local_rebuild: bool, fail_fast: bool, @@ -374,6 +375,7 @@ impl Build { let cargo_info = channel::GitInfo::new(&config, &src.join("src/tools/cargo")); let rls_info = channel::GitInfo::new(&config, &src.join("src/tools/rls")); let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy")); + let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri")); let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt")); let mut build = Build { @@ -396,6 +398,7 @@ impl Build { cargo_info, rls_info, clippy_info, + miri_info, rustfmt_info, cc: HashMap::new(), cxx: HashMap::new(), diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d31ea0f845873..af90693014575 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -592,6 +592,14 @@ tool_extended!((self, builder), }); }; Miri, miri, "src/tools/miri", "miri", {}; + CargoMiri, clippy, "src/tools/miri", "cargo-miri", { + // Miri depends on procedural macros (serde), which requires a full host + // compiler to be available, so we need to depend on that. + builder.ensure(compile::Rustc { + compiler: self.compiler, + target: builder.config.build, + }); + }; Rls, rls, "src/tools/rls", "rls", { let clippy = builder.ensure(Clippy { compiler: self.compiler,