rustbuild: Rewrite user-facing interface
This commit is a rewrite of the user-facing interface to the rustbuild build
system. The intention here is to make it much easier to compile/test the project
without having to remember weird rule names and such. An overall view of the new
interface is:
# build everything
./x.py build
# document everyting
./x.py doc
# test everything
./x.py test
# test libstd
./x.py test src/libstd
# build libcore stage0
./x.py build src/libcore --stage 0
# run stage1 run-pass tests
./x.py test src/test/run-pass --stage 1
The `src/bootstrap/bootstrap.py` script is now aliased as a top-level `x.py`
script. This `x` was chosen to be both short and easily tab-completable (no
collisions in that namespace!). The build system now accepts a "subcommand" of
what to do next, the main ones being build/doc/test.
Each subcommand then receives an optional list of arguments. These arguments are
paths in the source repo of what to work with. That is, if you want to test a
directory, you just pass that directory as an argument.
The purpose of this rewrite is to do away with all of the arcane renames like
"rpass" is the "run-pass" suite, "cfail" is the "compile-fail" suite, etc. By
simply working with directories and files it's much more intuitive of how to run
a test (just pass it as an argument).
The rustbuild step/dependency management was also rewritten along the way to
make this easy to work with and define, but that's largely just a refactoring of
what was there before.
The *intention* is that this support is extended for arbitrary files (e.g.
`src/test/run-pass/my-test-case.rs`), but that isn't quite implemented just yet.
Instead directories work for now but we can follow up with stricter path
filtering logic to plumb through all the arguments.
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 0a281b8..e5b666a 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -13,44 +13,19 @@
//! This file implements the various regression test suites that we execute on
//! our CI.
-use std::collections::{HashMap, HashSet};
+use std::collections::HashSet;
use std::env;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use build_helper::output;
-use rustc_serialize::json;
use {Build, Compiler, Mode};
use util::{self, dylib_path, dylib_path_var};
const ADB_TEST_DIR: &'static str = "/data/tmp";
-#[derive(RustcDecodable)]
-struct Output {
- packages: Vec<Package>,
- resolve: Resolve,
-}
-
-#[derive(RustcDecodable)]
-struct Package {
- id: String,
- name: String,
- source: Option<String>,
-}
-
-#[derive(RustcDecodable)]
-struct Resolve {
- nodes: Vec<ResolveNode>,
-}
-
-#[derive(RustcDecodable)]
-struct ResolveNode {
- id: String,
- dependencies: Vec<String>,
-}
-
/// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
///
/// This tool in `src/tools` will verify the validity of all our links in the
@@ -181,7 +156,7 @@
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
cmd.arg("--llvm-version").arg(llvm_version);
- cmd.args(&build.flags.args);
+ cmd.args(&build.flags.cmd.test_args());
if build.config.verbose || build.flags.verbose {
cmd.arg("--verbose");
@@ -282,7 +257,7 @@
cmd.arg("--test");
cmd.arg(markdown);
- let mut test_args = build.flags.args.join(" ");
+ let mut test_args = build.flags.cmd.test_args().join(" ");
if build.config.quiet_tests {
test_args.push_str(" --quiet");
}
@@ -302,7 +277,8 @@
pub fn krate(build: &Build,
compiler: &Compiler,
target: &str,
- mode: Mode) {
+ mode: Mode,
+ krate: Option<&str>) {
let (name, path, features, root) = match mode {
Mode::Libstd => {
("libstd", "src/rustc/std_shim", build.std_features(), "std_shim")
@@ -318,24 +294,6 @@
println!("Testing {} stage{} ({} -> {})", name, compiler.stage,
compiler.host, target);
- // Run `cargo metadata` to figure out what crates we're testing.
- //
- // Down below we're going to call `cargo test`, but to test the right set
- // of packages we're going to have to know what `-p` arguments to pass it
- // to know what crates to test. Here we run `cargo metadata` to learn about
- // the dependency graph and what `-p` arguments there are.
- let mut cargo = Command::new(&build.cargo);
- cargo.arg("metadata")
- .arg("--manifest-path").arg(build.src.join(path).join("Cargo.toml"));
- let output = output(&mut cargo);
- let output: Output = json::decode(&output).unwrap();
- let id2pkg = output.packages.iter()
- .map(|pkg| (&pkg.id, pkg))
- .collect::<HashMap<_, _>>();
- let id2deps = output.resolve.nodes.iter()
- .map(|node| (&node.id, &node.dependencies))
- .collect::<HashMap<_, _>>();
-
// Build up the base `cargo test` command.
//
// Pass in some standard flags then iterate over the graph we've discovered
@@ -346,24 +304,25 @@
.arg(build.src.join(path).join("Cargo.toml"))
.arg("--features").arg(features);
- let mut visited = HashSet::new();
- let root_pkg = output.packages.iter().find(|p| p.name == root).unwrap();
- let mut next = vec![&root_pkg.id];
- while let Some(id) = next.pop() {
- // Skip any packages with sources listed, as these come from crates.io
- // and we shouldn't be testing them.
- if id2pkg[id].source.is_some() {
- continue
+ match krate {
+ Some(krate) => {
+ cargo.arg("-p").arg(krate);
}
- // Right now jemalloc is our only target-specific crate in the sense
- // that it's not present on all platforms. Custom skip it here for now,
- // but if we add more this probably wants to get more generalized.
- if !id.contains("jemalloc") {
- cargo.arg("-p").arg(&id2pkg[id].name);
- }
- for dep in id2deps[id] {
- if visited.insert(dep) {
- next.push(dep);
+ None => {
+ let mut visited = HashSet::new();
+ let mut next = vec![root];
+ while let Some(name) = next.pop() {
+ // Right now jemalloc is our only target-specific crate in the sense
+ // that it's not present on all platforms. Custom skip it here for now,
+ // but if we add more this probably wants to get more generalized.
+ if !name.contains("jemalloc") {
+ cargo.arg("-p").arg(name);
+ }
+ for dep in build.crates[name].deps.iter() {
+ if visited.insert(dep) {
+ next.push(dep);
+ }
+ }
}
}
}
@@ -389,7 +348,7 @@
build.run(cargo.arg("--no-run"));
krate_emscripten(build, compiler, target, mode);
} else {
- cargo.args(&build.flags.args);
+ cargo.args(&build.flags.cmd.test_args());
build.run(&mut cargo);
}
}
@@ -421,7 +380,7 @@
target = target,
test = test_file_name,
log = log,
- args = build.flags.args.join(" "));
+ args = build.flags.cmd.test_args().join(" "));
let output = output(Command::new("adb").arg("shell").arg(&program));
println!("{}", output);