mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 11:04:03 +00:00
Auto merge of #43628 - oli-obk:orbital_standard_library, r=alexcrichton
Run the miri test suite on the aux builder and travis Reopen of #38350 see https://github.com/rust-lang/rust/pull/43340#issuecomment-316940762 for earlier discussion Rationale for running miri's test suite in rustc's CI is that miri currently contains many features that we want in const eval in the future, and these features would break if the test suite is not run. fixes #44077 r? @nikomatsakis cc @eddyb
This commit is contained in:
commit
caad2560bf
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -39,3 +39,6 @@
|
||||
[submodule "src/tools/rustfmt"]
|
||||
path = src/tools/rustfmt
|
||||
url = https://github.com/rust-lang-nursery/rustfmt.git
|
||||
[submodule "src/tools/miri"]
|
||||
path = src/tools/miri
|
||||
url = https://github.com/solson/miri.git
|
||||
|
@ -291,6 +291,10 @@
|
||||
# When creating source tarballs whether or not to create a source tarball.
|
||||
#dist-src = false
|
||||
|
||||
# Whether to also run the Miri tests suite when running tests.
|
||||
# As a side-effect also generates MIR for all libraries.
|
||||
#test-miri = false
|
||||
|
||||
# =============================================================================
|
||||
# Options for specific targets
|
||||
#
|
||||
|
@ -246,6 +246,12 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// When running miri tests, we need to generate MIR for all libraries
|
||||
if env::var("TEST_MIRI").ok().map_or(false, |val| val == "true") {
|
||||
cmd.arg("-Zalways-encode-mir");
|
||||
cmd.arg("-Zmir-emit-validate=1");
|
||||
}
|
||||
|
||||
// Force all crates compiled by this compiler to (a) be unstable and (b)
|
||||
// allow the `rustc_private` feature to link to other unstable crates
|
||||
// also in the sysroot.
|
||||
|
@ -250,18 +250,18 @@ impl<'a> Builder<'a> {
|
||||
tool::UnstableBookGen, tool::Tidy, tool::Linkchecker, tool::CargoTest,
|
||||
tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient,
|
||||
tool::RustInstaller, tool::Cargo, tool::Rls, tool::Rustdoc, tool::Clippy,
|
||||
native::Llvm, tool::Rustfmt),
|
||||
native::Llvm, tool::Rustfmt, tool::Miri),
|
||||
Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest,
|
||||
check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc,
|
||||
check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs,
|
||||
check::ErrorIndex, check::Distcheck, check::Rustfmt),
|
||||
check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri),
|
||||
Kind::Bench => describe!(check::Crate, check::CrateLibrustc),
|
||||
Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook,
|
||||
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon,
|
||||
doc::Reference, doc::Rustdoc, doc::CargoBook),
|
||||
Kind::Dist => describe!(dist::Docs, dist::Mingw, dist::Rustc, dist::DebuggerScripts,
|
||||
dist::Std, dist::Analysis, dist::Src, dist::PlainSourceTarball, dist::Cargo,
|
||||
dist::Rls, dist::Extended, dist::HashSign),
|
||||
dist::Rls, dist::Extended, dist::HashSign, dist::DontDistWithMiriEnabled),
|
||||
Kind::Install => describe!(install::Docs, install::Std, install::Cargo, install::Rls,
|
||||
install::Analysis, install::Src, install::Rustc),
|
||||
}
|
||||
@ -481,6 +481,7 @@ impl<'a> Builder<'a> {
|
||||
} else {
|
||||
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
||||
})
|
||||
.env("TEST_MIRI", self.config.test_miri.to_string())
|
||||
.env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
|
||||
|
||||
if mode != Mode::Tool {
|
||||
|
@ -23,7 +23,7 @@ use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
use std::io::Read;
|
||||
|
||||
use build_helper::{self, output};
|
||||
use build_helper::{self, output, BuildExpectation};
|
||||
|
||||
use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step};
|
||||
use cache::{INTERNER, Interned};
|
||||
@ -33,6 +33,7 @@ use native;
|
||||
use tool::{self, Tool};
|
||||
use util::{self, dylib_path, dylib_path_var};
|
||||
use {Build, Mode};
|
||||
use toolstate::ToolState;
|
||||
|
||||
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
||||
|
||||
@ -64,17 +65,21 @@ impl fmt::Display for TestKind {
|
||||
}
|
||||
}
|
||||
|
||||
fn try_run(build: &Build, cmd: &mut Command) {
|
||||
fn try_run_expecting(build: &Build, cmd: &mut Command, expect: BuildExpectation) {
|
||||
if !build.fail_fast {
|
||||
if !build.try_run(cmd) {
|
||||
if !build.try_run(cmd, expect) {
|
||||
let failures = build.delayed_failures.get();
|
||||
build.delayed_failures.set(failures + 1);
|
||||
}
|
||||
} else {
|
||||
build.run(cmd);
|
||||
build.run_expecting(cmd, expect);
|
||||
}
|
||||
}
|
||||
|
||||
fn try_run(build: &Build, cmd: &mut Command) {
|
||||
try_run_expecting(build, cmd, BuildExpectation::None)
|
||||
}
|
||||
|
||||
fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
||||
if !build.fail_fast {
|
||||
if !build.try_run_quiet(cmd) {
|
||||
@ -294,6 +299,56 @@ impl Step for Rustfmt {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Miri {
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Miri {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
let test_miri = run.builder.build.config.test_miri;
|
||||
run.path("src/tools/miri").default_condition(test_miri)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(Miri {
|
||||
host: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
/// Runs `cargo test` for miri.
|
||||
fn run(self, builder: &Builder) {
|
||||
let build = builder.build;
|
||||
let host = self.host;
|
||||
let compiler = builder.compiler(1, host);
|
||||
|
||||
let miri = builder.ensure(tool::Miri { compiler, target: self.host });
|
||||
let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
|
||||
cargo.arg("--manifest-path").arg(build.src.join("src/tools/miri/Cargo.toml"));
|
||||
|
||||
// Don't build tests dynamically, just a pain to work with
|
||||
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
||||
// miri tests need to know about the stage sysroot
|
||||
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
|
||||
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
|
||||
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
|
||||
cargo.env("MIRI_PATH", miri);
|
||||
|
||||
builder.add_rustc_lib_path(compiler, &mut cargo);
|
||||
|
||||
try_run_expecting(
|
||||
build,
|
||||
&mut cargo,
|
||||
builder.build.config.toolstate.miri.passes(ToolState::Testing),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString {
|
||||
// Configure PATH to find the right rustc. NB. we have to use PATH
|
||||
// and not RUSTC because the Cargo test suite has tests that will
|
||||
|
@ -27,6 +27,7 @@ use util::exe;
|
||||
use cache::{INTERNER, Interned};
|
||||
use flags::Flags;
|
||||
pub use flags::Subcommand;
|
||||
use toolstate::ToolStates;
|
||||
|
||||
/// Global configuration for the entire build and/or bootstrap.
|
||||
///
|
||||
@ -111,6 +112,7 @@ pub struct Config {
|
||||
pub low_priority: bool,
|
||||
pub channel: String,
|
||||
pub quiet_tests: bool,
|
||||
pub test_miri: bool,
|
||||
// Fallback musl-root for all targets
|
||||
pub musl_root: Option<PathBuf>,
|
||||
pub prefix: Option<PathBuf>,
|
||||
@ -130,6 +132,8 @@ pub struct Config {
|
||||
// These are either the stage0 downloaded binaries or the locally installed ones.
|
||||
pub initial_cargo: PathBuf,
|
||||
pub initial_rustc: PathBuf,
|
||||
|
||||
pub toolstate: ToolStates,
|
||||
}
|
||||
|
||||
/// Per-target configuration stored in the global configuration structure.
|
||||
@ -269,6 +273,7 @@ struct Rust {
|
||||
debug: Option<bool>,
|
||||
dist_src: Option<bool>,
|
||||
quiet_tests: Option<bool>,
|
||||
test_miri: Option<bool>,
|
||||
}
|
||||
|
||||
/// TOML representation of how each build target is configured.
|
||||
@ -304,6 +309,7 @@ impl Config {
|
||||
config.codegen_tests = true;
|
||||
config.ignore_git = false;
|
||||
config.rust_dist_src = true;
|
||||
config.test_miri = false;
|
||||
|
||||
config.on_fail = flags.on_fail;
|
||||
config.stage = flags.stage;
|
||||
@ -330,6 +336,18 @@ impl Config {
|
||||
}
|
||||
}).unwrap_or_else(|| TomlConfig::default());
|
||||
|
||||
let toolstate_toml_path = config.src.join("src/tools/toolstate.toml");
|
||||
let parse_toolstate = || -> Result<_, Box<::std::error::Error>> {
|
||||
let mut f = File::open(toolstate_toml_path)?;
|
||||
let mut contents = String::new();
|
||||
f.read_to_string(&mut contents)?;
|
||||
Ok(toml::from_str(&contents)?)
|
||||
};
|
||||
config.toolstate = parse_toolstate().unwrap_or_else(|err| {
|
||||
println!("failed to parse TOML configuration 'toolstate.toml': {}", err);
|
||||
process::exit(2);
|
||||
});
|
||||
|
||||
let build = toml.build.clone().unwrap_or(Build::default());
|
||||
set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x)));
|
||||
set(&mut config.build, flags.build);
|
||||
@ -444,6 +462,7 @@ impl Config {
|
||||
set(&mut config.channel, rust.channel.clone());
|
||||
set(&mut config.rust_dist_src, rust.dist_src);
|
||||
set(&mut config.quiet_tests, rust.quiet_tests);
|
||||
set(&mut config.test_miri, rust.test_miri);
|
||||
config.rustc_default_linker = rust.default_linker.clone();
|
||||
config.rustc_default_ar = rust.default_ar.clone();
|
||||
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
||||
|
@ -38,6 +38,7 @@ o("debug", "rust.debug", "debug mode; disables optimization unless `--enable-opt
|
||||
o("docs", "build.docs", "build standard library documentation")
|
||||
o("compiler-docs", "build.compiler-docs", "build compiler documentation")
|
||||
o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
|
||||
o("test-miri", "rust.test-miri", "run miri's test suite")
|
||||
o("debuginfo-tests", "rust.debuginfo-tests", "build tests with debugger metadata")
|
||||
o("quiet-tests", "rust.quiet-tests", "enable quieter output when running tests")
|
||||
o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds")
|
||||
|
@ -1111,6 +1111,31 @@ impl Step for Rls {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct DontDistWithMiriEnabled;
|
||||
|
||||
impl Step for DontDistWithMiriEnabled {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
let build_miri = run.builder.build.config.test_miri;
|
||||
run.default_condition(build_miri)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(DontDistWithMiriEnabled);
|
||||
}
|
||||
|
||||
fn run(self, _: &Builder) -> PathBuf {
|
||||
panic!("Do not distribute with miri enabled.\n\
|
||||
The distributed libraries would include all MIR (increasing binary size).
|
||||
The distributed MIR would include validation statements.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Extended {
|
||||
stage: u32,
|
||||
|
@ -143,7 +143,8 @@ use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
use std::slice;
|
||||
|
||||
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime};
|
||||
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime,
|
||||
BuildExpectation};
|
||||
|
||||
use util::{exe, libdir, OutputFolder, CiEnv};
|
||||
|
||||
@ -164,6 +165,7 @@ pub mod util;
|
||||
mod builder;
|
||||
mod cache;
|
||||
mod tool;
|
||||
mod toolstate;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod job;
|
||||
@ -542,24 +544,31 @@ impl Build {
|
||||
.join(libdir(&self.config.build))
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if its build
|
||||
/// status is not the expected one
|
||||
fn run_expecting(&self, cmd: &mut Command, expect: BuildExpectation) {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_silent(cmd, expect)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
fn run(&self, cmd: &mut Command) {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_silent(cmd)
|
||||
self.run_expecting(cmd, BuildExpectation::None)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
fn run_quiet(&self, cmd: &mut Command) {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
run_suppressed(cmd)
|
||||
run_suppressed(cmd, BuildExpectation::None)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
/// Exits if the command failed to execute at all, otherwise returns its
|
||||
/// `status.success()`.
|
||||
fn try_run(&self, cmd: &mut Command) -> bool {
|
||||
/// Runs a command, printing out nice contextual information if its build
|
||||
/// status is not the expected one.
|
||||
/// Exits if the command failed to execute at all, otherwise returns whether
|
||||
/// the expectation was met
|
||||
fn try_run(&self, cmd: &mut Command, expect: BuildExpectation) -> bool {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
try_run_silent(cmd)
|
||||
try_run_silent(cmd, expect)
|
||||
}
|
||||
|
||||
/// Runs a command, printing out nice contextual information if it fails.
|
||||
@ -567,7 +576,7 @@ impl Build {
|
||||
/// `status.success()`.
|
||||
fn try_run_quiet(&self, cmd: &mut Command) -> bool {
|
||||
self.verbose(&format!("running: {:?}", cmd));
|
||||
try_run_suppressed(cmd)
|
||||
try_run_suppressed(cmd, BuildExpectation::None)
|
||||
}
|
||||
|
||||
pub fn is_verbose(&self) -> bool {
|
||||
|
@ -56,6 +56,7 @@ check-aux:
|
||||
src/tools/cargo \
|
||||
src/tools/rls \
|
||||
src/tools/rustfmt \
|
||||
src/tools/miri \
|
||||
src/test/pretty \
|
||||
src/test/run-pass/pretty \
|
||||
src/test/run-fail/pretty \
|
||||
|
@ -21,6 +21,8 @@ use compile::{self, libtest_stamp, libstd_stamp, librustc_stamp};
|
||||
use native;
|
||||
use channel::GitInfo;
|
||||
use cache::Interned;
|
||||
use toolstate::ToolState;
|
||||
use build_helper::BuildExpectation;
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct CleanTools {
|
||||
@ -64,6 +66,7 @@ struct ToolBuild {
|
||||
tool: &'static str,
|
||||
path: &'static str,
|
||||
mode: Mode,
|
||||
expectation: BuildExpectation,
|
||||
}
|
||||
|
||||
impl Step for ToolBuild {
|
||||
@ -83,6 +86,7 @@ impl Step for ToolBuild {
|
||||
let target = self.target;
|
||||
let tool = self.tool;
|
||||
let path = self.path;
|
||||
let expectation = self.expectation;
|
||||
|
||||
match self.mode {
|
||||
Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
|
||||
@ -95,7 +99,7 @@ impl Step for ToolBuild {
|
||||
println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
|
||||
|
||||
let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
|
||||
build.run(&mut cargo);
|
||||
build.run_expecting(&mut cargo, expectation);
|
||||
build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host))
|
||||
}
|
||||
}
|
||||
@ -200,6 +204,7 @@ macro_rules! tool {
|
||||
tool: $tool_name,
|
||||
mode: $mode,
|
||||
path: $path,
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -247,6 +252,7 @@ impl Step for RemoteTestServer {
|
||||
tool: "remote-test-server",
|
||||
mode: Mode::Libstd,
|
||||
path: "src/tools/remote-test-server",
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -359,6 +365,7 @@ impl Step for Cargo {
|
||||
tool: "cargo",
|
||||
mode: Mode::Librustc,
|
||||
path: "src/tools/cargo",
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -398,6 +405,7 @@ impl Step for Clippy {
|
||||
tool: "clippy",
|
||||
mode: Mode::Librustc,
|
||||
path: "src/tools/clippy",
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -441,6 +449,7 @@ impl Step for Rls {
|
||||
tool: "rls",
|
||||
mode: Mode::Librustc,
|
||||
path: "src/tools/rls",
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -475,6 +484,43 @@ impl Step for Rustfmt {
|
||||
tool: "rustfmt",
|
||||
mode: Mode::Librustc,
|
||||
path: "src/tools/rustfmt",
|
||||
expectation: BuildExpectation::None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Miri {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl Step for Miri {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||
let build_miri = run.builder.build.config.test_miri;
|
||||
run.path("src/tools/miri").default_condition(build_miri)
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig) {
|
||||
run.builder.ensure(Miri {
|
||||
compiler: run.builder.compiler(run.builder.top_stage, run.builder.build.build),
|
||||
target: run.target,
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder) -> PathBuf {
|
||||
builder.ensure(ToolBuild {
|
||||
compiler: self.compiler,
|
||||
target: self.target,
|
||||
tool: "miri",
|
||||
mode: Mode::Librustc,
|
||||
path: "src/tools/miri",
|
||||
expectation: builder.build.config.toolstate.miri.passes(ToolState::Compiling),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
48
src/bootstrap/toolstate.rs
Normal file
48
src/bootstrap/toolstate.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use build_helper::BuildExpectation;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq)]
|
||||
/// Whether a tool can be compiled, tested or neither
|
||||
pub enum ToolState {
|
||||
/// The tool compiles successfully, but the test suite fails
|
||||
Compiling = 1,
|
||||
/// The tool compiles successfully and its test suite passes
|
||||
Testing = 2,
|
||||
/// The tool can't even be compiled
|
||||
Broken = 0,
|
||||
}
|
||||
|
||||
impl ToolState {
|
||||
/// If a tool with the current toolstate should be working on
|
||||
/// the given toolstate
|
||||
pub fn passes(self, other: ToolState) -> BuildExpectation {
|
||||
if self as usize >= other as usize {
|
||||
BuildExpectation::Succeeding
|
||||
} else {
|
||||
BuildExpectation::Failing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ToolState {
|
||||
fn default() -> Self {
|
||||
// err on the safe side
|
||||
ToolState::Broken
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Deserialize, Default)]
|
||||
/// Used to express which tools should (not) be compiled or tested.
|
||||
/// This is created from `toolstate.toml`.
|
||||
pub struct ToolStates {
|
||||
pub miri: ToolState,
|
||||
}
|
@ -35,55 +35,97 @@ macro_rules! t {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run(cmd: &mut Command) {
|
||||
println!("running: {:?}", cmd);
|
||||
run_silent(cmd);
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum BuildExpectation {
|
||||
Succeeding,
|
||||
Failing,
|
||||
None,
|
||||
}
|
||||
|
||||
pub fn run_silent(cmd: &mut Command) {
|
||||
if !try_run_silent(cmd) {
|
||||
pub fn run(cmd: &mut Command, expect: BuildExpectation) {
|
||||
println!("running: {:?}", cmd);
|
||||
run_silent(cmd, expect);
|
||||
}
|
||||
|
||||
pub fn run_silent(cmd: &mut Command, expect: BuildExpectation) {
|
||||
if !try_run_silent(cmd, expect) {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_run_silent(cmd: &mut Command) -> bool {
|
||||
pub fn try_run_silent(cmd: &mut Command, expect: BuildExpectation) -> bool {
|
||||
let status = match cmd.status() {
|
||||
Ok(status) => status,
|
||||
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}",
|
||||
cmd, e)),
|
||||
};
|
||||
if !status.success() {
|
||||
println!("\n\ncommand did not execute successfully: {:?}\n\
|
||||
expected success, got: {}\n\n",
|
||||
cmd,
|
||||
status);
|
||||
}
|
||||
status.success()
|
||||
process_status(
|
||||
cmd,
|
||||
status.success(),
|
||||
expect,
|
||||
|| println!("\n\ncommand did not execute successfully: {:?}\n\
|
||||
expected success, got: {}\n\n",
|
||||
cmd,
|
||||
status))
|
||||
}
|
||||
|
||||
pub fn run_suppressed(cmd: &mut Command) {
|
||||
if !try_run_suppressed(cmd) {
|
||||
fn process_status<F: FnOnce()>(
|
||||
cmd: &Command,
|
||||
success: bool,
|
||||
expect: BuildExpectation,
|
||||
f: F,
|
||||
) -> bool {
|
||||
use BuildExpectation::*;
|
||||
match (expect, success) {
|
||||
(None, false) => { f(); false },
|
||||
// Non-tool build succeeds, everything is good
|
||||
(None, true) => true,
|
||||
// Tool expected to work and is working
|
||||
(Succeeding, true) => true,
|
||||
// Tool expected to fail and is failing
|
||||
(Failing, false) => {
|
||||
println!("This failure is expected (see `src/tools/toolstate.toml`)");
|
||||
true
|
||||
},
|
||||
// Tool expected to work, but is failing
|
||||
(Succeeding, false) => {
|
||||
f();
|
||||
println!("You can disable the tool in `src/tools/toolstate.toml`");
|
||||
false
|
||||
},
|
||||
// Tool expected to fail, but is working
|
||||
(Failing, true) => {
|
||||
println!("Expected `{:?}` to fail, but it succeeded.\n\
|
||||
Please adjust `src/tools/toolstate.toml` accordingly", cmd);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_suppressed(cmd: &mut Command, expect: BuildExpectation) {
|
||||
if !try_run_suppressed(cmd, expect) {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_run_suppressed(cmd: &mut Command) -> bool {
|
||||
pub fn try_run_suppressed(cmd: &mut Command, expect: BuildExpectation) -> bool {
|
||||
let output = match cmd.output() {
|
||||
Ok(status) => status,
|
||||
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}",
|
||||
cmd, e)),
|
||||
};
|
||||
if !output.status.success() {
|
||||
println!("\n\ncommand did not execute successfully: {:?}\n\
|
||||
process_status(
|
||||
cmd,
|
||||
output.status.success(),
|
||||
expect,
|
||||
|| println!("\n\ncommand did not execute successfully: {:?}\n\
|
||||
expected success, got: {}\n\n\
|
||||
stdout ----\n{}\n\
|
||||
stderr ----\n{}\n\n",
|
||||
cmd,
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr));
|
||||
}
|
||||
output.status.success()
|
||||
String::from_utf8_lossy(&output.stderr)))
|
||||
}
|
||||
|
||||
pub fn gnu_target(target: &str) -> String {
|
||||
|
@ -20,7 +20,7 @@ Images will output artifacts in an `obj` dir at the root of a repository.
|
||||
|
||||
- Each directory, excluding `scripts` and `disabled`, corresponds to a docker image
|
||||
- `scripts` contains files shared by docker images
|
||||
- `disabled` contains images that are not build travis
|
||||
- `disabled` contains images that are not built on travis
|
||||
|
||||
## Cross toolchains
|
||||
|
||||
|
@ -17,5 +17,5 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
COPY scripts/sccache.sh /scripts/
|
||||
RUN sh /scripts/sccache.sh
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
|
||||
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-test-miri
|
||||
ENV RUST_CHECK_TARGET check-aux
|
||||
|
@ -16,7 +16,7 @@ extern crate gcc;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use build_helper::{run, native_lib_boilerplate};
|
||||
use build_helper::{run, native_lib_boilerplate, BuildExpectation};
|
||||
|
||||
fn main() {
|
||||
// FIXME: This is a hack to support building targets that don't
|
||||
@ -126,7 +126,7 @@ fn main() {
|
||||
cmd.arg("--with-lg-quantum=4");
|
||||
}
|
||||
|
||||
run(&mut cmd);
|
||||
run(&mut cmd, BuildExpectation::None);
|
||||
|
||||
let mut make = Command::new(build_helper::make(&host));
|
||||
make.current_dir(&native.out_dir)
|
||||
@ -143,7 +143,7 @@ fn main() {
|
||||
.arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set"));
|
||||
}
|
||||
|
||||
run(&mut make);
|
||||
run(&mut make, BuildExpectation::None);
|
||||
|
||||
// The pthread_atfork symbols is used by jemalloc on android but the really
|
||||
// old android we're building on doesn't have them defined, so just make
|
||||
|
@ -15,7 +15,7 @@ extern crate gcc;
|
||||
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use build_helper::{run, native_lib_boilerplate};
|
||||
use build_helper::{run, native_lib_boilerplate, BuildExpectation};
|
||||
|
||||
fn main() {
|
||||
let target = env::var("TARGET").expect("TARGET was not set");
|
||||
@ -97,11 +97,14 @@ fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
|
||||
.env("CC", compiler.path())
|
||||
.env("AR", &ar)
|
||||
.env("RANLIB", format!("{} s", ar.display()))
|
||||
.env("CFLAGS", cflags));
|
||||
.env("CFLAGS", cflags),
|
||||
BuildExpectation::None);
|
||||
|
||||
run(Command::new(build_helper::make(host))
|
||||
.current_dir(&native.out_dir)
|
||||
.arg(format!("INCDIR={}", native.src_dir.display()))
|
||||
.arg("-j").arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));
|
||||
.arg("-j").arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")),
|
||||
BuildExpectation::None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
1
src/tools/miri
Submodule
1
src/tools/miri
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 80853e2f24a01db96fe9821e468dd2af75a4d2e5
|
@ -65,6 +65,7 @@ fn filter_dirs(path: &Path) -> bool {
|
||||
"src/tools/clippy",
|
||||
"src/tools/rust-installer",
|
||||
"src/tools/rustfmt",
|
||||
"src/tools/miri",
|
||||
];
|
||||
skip.iter().any(|p| path.ends_with(p))
|
||||
}
|
||||
|
24
src/tools/toolstate.toml
Normal file
24
src/tools/toolstate.toml
Normal file
@ -0,0 +1,24 @@
|
||||
# This file reflects the current status of all tools which are allowed
|
||||
# to fail without failing the build.
|
||||
#
|
||||
# There are three states a tool can be in:
|
||||
# 1. Broken: The tool doesn't build
|
||||
# 2. Building: The tool builds but its tests are failing
|
||||
# 3. Testing: The tool builds and its tests are passing
|
||||
#
|
||||
# In the future there will be further states like "Distributing", which
|
||||
# configures whether the tool is included in the Rust distribution.
|
||||
#
|
||||
# If a tool was working before your PR but is broken now, consider
|
||||
# updating the tool within your PR. How to do that is described in
|
||||
# "CONTRIBUTING.md#External Dependencies". If the effort required is not
|
||||
# warranted (e.g. due to the tool abusing some API that you changed, and
|
||||
# fixing the tool would mean a significant refactoring), you can disable
|
||||
# the tool here, by changing its state to `Broken`. Remember to ping
|
||||
# the tool authors if you do not fix their tool, so they can proactively
|
||||
# fix it, instead of being surprised by the breakage.
|
||||
#
|
||||
# Each tool has a list of people to ping
|
||||
|
||||
# ping @oli-obk @RalfJung @eddyb
|
||||
miri = "Testing"
|
Loading…
Reference in New Issue
Block a user