From b53468f500e079cef07ed53245c3aa99daf32fcc Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 11 Apr 2018 23:36:42 +0100 Subject: [PATCH 1/6] Add rustc_trans to x.py check --- src/bootstrap/builder.rs | 4 +- src/bootstrap/check.rs | 97 +++++++++++++++++++++++++++++++++++++++- src/bootstrap/compile.rs | 6 +-- 3 files changed, 100 insertions(+), 7 deletions(-) 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 { From 49b677346fe0e2ac2554555ce16499f0315ba934 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 12 Apr 2018 00:34:49 +0100 Subject: [PATCH 2/6] Correct the timestamp for CodegenBackend check --- src/bootstrap/check.rs | 15 +++++++++++---- src/bootstrap/compile.rs | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index b155cb826b644..487f8d700338b 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -186,13 +186,10 @@ impl Step for CodegenBackend { _ => 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, + &codegen_backend_stamp(build, compiler, target, self.backend), true); } } @@ -254,3 +251,13 @@ pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned) -> PathBuf { builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp") } + +/// Cargo's output path for librustc_trans in a given stage, compiled by a particular +/// compiler for the specified target and backend. +fn codegen_backend_stamp(build: &Build, + compiler: Compiler, + target: Interned, + backend: Interned) -> PathBuf { + build.cargo_out(compiler, Mode::Librustc, target) + .join(format!(".librustc_trans-{}-check.stamp", backend)) +} diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 12fd57d9531f2..f180f971fdc77 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -795,6 +795,8 @@ pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned, From f31c01c713de320b4f5de7670c6fedfad48401e4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 12 Apr 2018 15:51:55 +0100 Subject: [PATCH 3/6] Abstract LLVM building from bootstrap This deduplicates the LLVM building functionality from compile.rs and check.rs. --- src/bootstrap/check.rs | 50 ++---------------- src/bootstrap/compile.rs | 109 ++++++++++++++++++++++----------------- 2 files changed, 65 insertions(+), 94 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 487f8d700338b..d7b8fa36b7f68 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -11,10 +11,9 @@ //! Implementation of compiling the compiler and standard library, in "check" mode. use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; -use compile::compiler_file; +use compile::build_codegen_backend; use builder::{RunConfig, Builder, ShouldRun, Step}; use {Compiler, Mode}; -use native; use cache::{INTERNER, Interned}; use std::path::PathBuf; @@ -136,60 +135,19 @@ impl Step for CodegenBackend { let build = builder.build; let compiler = builder.compiler(0, build.build); let target = self.target; + let backend = self.backend; 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), - } + features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend); let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); run_cargo(build, cargo.arg("--features").arg(features), - &codegen_backend_stamp(build, compiler, target, self.backend), + &codegen_backend_stamp(build, compiler, target, backend), true); } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index f180f971fdc77..9fd252e114e88 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -621,6 +621,7 @@ impl Step for CodegenBackend { fn run(self, builder: &Builder) { let compiler = self.compiler; let target = self.target; + let backend = self.backend; builder.ensure(Rustc { compiler, target }); @@ -628,7 +629,7 @@ impl Step for CodegenBackend { builder.ensure(CodegenBackend { compiler: builder.compiler(1, builder.config.build), target, - backend: self.backend, + backend, }); return; } @@ -639,52 +640,7 @@ impl Step for CodegenBackend { .arg(builder.src.join("src/librustc_trans/Cargo.toml")); rustc_cargo_env(builder, &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"); - } - - builder.info(&format!("Building stage{} codegen artifacts ({} -> {}, {})", - compiler.stage, &compiler.host, target, self.backend)); - - // Pass down configuration from the LLVM build into the build of - // librustc_llvm and librustc_trans. - if builder.is_rust_llvm(target) { - cargo.env("LLVM_RUSTLLVM", "1"); - } - cargo.env("LLVM_CONFIG", &llvm_config); - if self.backend != "emscripten" { - let target_config = builder.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 builder.config.llvm_static_stdcpp && - !target.contains("freebsd") && - !target.contains("windows") && - !target.contains("apple") { - let file = compiler_file(builder, - builder.cxx(target).unwrap(), - target, - "libstdc++.a"); - cargo.env("LLVM_STATIC_STDCPP", file); - } - if builder.config.llvm_link_shared { - cargo.env("LLVM_LINK_SHARED", "1"); - } - } - _ => panic!("unknown backend: {}", self.backend), - } + features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend); let tmp_stamp = builder.cargo_out(compiler, Mode::Librustc, target) .join(".tmp.stamp"); @@ -711,12 +667,69 @@ impl Step for CodegenBackend { codegen_backend.display(), f.display()); } - let stamp = codegen_backend_stamp(builder, compiler, target, self.backend); + let stamp = codegen_backend_stamp(build, compiler, target, backend); let codegen_backend = codegen_backend.to_str().unwrap(); t!(t!(File::create(&stamp)).write_all(codegen_backend.as_bytes())); } } +pub fn build_codegen_backend(builder: &Builder, + cargo: &mut Command, + compiler: &Compiler, + target: Interned, + backend: Interned) -> String { + let mut features = String::new(); + + match &*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: backend == "emscripten", + }); + + if backend == "emscripten" { + features.push_str(" emscripten"); + } + + builder.info(&format!("Building stage{} codegen artifacts ({} -> {}, {})", + compiler.stage, &compiler.host, target, backend)); + + // Pass down configuration from the LLVM build into the build of + // librustc_llvm and librustc_trans. + if builder.is_rust_llvm(target) { + cargo.env("LLVM_RUSTLLVM", "1"); + } + cargo.env("LLVM_CONFIG", &llvm_config); + if backend != "emscripten" { + let target_config = builder.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 builder.config.llvm_static_stdcpp && + !target.contains("freebsd") && + !target.contains("windows") && + !target.contains("apple") { + let file = compiler_file(builder, + builder.cxx(target).unwrap(), + target, + "libstdc++.a"); + cargo.env("LLVM_STATIC_STDCPP", file); + } + if builder.config.llvm_link_shared { + cargo.env("LLVM_LINK_SHARED", "1"); + } + } + _ => panic!("unknown backend: {}", backend), + } + + features +} + /// Creates the `codegen-backends` folder for a compiler that's about to be /// assembled as a complete compiler. /// From 1db9fabdf7ba45fcb5ee184254cabd696faf6414 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 18 Apr 2018 00:50:41 +0100 Subject: [PATCH 4/6] Do not rebuild LLVM for x.py check --- src/bootstrap/builder.rs | 6 ++++++ src/bootstrap/check.rs | 5 ++--- src/librustc_llvm/build.rs | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index dcc4134b2f306..872271c453ecc 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -552,6 +552,12 @@ impl<'a> Builder<'a> { .arg("--target") .arg(target); + // Set a flag for `check` so that certain build scripts can do less work + // (e.g. not building/requiring LLVM). + if cmd == "check" { + cargo.env("RUST_CHECK", "1"); + } + // If we were invoked from `make` then that's already got a jobserver // set up for us so no need to tell Cargo about jobs all over again. if env::var_os("MAKEFLAGS").is_none() && env::var_os("MFLAGS").is_none() { diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index d7b8fa36b7f68..61e02b25e5834 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -11,7 +11,6 @@ //! Implementation of compiling the compiler and standard library, in "check" mode. use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; -use compile::build_codegen_backend; use builder::{RunConfig, Builder, ShouldRun, Step}; use {Compiler, Mode}; use cache::{INTERNER, Interned}; @@ -138,11 +137,11 @@ impl Step for CodegenBackend { let backend = self.backend; let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check"); - let mut features = build.rustc_features().to_string(); + let 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); - features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend); + // We won't build LLVM if it's not available, as it shouldn't affect `check`. let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); run_cargo(build, diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 54e3f544acb68..d09a3e8b9dad2 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -28,6 +28,11 @@ fn detect_llvm_link() -> (&'static str, &'static str) { } fn main() { + if env::var_os("RUST_CHECK").is_some() { + // If we're just running `check`, there's no need for LLVM to be built. + return; + } + let target = env::var("TARGET").expect("TARGET was not set"); let llvm_config = env::var_os("LLVM_CONFIG") .map(PathBuf::from) From 84f52a716260a00c8dc6c99506b661b48397c03d Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 18 Apr 2018 10:56:04 +0100 Subject: [PATCH 5/6] Replace Build with Builder --- src/bootstrap/check.rs | 19 +++++++++---------- src/bootstrap/compile.rs | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 61e02b25e5834..e7c6ec888dfb1 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -131,22 +131,21 @@ impl Step for CodegenBackend { } fn run(self, builder: &Builder) { - let build = builder.build; - let compiler = builder.compiler(0, build.build); + let compiler = builder.compiler(0, builder.config.build); let target = self.target; let backend = self.backend; let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check"); - let 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); + let features = builder.rustc_features().to_string(); + cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_trans/Cargo.toml")); + rustc_cargo_env(builder, &mut cargo); // We won't build LLVM if it's not available, as it shouldn't affect `check`. - let _folder = build.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); - run_cargo(build, + let _folder = builder.fold_output(|| format!("stage{}-rustc_trans", compiler.stage)); + run_cargo(builder, cargo.arg("--features").arg(features), - &codegen_backend_stamp(build, compiler, target, backend), + &codegen_backend_stamp(builder, compiler, target, backend), true); } } @@ -211,10 +210,10 @@ pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned, backend: Interned) -> PathBuf { - build.cargo_out(compiler, Mode::Librustc, target) + builder.cargo_out(compiler, Mode::Librustc, target) .join(format!(".librustc_trans-{}-check.stamp", backend)) } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9fd252e114e88..1248c2b50be5e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -667,7 +667,7 @@ impl Step for CodegenBackend { codegen_backend.display(), f.display()); } - let stamp = codegen_backend_stamp(build, compiler, target, backend); + let stamp = codegen_backend_stamp(builder, compiler, target, backend); let codegen_backend = codegen_backend.to_str().unwrap(); t!(t!(File::create(&stamp)).write_all(codegen_backend.as_bytes())); } From 86acb09273275a0a045f48bd43cb60eb0a512ff1 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 19 Apr 2018 00:09:41 +0100 Subject: [PATCH 6/6] Add rerun-if-env-changed=RUST_CHECK to librustc_llvm --- src/librustc_llvm/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index d09a3e8b9dad2..1619637b827df 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -30,6 +30,7 @@ fn detect_llvm_link() -> (&'static str, &'static str) { fn main() { if env::var_os("RUST_CHECK").is_some() { // If we're just running `check`, there's no need for LLVM to be built. + println!("cargo:rerun-if-env-changed=RUST_CHECK"); return; }