diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 20c89f99b2b0c..dcc4134b2f306 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -310,7 +310,7 @@ impl<'a> Builder<'a> { tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient, tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy, native::Llvm, tool::Rustfmt, tool::Miri, native::Lld), - Kind::Check => describe!(check::Std, check::Test, check::Rustc), + Kind::Check => describe!(check::Std, check::Test, check::Rustc, check::CodegenBackend), Kind::Test => describe!(test::Tidy, test::Bootstrap, test::Ui, test::RunPass, test::CompileFail, test::ParseFail, test::RunFail, test::RunPassValgrind, test::MirOpt, test::Codegen, test::CodegenUnits, test::Incremental, test::Debuginfo, @@ -834,7 +834,7 @@ impl<'a> Builder<'a> { cargo } - /// Ensure that a given step is built, returning it's output. This will + /// Ensure that a given step is built, returning its output. This will /// cache the step, so it is safe (and good!) to call this as often as /// needed to ensure that all dependencies are built. pub fn ensure(&'a self, step: S) -> S::Output { diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index adebd424d7eb6..b155cb826b644 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -10,10 +10,12 @@ //! Implementation of compiling the compiler and standard library, in "check" mode. -use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, add_to_sysroot}; +use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; +use compile::compiler_file; use builder::{RunConfig, Builder, ShouldRun, Step}; use {Compiler, Mode}; -use cache::Interned; +use native; +use cache::{INTERNER, Interned}; use std::path::PathBuf; #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -104,6 +106,97 @@ impl Step for Rustc { } } +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct CodegenBackend { + pub target: Interned, + pub backend: Interned, +} + +impl Step for CodegenBackend { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.all_krates("rustc_trans") + } + + fn make_run(run: RunConfig) { + let backend = run.builder.config.rust_codegen_backends.get(0); + let backend = backend.cloned().unwrap_or_else(|| { + INTERNER.intern_str("llvm") + }); + run.builder.ensure(CodegenBackend { + target: run.target, + backend, + }); + } + + fn run(self, builder: &Builder) { + let build = builder.build; + let compiler = builder.compiler(0, build.build); + let target = self.target; + + let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check"); + let mut features = build.rustc_features().to_string(); + cargo.arg("--manifest-path").arg(build.src.join("src/librustc_trans/Cargo.toml")); + rustc_cargo_env(build, &mut cargo); + + match &*self.backend { + "llvm" | "emscripten" => { + // Build LLVM for our target. This will implicitly build the + // host LLVM if necessary. + let llvm_config = builder.ensure(native::Llvm { + target, + emscripten: self.backend == "emscripten", + }); + + if self.backend == "emscripten" { + features.push_str(" emscripten"); + } + + // Pass down configuration from the LLVM build into the build of + // librustc_llvm and librustc_trans. + if build.is_rust_llvm(target) { + cargo.env("LLVM_RUSTLLVM", "1"); + } + cargo.env("LLVM_CONFIG", &llvm_config); + if self.backend != "emscripten" { + let target_config = build.config.target_config.get(&target); + if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { + cargo.env("CFG_LLVM_ROOT", s); + } + } + // Building with a static libstdc++ is only supported on linux right now, + // not for MSVC or macOS + if build.config.llvm_static_stdcpp && + !target.contains("freebsd") && + !target.contains("windows") && + !target.contains("apple") { + let file = compiler_file(build, + build.cxx(target).unwrap(), + target, + "libstdc++.a"); + cargo.env("LLVM_STATIC_STDCPP", file); + } + if build.config.llvm_link_shared { + cargo.env("LLVM_LINK_SHARED", "1"); + } + } + _ => panic!("unknown backend: {}", self.backend), + } + + let tmp_stamp = build.cargo_out(compiler, Mode::Librustc, target) + .join(".tmp.stamp"); + + let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); + run_cargo(build, + cargo.arg("--features").arg(features), + &tmp_stamp, + true); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Test { pub target: Interned, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 07bce77af8d24..12fd57d9531f2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -519,7 +519,7 @@ pub fn rustc_cargo(builder: &Builder, cargo: &mut Command) { rustc_cargo_env(builder, cargo); } -fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) { +pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) { // Set some configuration variables picked up by build scripts and // the compiler alike cargo.env("CFG_RELEASE", builder.rust_release()) @@ -614,7 +614,7 @@ impl Step for CodegenBackend { run.builder.ensure(CodegenBackend { compiler: run.builder.compiler(run.builder.top_stage, run.host), target: run.target, - backend + backend, }); } @@ -803,7 +803,7 @@ fn codegen_backend_stamp(builder: &Builder, .join(format!(".librustc_trans-{}.stamp", backend)) } -fn compiler_file(builder: &Builder, +pub fn compiler_file(builder: &Builder, compiler: &Path, target: Interned, file: &str) -> PathBuf {