Skip to content

Add rustc_trans to x.py check #49890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -834,7 +840,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<S: Step>(&'a self, step: S) -> S::Output {
Expand Down
60 changes: 58 additions & 2 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

//! 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 builder::{RunConfig, Builder, ShouldRun, Step};
use {Compiler, Mode};
use cache::Interned;
use cache::{INTERNER, Interned};
use std::path::PathBuf;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -104,6 +104,52 @@ impl Step for Rustc {
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CodegenBackend {
pub target: Interned<String>,
pub backend: Interned<String>,
}

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 compiler = builder.compiler(0, builder.config.build);
let target = self.target;
let backend = self.backend;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to clear_if_dirty anything here (or add this to the clear_if_dirty sections of any of the other steps)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? If it in general works I wouldn't worry too much, we can patch it in later.

let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
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 = builder.fold_output(|| format!("stage{}-rustc_trans", compiler.stage));
run_cargo(builder,
cargo.arg("--features").arg(features),
&codegen_backend_stamp(builder, compiler, target, backend),
true);
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Test {
pub target: Interned<String>,
Expand Down Expand Up @@ -161,3 +207,13 @@ pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned<Str
pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> 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(builder: &Builder,
compiler: Compiler,
target: Interned<String>,
backend: Interned<String>) -> PathBuf {
builder.cargo_out(compiler, Mode::Librustc, target)
.join(format!(".librustc_trans-{}-check.stamp", backend))
}
117 changes: 66 additions & 51 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -614,21 +614,22 @@ impl Step for CodegenBackend {
run.builder.ensure(CodegenBackend {
compiler: run.builder.compiler(run.builder.top_stage, run.host),
target: run.target,
backend
backend,
});
}

fn run(self, builder: &Builder) {
let compiler = self.compiler;
let target = self.target;
let backend = self.backend;

builder.ensure(Rustc { compiler, target });

if builder.force_use_stage1(compiler, target) {
builder.ensure(CodegenBackend {
compiler: builder.compiler(1, builder.config.build),
target,
backend: self.backend,
backend,
});
return;
}
Expand All @@ -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");
Expand All @@ -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(builder, 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<String>,
backend: Interned<String>) -> 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.
///
Expand Down Expand Up @@ -795,6 +808,8 @@ pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<St
builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc.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(builder: &Builder,
compiler: Compiler,
target: Interned<String>,
Expand All @@ -803,7 +818,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<String>,
file: &str) -> PathBuf {
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ 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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this print out rerun-if-env-changed to automatically detect when this is altered?

println!("cargo:rerun-if-env-changed=RUST_CHECK");
return;
}

let target = env::var("TARGET").expect("TARGET was not set");
let llvm_config = env::var_os("LLVM_CONFIG")
.map(PathBuf::from)
Expand Down