Commit a270b801 authored by Alex Crichton's avatar Alex Crichton

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.
parent 5665bdf3
......@@ -127,7 +127,7 @@ ones from MSYS if you have it installed). You'll also need Visual Studio 2013 or
newer with the C++ tools. Then all you need to do is to kick off rustbuild.
```
python .\src\bootstrap\bootstrap.py
python x.py build
```
Currently rustbuild only works with some known versions of Visual Studio. If you
......@@ -137,7 +137,7 @@ by manually calling the appropriate vcvars file before running the bootstrap.
```
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
python .\src\bootstrap\bootstrap.py
python x.py build
```
## Building Documentation
......
......@@ -40,9 +40,9 @@ name = "bootstrap"
version = "0.0.0"
dependencies = [
"build_helper 0.1.0",
"cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)",
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -63,7 +63,7 @@ version = "0.1.0"
[[package]]
name = "cmake"
version = "0.1.17"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -131,11 +131,6 @@ dependencies = [
name = "fmt_macros"
version = "0.0.0"
[[package]]
name = "gcc"
version = "0.3.38"
source = "git+https://github.com/alexcrichton/gcc-rs#be620ac6d3ddb498cd0c700d5312c6a4c3c19597"
[[package]]
name = "gcc"
version = "0.3.38"
......@@ -189,7 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "linkchecker"
version = "0.1.0"
dependencies = [
"url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -725,7 +720,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.2.2"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -743,10 +738,9 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978"
"checksum cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0e5bcf27e097a184c1df4437654ed98df3d7a516e8508a6ba45d8b092bbdf283"
"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
"checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
"checksum gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>"
"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
"checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
......@@ -760,6 +754,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
"checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
"checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
"checksum url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba5a45db1d2e0effb7a1c00cc73ffc63a973da8c7d1fcd5b46f24285ade6c54"
"checksum url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "48ccf7bd87a81b769cf84ad556e034541fb90e1cd6d4bc375c822ed9500cd9d7"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
......@@ -27,7 +27,7 @@ num_cpus = "0.2"
toml = "0.1"
getopts = "0.2"
rustc-serialize = "0.3"
gcc = { git = "https://github.com/alexcrichton/gcc-rs" }
gcc = "0.3.36"
libc = "0.2"
md5 = "0.1"
......
......@@ -10,24 +10,72 @@ system.
## Using rustbuild
When configuring Rust via `./configure`, pass the following to enable building
via this build system:
The rustbuild build system has a primary entry point, a top level `x.py` script:
```
./configure --enable-rustbuild
make
python ./x.py build
```
Afterwards the `Makefile` which is generated will have a few commands like
`make check`, `make tidy`, etc. For finer-grained control, the
`bootstrap.py` entry point can be used:
Note that if you're on Unix you should be able to execute the script directly:
```
python src/bootstrap/bootstrap.py
./x.py build
```
This accepts a number of options like `--stage` and `--step` which can configure
what's actually being done.
The script accepts commands, flags, and filters to determine what to do:
* `build` - a general purpose command for compiling code. Alone `build` will
bootstrap the entire compiler, and otherwise arguments passed indicate what to
build. For example:
```
# build the whole compiler
./x.py build
# build the stage1 compier
./x.py build --stage 1
# build stage0 libstd
./x.py build --stage 0 src/libstd
# build a particular crate in stage0
./x.py build --stage 0 src/libtest
```
* `test` - a command for executing unit tests. Like the `build` command this
will execute the entire test suite by default, and otherwise it can be used to
select which test suite is run:
```
# run all unit tests
./x.py test
# execute the run-pass test suite
./x.py test src/test/run-pass
# execute only some tests in the run-pass test suite
./x.py test src/test/run-pass --filter my-filter
# execute tests in the standard library in stage0
./x.py test --stage 0 src/libstd
# execute all doc tests
./x.py test src/doc
```
* `doc` - a command for building documentation. Like above can take arguments
for what to document.
If you're more used to `./configure` and `make`, however, then you can also
configure the build system to use rustbuild instead of the old makefiles:
```
./configure --enable-rustbuild
make
```
Afterwards the `Makefile` which is generated will have a few commands like
`make check`, `make tidy`, etc.
## Configuring rustbuild
......@@ -47,7 +95,7 @@ being invoked manually (via the python script).
The rustbuild build system goes through a few phases to actually build the
compiler. What actually happens when you invoke rustbuild is:
1. The entry point script, `src/bootstrap/bootstrap.py` is run. This script is
1. The entry point script, `x.py` is run. This script is
responsible for downloading the stage0 compiler/Cargo binaries, and it then
compiles the build system itself (this folder). Finally, it then invokes the
actual `bootstrap` binary build system.
......
......@@ -399,12 +399,10 @@ def main():
# Run the bootstrap
args = [os.path.join(rb.build_dir, "bootstrap/debug/bootstrap")]
args.append('--src')
args.append(rb.rust_root)
args.append('--build')
args.append(rb.build)
args.extend(sys.argv[1:])
env = os.environ.copy()
env["BUILD"] = rb.build
env["SRC"] = rb.rust_root
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
rb.run(args, env)
......
......@@ -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 @@ pub fn compiletest(build: &Build,
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 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
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 @@ fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
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 @@ pub fn krate(build: &Build,
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 @@ pub fn krate(build: &Build,
.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
}
// 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);
match krate {
Some(krate) => {
cargo.arg("-p").arg(krate);
}
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 @@ pub fn krate(build: &Build,
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 @@ fn krate_android(build: &Build,
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);
......
......@@ -25,17 +25,17 @@ pub fn clean(build: &Build) {
rm_rf(build, &build.out.join("tmp"));
for host in build.config.host.iter() {
let out = build.out.join(host);
rm_rf(build, &out.join("doc"));
for stage in 0..4 {
rm_rf(build, &out.join(format!("stage{}", stage)));
rm_rf(build, &out.join(format!("stage{}-std", stage)));
rm_rf(build, &out.join(format!("stage{}-rustc", stage)));
rm_rf(build, &out.join(format!("stage{}-tools", stage)));
rm_rf(build, &out.join(format!("stage{}-test", stage)));
let entries = match build.out.join(host).read_dir() {
Ok(iter) => iter,
Err(_) => continue,
};
for entry in entries {
let entry = t!(entry);
if entry.file_name().to_str() == Some("llvm") {
continue
}
t!(fs::remove_dir_all(&entry.path()));
}
}
}
......
......@@ -64,8 +64,8 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
}
build.run(&mut cargo);
update_mtime(&libstd_stamp(build, compiler, target));
std_link(build, target, compiler, compiler.host);
update_mtime(&libstd_stamp(build, &compiler, target));
std_link(build, target, compiler.stage, compiler.host);
}
/// Link all libstd rlibs/dylibs into the sysroot location.
......@@ -74,11 +74,12 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
/// by `compiler` into `host`'s sysroot.
pub fn std_link(build: &Build,
target: &str,
compiler: &Compiler,
stage: u32,
host: &str) {
let compiler = Compiler::new(stage, &build.config.build);
let target_compiler = Compiler::new(compiler.stage, host);
let libdir = build.sysroot_libdir(&target_compiler, target);
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
let out_dir = build.cargo_out(&compiler, Mode::Libstd, target);
// If we're linking one compiler host's output into another, then we weren't
// called from the `std` method above. In that case we clean out what's
......@@ -146,7 +147,7 @@ pub fn test<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
.arg(build.src.join("src/rustc/test_shim/Cargo.toml"));
build.run(&mut cargo);
update_mtime(&libtest_stamp(build, compiler, target));
test_link(build, target, compiler, compiler.host);
test_link(build, target, compiler.stage, compiler.host);
}
/// Link all libtest rlibs/dylibs into the sysroot location.
......@@ -155,11 +156,12 @@ pub fn test<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
/// by `compiler` into `host`'s sysroot.
pub fn test_link(build: &Build,
target: &str,
compiler: &Compiler,
stage: u32,
host: &str) {
let compiler = Compiler::new(stage, &build.config.build);
let target_compiler = Compiler::new(compiler.stage, host);
let libdir = build.sysroot_libdir(&target_compiler, target);
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
let out_dir = build.cargo_out(&compiler, Mode::Libtest, target);
add_to_sysroot(&out_dir, &libdir);
}
......@@ -218,7 +220,7 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
}
build.run(&mut cargo);
rustc_link(build, target, compiler, compiler.host);
rustc_link(build, target, compiler.stage, compiler.host);
}
/// Link all librustc rlibs/dylibs into the sysroot location.
......@@ -227,11 +229,12 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
/// by `compiler` into `host`'s sysroot.
pub fn rustc_link(build: &Build,
target: &str,
compiler: &Compiler,
stage: u32,
host: &str) {
let compiler = Compiler::new(stage, &build.config.build);
let target_compiler = Compiler::new(compiler.stage, host);
let libdir = build.sysroot_libdir(&target_compiler, target);
let out_dir = build.cargo_out(compiler, Mode::Librustc, target);
let out_dir = build.cargo_out(&compiler, Mode::Librustc, target);
add_to_sysroot(&out_dir, &libdir);
}
......@@ -259,7 +262,10 @@ fn compiler_file(compiler: &Path, file: &str) -> PathBuf {
/// must have been previously produced by the `stage - 1` build.config.build
/// compiler.
pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
assert!(stage > 0, "the stage0 compiler isn't assembled, it's downloaded");
// nothing to do in stage0
if stage == 0 {
return
}
// The compiler that we're assembling
let target_compiler = Compiler::new(stage, host);
......
......@@ -19,7 +19,6 @@
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
use {Build, Compiler, Mode};
......@@ -30,8 +29,9 @@ use util::{up_to_date, cp_r};
///
/// This will not actually generate any documentation if the documentation has
/// already been generated.
pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str, out: &Path) {
t!(fs::create_dir_all(out));
pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str) {
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let out = out.join(name);
let compiler = Compiler::new(stage, &build.config.build);
......@@ -57,9 +57,10 @@ pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str, out: &Path)
/// `STAMP` alongw ith providing the various header/footer HTML we've cutomized.
///
/// In the end, this is just a glorified wrapper around rustdoc!
pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) {
pub fn standalone(build: &Build, stage: u32, target: &str) {
println!("Documenting stage{} standalone ({})", stage, target);
t!(fs::create_dir_all(out));
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(stage, &build.config.build);
......@@ -109,7 +110,7 @@ pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) {
.arg("--html-in-header").arg(&favicon)
.arg("--markdown-playground-url")
.arg("https://play.rust-lang.org/")
.arg("-o").arg(out)
.arg("-o").arg(&out)
.arg(&path);
if filename == "reference.md" {
......@@ -131,9 +132,10 @@ pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) {
///
/// This will generate all documentation for the standard library and its
/// dependencies. This is largely just a wrapper around `cargo doc`.
pub fn std(build: &Build, stage: u32, target: &str, out: &Path) {
pub fn std(build: &Build, stage: u32, target: &str) {
println!("Documenting stage{} std ({})", stage, target);
t!(fs::create_dir_all(out));
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(stage, &build.config.build);
let out_dir = build.stage_out(&compiler, Mode::Libstd)
.join(target).join("doc");
......@@ -146,16 +148,17 @@ pub fn std(build: &Build, stage: u32, target: &str, out: &Path) {
.arg(build.src.join("src/rustc/std_shim/Cargo.toml"))
.arg("--features").arg(build.std_features());
build.run(&mut cargo);
cp_r(&out_dir, out)
cp_r(&out_dir, &out)
}
/// Compile all libtest documentation.
///
/// This will generate all documentation for libtest and its dependencies. This
/// is largely just a wrapper around `cargo doc`.
pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
pub fn test(build: &Build, stage: u32, target: &str) {
println!("Documenting stage{} test ({})", stage, target);
t!(fs::create_dir_all(out));
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(stage, &build.config.build);
let out_dir = build.stage_out(&compiler, Mode::Libtest)
.join(target).join("doc");
......@@ -167,16 +170,17 @@ pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
cargo.arg("--manifest-path")
.arg(build.src.join("src/rustc/test_shim/Cargo.toml"));
build.run(&mut cargo);
cp_r(&out_dir, out)
cp_r(&out_dir, &out)
}
/// Generate all compiler documentation.
///
/// This will generate all documentation for the compiler libraries and their
/// dependencies. This is largely just a wrapper around `cargo doc`.
pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) {
pub fn rustc(build: &Build, stage: u32, target: &str) {
println!("Documenting stage{} compiler ({})", stage, target);
t!(fs::create_dir_all(out));
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(stage, &build.config.build);
let out_dir = build.stage_out(&compiler, Mode::Librustc)
.join(target).join("doc");
......@@ -189,14 +193,15 @@ pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) {
.arg(build.src.join("src/rustc/Cargo.toml"))
.arg("--features").arg(build.rustc_features());
build.run(&mut cargo);
cp_r(&out_dir, out)
cp_r(&out_dir, &out)
}
/// Generates the HTML rendered error-index by running the
/// `error_index_generator` tool.
pub fn error_index(build: &Build, stage: u32, target: &str, out: &Path) {
pub fn error_index(build: &Build, stage: u32, target: &str) {
println!("Documenting stage{} error index ({})", stage, target);
t!(fs::create_dir_all(out));
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
let compiler = Compiler::new(stage, &build.config.build);
let mut index = build.tool_cmd(&compiler, "error_index_generator");
index.arg("html");
......
......@@ -13,30 +13,46 @@
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.
use std::env;
use std::fs;
use std::path::PathBuf;
use std::process;
use std::slice;
use getopts::Options;
use getopts::{Matches, Options};
use Build;
use config::Config;
use metadata;
use step;
/// Deserialized version of all flags for this compile.
pub struct Flags {
pub verbose: bool,
pub stage: Option<u32>,
pub build: String,
pub host: Filter,
pub target: Filter,
pub step: Vec<String>,
pub host: Vec<String>,
pub target: Vec<String>,
pub config: Option<PathBuf>,
pub src: Option<PathBuf>,
pub jobs: Option<u32>,
pub args: Vec<String>,
pub clean: bool,
pub cmd: Subcommand,
}
pub struct Filter {
values: Vec<String>,
pub enum Subcommand {
Build {
paths: Vec<PathBuf>,
},
Doc {
paths: Vec<PathBuf>,
},
Test {
paths: Vec<PathBuf>,
test_args: Vec<String>,
},
Clean,
Dist {
install: bool,
},
}