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.
96 lines
2.9 KiB
Rust
96 lines
2.9 KiB
Rust
// 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 std::collections::HashMap;
|
|
use std::process::Command;
|
|
use std::path::PathBuf;
|
|
|
|
use build_helper::output;
|
|
use rustc_serialize::json;
|
|
|
|
use {Build, Crate};
|
|
|
|
#[derive(RustcDecodable)]
|
|
struct Output {
|
|
packages: Vec<Package>,
|
|
resolve: Resolve,
|
|
}
|
|
|
|
#[derive(RustcDecodable)]
|
|
struct Package {
|
|
id: String,
|
|
name: String,
|
|
source: Option<String>,
|
|
manifest_path: String,
|
|
}
|
|
|
|
#[derive(RustcDecodable)]
|
|
struct Resolve {
|
|
nodes: Vec<ResolveNode>,
|
|
}
|
|
|
|
#[derive(RustcDecodable)]
|
|
struct ResolveNode {
|
|
id: String,
|
|
dependencies: Vec<String>,
|
|
}
|
|
|
|
pub fn build(build: &mut Build) {
|
|
build_krate(build, "src/rustc/std_shim");
|
|
build_krate(build, "src/rustc/test_shim");
|
|
build_krate(build, "src/rustc");
|
|
}
|
|
|
|
fn build_krate(build: &mut Build, krate: &str) {
|
|
// 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(krate).join("Cargo.toml"));
|
|
let output = output(&mut cargo);
|
|
let output: Output = json::decode(&output).unwrap();
|
|
let mut id2name = HashMap::new();
|
|
for package in output.packages {
|
|
if package.source.is_none() {
|
|
id2name.insert(package.id, package.name.clone());
|
|
let mut path = PathBuf::from(package.manifest_path);
|
|
path.pop();
|
|
build.crates.insert(package.name.clone(), Crate {
|
|
build_step: format!("build-crate-{}", package.name),
|
|
doc_step: format!("doc-crate-{}", package.name),
|
|
test_step: format!("test-crate-{}", package.name),
|
|
name: package.name,
|
|
deps: Vec::new(),
|
|
path: path,
|
|
});
|
|
}
|
|
}
|
|
|
|
for node in output.resolve.nodes {
|
|
let name = match id2name.get(&node.id) {
|
|
Some(name) => name,
|
|
None => continue,
|
|
};
|
|
|
|
let krate = build.crates.get_mut(name).unwrap();
|
|
for dep in node.dependencies.iter() {
|
|
let dep = match id2name.get(dep) {
|
|
Some(dep) => dep,
|
|
None => continue,
|
|
};
|
|
krate.deps.push(dep.clone());
|
|
}
|
|
}
|
|
}
|