Revert "Add a file to trivially disable tool building or testing"

This reverts commit ab018c76e1.

This also adds the `ToolBuild::is_ext_tool` field to replace the previous
`ToolBuild::expectation` field, to indicate whether a build-failure of
certain tool is essential.
This commit is contained in:
kennytm 2017-12-07 05:06:48 +08:00
parent 519f92f2aa
commit 2566fa25c7
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C
10 changed files with 56 additions and 232 deletions

View file

@ -23,7 +23,7 @@ use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::Read;
use build_helper::{self, output, BuildExpectation};
use build_helper::{self, output};
use builder::{Kind, RunConfig, ShouldRun, Builder, Compiler, Step};
use cache::{INTERNER, Interned};
@ -65,23 +65,19 @@ impl fmt::Display for TestKind {
}
}
fn try_run_expecting(build: &Build, cmd: &mut Command, expect: BuildExpectation) -> bool {
fn try_run(build: &Build, cmd: &mut Command) -> bool {
if !build.fail_fast {
if !build.try_run(cmd, expect) {
if !build.try_run(cmd) {
let mut failures = build.delayed_failures.borrow_mut();
failures.push(format!("{:?}", cmd));
return false;
}
} else {
build.run_expecting(cmd, expect);
build.run(cmd);
}
true
}
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) {
@ -259,11 +255,7 @@ impl Step for Rls {
builder.add_rustc_lib_path(compiler, &mut cargo);
if try_run_expecting(
build,
&mut cargo,
builder.build.config.toolstate.rls.passes(ToolState::Testing),
) {
if try_run(build, &mut cargo) {
build.save_toolstate("rls", ToolState::Testing);
}
}
@ -309,11 +301,7 @@ impl Step for Rustfmt {
builder.add_rustc_lib_path(compiler, &mut cargo);
if try_run_expecting(
build,
&mut cargo,
builder.build.config.toolstate.rustfmt.passes(ToolState::Testing),
) {
if try_run(build, &mut cargo) {
build.save_toolstate("rustfmt", ToolState::Testing);
}
}
@ -363,11 +351,7 @@ impl Step for Miri {
builder.add_rustc_lib_path(compiler, &mut cargo);
if try_run_expecting(
build,
&mut cargo,
builder.build.config.toolstate.miri.passes(ToolState::Testing),
) {
if try_run(build, &mut cargo) {
build.save_toolstate("miri", ToolState::Testing);
}
} else {
@ -422,11 +406,7 @@ impl Step for Clippy {
builder.add_rustc_lib_path(compiler, &mut cargo);
if try_run_expecting(
build,
&mut cargo,
builder.build.config.toolstate.clippy.passes(ToolState::Testing),
) {
if try_run(build, &mut cargo) {
build.save_toolstate("clippy-driver", ToolState::Testing);
}
} else {

View file

@ -27,7 +27,6 @@ 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.
///
@ -134,8 +133,6 @@ 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.
@ -348,18 +345,6 @@ 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);

View file

@ -1077,11 +1077,6 @@ impl Step for Rls {
let target = self.target;
assert!(build.config.extended);
if !builder.config.toolstate.rls.testing() {
println!("skipping Dist RLS stage{} ({})", stage, target);
return None
}
println!("Dist RLS stage{} ({})", stage, target);
let src = build.src.join("src/tools/rls");
let release_num = build.release_num("rls");
@ -1164,11 +1159,6 @@ impl Step for Rustfmt {
let target = self.target;
assert!(build.config.extended);
if !builder.config.toolstate.rustfmt.testing() {
println!("skipping Dist Rustfmt stage{} ({})", stage, target);
return None
}
println!("Dist Rustfmt stage{} ({})", stage, target);
let src = build.src.join("src/tools/rustfmt");
let release_num = build.release_num("rustfmt");

View file

@ -143,8 +143,7 @@ use std::path::{PathBuf, Path};
use std::process::{self, Command};
use std::slice;
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime,
BuildExpectation};
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime};
use util::{exe, libdir, OutputFolder, CiEnv};
@ -569,31 +568,24 @@ 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.run_expecting(cmd, BuildExpectation::None)
self.verbose(&format!("running: {:?}", cmd));
run_silent(cmd)
}
/// 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, BuildExpectation::None)
run_suppressed(cmd)
}
/// 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 {
/// 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 {
self.verbose(&format!("running: {:?}", cmd));
try_run_silent(cmd, expect)
try_run_silent(cmd)
}
/// Runs a command, printing out nice contextual information if it fails.
@ -601,7 +593,7 @@ impl Build {
/// `status.success()`.
fn try_run_quiet(&self, cmd: &mut Command) -> bool {
self.verbose(&format!("running: {:?}", cmd));
try_run_suppressed(cmd, BuildExpectation::None)
try_run_suppressed(cmd)
}
pub fn is_verbose(&self) -> bool {

View file

@ -22,7 +22,6 @@ 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 {
@ -82,7 +81,7 @@ struct ToolBuild {
tool: &'static str,
path: &'static str,
mode: Mode,
expectation: BuildExpectation,
is_ext_tool: bool,
}
impl Step for ToolBuild {
@ -102,7 +101,7 @@ impl Step for ToolBuild {
let target = self.target;
let tool = self.tool;
let path = self.path;
let expectation = self.expectation;
let is_ext_tool = self.is_ext_tool;
match self.mode {
Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
@ -115,34 +114,25 @@ impl Step for ToolBuild {
println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
let is_expected = build.try_run(&mut cargo, expectation);
// If the expectation is "Failing", `try_run` returning true actually
// means a build-failure is successfully observed, i.e. the tool is
// broken. Thus the XOR here.
// Sorry for the complicated logic, but we can remove this expectation
// logic after #45861 is fully fixed.
build.save_toolstate(tool, if is_expected ^ (expectation == BuildExpectation::Failing) {
let is_expected = build.try_run(&mut cargo);
build.save_toolstate(tool, if is_expected {
ToolState::Compiling
} else {
ToolState::Broken
});
if !is_expected {
if expectation == BuildExpectation::None {
if !is_ext_tool {
exit(1);
} else {
return None;
}
}
if expectation == BuildExpectation::Succeeding || expectation == BuildExpectation::None {
} else {
let cargo_out = build.cargo_out(compiler, Mode::Tool, target)
.join(exe(tool, &compiler.host));
let bin = build.tools_dir(compiler).join(exe(tool, &compiler.host));
copy(&cargo_out, &bin);
Some(bin)
} else {
None
}
}
}
@ -251,8 +241,8 @@ macro_rules! tool {
tool: $tool_name,
mode: $mode,
path: $path,
expectation: BuildExpectation::None,
}).expect("expected to build -- BuildExpectation::None")
is_ext_tool: false,
}).expect("expected to build -- essential tool")
}
}
)+
@ -299,8 +289,8 @@ impl Step for RemoteTestServer {
tool: "remote-test-server",
mode: Mode::Libstd,
path: "src/tools/remote-test-server",
expectation: BuildExpectation::None,
}).expect("expected to build -- BuildExpectation::None")
is_ext_tool: false,
}).expect("expected to build -- essential tool")
}
}
@ -417,8 +407,8 @@ impl Step for Cargo {
tool: "cargo",
mode: Mode::Librustc,
path: "src/tools/cargo",
expectation: BuildExpectation::None,
}).expect("BuildExpectation::None - expected to build")
is_ext_tool: false,
}).expect("expected to build -- essential tool")
}
}
@ -455,14 +445,13 @@ macro_rules! tool_extended {
fn run($sel, $builder: &Builder) -> Option<PathBuf> {
$extra_deps
let toolstate = $builder.build.config.toolstate.$toolstate;
$builder.ensure(ToolBuild {
compiler: $sel.compiler,
target: $sel.target,
tool: $tool_name,
mode: Mode::Librustc,
path: $path,
expectation: toolstate.passes(ToolState::Compiling),
is_ext_tool: true,
})
}
}

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use build_helper::BuildExpectation;
#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
/// Whether a tool can be compiled, tested or neither
pub enum ToolState {
@ -21,38 +19,9 @@ pub enum ToolState {
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
}
}
pub fn testing(&self) -> bool {
match *self {
ToolState::Testing => true,
_ => false,
}
}
}
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,
pub clippy: ToolState,
pub rls: ToolState,
pub rustfmt: ToolState,
}

View file

@ -35,97 +35,55 @@ macro_rules! t {
})
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum BuildExpectation {
Succeeding,
Failing,
None,
}
pub fn run(cmd: &mut Command, expect: BuildExpectation) {
pub fn run(cmd: &mut Command) {
println!("running: {:?}", cmd);
run_silent(cmd, expect);
run_silent(cmd);
}
pub fn run_silent(cmd: &mut Command, expect: BuildExpectation) {
if !try_run_silent(cmd, expect) {
pub fn run_silent(cmd: &mut Command) {
if !try_run_silent(cmd) {
std::process::exit(1);
}
}
pub fn try_run_silent(cmd: &mut Command, expect: BuildExpectation) -> bool {
pub fn try_run_silent(cmd: &mut Command) -> bool {
let status = match cmd.status() {
Ok(status) => status,
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}",
cmd, e)),
};
process_status(
cmd,
status.success(),
expect,
|| println!("\n\ncommand did not execute successfully: {:?}\n\
expected success, got: {}\n\n",
cmd,
status))
}
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
}
if !status.success() {
println!("\n\ncommand did not execute successfully: {:?}\n\
expected success, got: {}\n\n",
cmd,
status);
}
status.success()
}
pub fn run_suppressed(cmd: &mut Command, expect: BuildExpectation) {
if !try_run_suppressed(cmd, expect) {
pub fn run_suppressed(cmd: &mut Command) {
if !try_run_suppressed(cmd) {
std::process::exit(1);
}
}
pub fn try_run_suppressed(cmd: &mut Command, expect: BuildExpectation) -> bool {
pub fn try_run_suppressed(cmd: &mut Command) -> bool {
let output = match cmd.output() {
Ok(status) => status,
Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}",
cmd, e)),
};
process_status(
cmd,
output.status.success(),
expect,
|| println!("\n\ncommand did not execute successfully: {:?}\n\
if !output.status.success() {
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)))
String::from_utf8_lossy(&output.stderr));
}
output.status.success()
}
pub fn gnu_target(target: &str) -> String {

View file

@ -16,7 +16,7 @@ extern crate cc;
use std::env;
use std::path::PathBuf;
use std::process::Command;
use build_helper::{run, native_lib_boilerplate, BuildExpectation};
use build_helper::{run, native_lib_boilerplate};
fn main() {
// FIXME: This is a hack to support building targets that don't
@ -113,7 +113,7 @@ fn main() {
cmd.arg("--with-lg-quantum=4");
}
run(&mut cmd, BuildExpectation::None);
run(&mut cmd);
let mut make = Command::new(build_helper::make(&host));
make.current_dir(&native.out_dir)
@ -130,7 +130,7 @@ fn main() {
.arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set"));
}
run(&mut make, BuildExpectation::None);
run(&mut make);
// 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

View file

@ -14,7 +14,7 @@ extern crate build_helper;
use std::env;
use std::process::Command;
use build_helper::{run, native_lib_boilerplate, BuildExpectation};
use build_helper::{run, native_lib_boilerplate};
fn main() {
let target = env::var("TARGET").expect("TARGET was not set");
@ -91,14 +91,11 @@ fn build_libbacktrace(host: &str, target: &str) -> Result<(), ()> {
.arg("--disable-host-shared")
.arg(format!("--host={}", build_helper::gnu_target(target)))
.arg(format!("--build={}", build_helper::gnu_target(host)))
.env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden"),
BuildExpectation::None);
.env("CFLAGS", env::var("CFLAGS").unwrap_or_default() + " -fvisibility=hidden"));
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")),
BuildExpectation::None);
.arg("-j").arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set")));
Ok(())
}

View file

@ -1,36 +0,0 @@
# 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. Compiling: 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
# opening a PR against the tool so that it works with your changes.
# If the tool stops compiling, change its state to `Broken`. If it
# still builds, change it to `Compiling`.
# 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) remember to ping
# the tool authors, so they can fix it, instead of being surprised by the
# breakage.
#
# Each tool has a list of people to ping
# ping @oli-obk @RalfJung @eddyb
miri = "Broken"
# ping @Manishearth @llogiq @mcarton @oli-obk
clippy = "Broken"
# ping @nrc
rls = "Broken"
# ping @nrc
# when breaking rustfmt, always break rls as well
rustfmt = "Broken"