"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
rustc-serialize = "0.3"
gcc = "0.3.50"
libc = "0.2"
+serde = "1.0"
+serde_json = "1.0"
+serde_derive = "1.0"
use serde::{Serialize, Deserialize};
use std::cell::RefCell;
-use std::collections::HashSet;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::fs;
+use std::ops::Deref;
use compile;
use install;
use flags::Subcommand;
use doc;
+pub use Compiler;
+
pub struct Builder<'a> {
pub build: &'a Build,
pub top_stage: u32,
pub trait Step<'a>: Sized {
type Output: Serialize + Deserialize<'a>;
- const NAME: &'static str;
const DEFAULT: bool = false;
compile::StartupObjects),
Kind::Test => check!(builder, paths, check::Tidy, check::Bootstrap, check::Compiletest,
check::Krate, check::KrateLibrustc, check::Linkcheck, check::Cargotest,
- check::TestCargo, check::Docs, check::ErrorIndex, check::Distcheck),
+ check::Cargo, check::Docs, check::ErrorIndex, check::Distcheck),
Kind::Bench => check!(builder, paths, check::Krate, check::KrateLibrustc),
Kind::Doc => builder.default_doc(Some(paths)),
Kind::Dist => check!(builder, paths, dist::Docs, dist::Mingw, dist::Rustc,
pub fn default_doc(&self, paths: Option<&[PathBuf]>) {
let paths = paths.unwrap_or(&[]);
- check!(self, paths, doc::UnstableBook, doc::UnstableBookGen, doc::Rustbook, doc::Book,
+ check!(self, paths, doc::UnstableBook, doc::UnstableBookGen, doc::Rustbook, doc::TheBook,
doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex,
doc::Nomicon, doc::Reference);
}
}
impl<'a> Step<'a> for Libdir<'a> {
type Output = PathBuf;
- const NAME: &'static str = "sysroot libdir";
fn run(self, builder: &Builder) -> PathBuf {
let sysroot = builder.sysroot(self.compiler)
.join("lib").join("rustlib").join(self.target).join("lib");
const ADB_TEST_DIR: &str = "/data/tmp/work";
/// The two modes of the test runner; tests or benchmarks.
-#[derive(Copy, Clone)]
+#[derive(Serialize, Copy, Clone)]
pub enum TestKind {
/// Run `cargo test`
Test,
/// test` to ensure that we don't regress the test suites there.
fn run(self, builder: &Builder) {
let build = builder.build;
- let compiler = builder.compiler(self.stage, host);
+ let compiler = builder.compiler(self.stage, self.host);
builder.ensure(compile::Rustc { compiler, target: compiler.host });
// Note that this is a short, cryptic, and not scoped directory name. This
let mut cmd = builder.tool_cmd(Tool::CargoTest);
try_run(build, cmd.arg(&build.initial_cargo)
.arg(&out_dir)
- .env("RUSTC", build.compiler_path(&compiler))
- .env("RUSTDOC", build.rustdoc(&compiler)));
+ .env("RUSTC", build.compiler_path(compiler))
+ .env("RUSTDOC", build.rustdoc(compiler)));
}
}
path.ends_with("cargo") // FIXME: Why is this not src/tools/cargo?
}
- fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
- builder.ensure(TestCargo {
- compiler: builder.compiler(builder.top_stage, host),
- target,
+ fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
+ builder.ensure(Cargotest {
+ stage: builder.top_stage,
+ host: target,
});
}
// 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
// fail if rustc is not spelled `rustc`.
- let path = build.sysroot(compiler).join("bin");
+ let path = builder.sysroot(compiler).join("bin");
let old_path = env::var_os("PATH").unwrap_or_default();
let newpath = env::join_paths(
iter::once(path).chain(env::split_paths(&old_path))
let _folder = build.fold_output(|| "tidy");
println!("tidy check ({})", host);
- let mut cmd = build.tool_cmd(Tool::Tidy);
+ let mut cmd = builder.tool_cmd(Tool::Tidy);
cmd.arg(build.src.join("src"));
if !build.config.vendor {
cmd.arg("--no-vendor");
// of them!
cmd.arg("--compile-lib-path").arg(build.rustc_libdir(compiler));
- cmd.arg("--run-lib-path").arg(build.sysroot_libdir(compiler, target));
+ cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target));
cmd.arg("--rustc-path").arg(build.compiler_path(compiler));
cmd.arg("--rustdoc-path").arg(build.rustdoc(compiler));
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
flags.push("-g".to_string());
}
- let mut hostflags = build.rustc_flags(&compiler.host);
+ let mut hostflags = build.rustc_flags(compiler.host);
hostflags.extend(flags.clone());
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
let output = dir.join("error-index.md");
let _time = util::timeit();
- build.run(build.tool_cmd(Tool::ErrorIndex)
+ build.run(builder.tool_cmd(Tool::ErrorIndex)
.arg("markdown")
.arg(&output)
.env("CFG_BUILD", &build.build));
}
}
-fn markdown_test(build: &Build, compiler: &Compiler, markdown: &Path) {
+fn markdown_test(build: &Build, compiler: Compiler, markdown: &Path) {
let mut file = t!(File::open(markdown));
let mut contents = String::new();
t!(file.read_to_string(&mut contents));
impl<'a> Step<'a> for KrateLibrustc<'a> {
type Output = ();
- const NAME: &'static str = "check librustc";
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
// Pass in some standard flags then iterate over the graph we've discovered
// in `cargo metadata` with the maps above and figure out what `-p`
// arguments need to get passed.
- let mut cargo = build.cargo(&compiler, mode, target, test_kind.subcommand());
+ let mut cargo = build.cargo(compiler, mode, target, test_kind.subcommand());
cargo.arg("--manifest-path")
.arg(build.src.join(path).join("Cargo.toml"))
.arg("--features").arg(features);
// Note that to run the compiler we need to run with the *host* libraries,
// but our wrapper scripts arrange for that to be the case anyway.
let mut dylib_path = dylib_path();
- dylib_path.insert(0, build.sysroot_libdir(&compiler, target));
+ dylib_path.insert(0, builder.sysroot_libdir(compiler, target));
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
if target.contains("emscripten") || build.remote_tested(target) {
if target.contains("emscripten") {
build.run(&mut cargo);
- krate_emscripten(build, &compiler, target, mode);
+ krate_emscripten(build, compiler, target, mode);
} else if build.remote_tested(target) {
build.run(&mut cargo);
- krate_remote(builder, &compiler, target, mode);
+ krate_remote(builder, compiler, target, mode);
} else {
cargo.args(&build.flags.cmd.test_args());
try_run(build, &mut cargo);
}
fn krate_emscripten(build: &Build,
- compiler: &Compiler,
+ compiler: Compiler,
target: &str,
mode: Mode) {
let out_dir = build.cargo_out(compiler, mode, target);
}
}
-fn krate_remote(build: &Builder,
- compiler: &Compiler,
+fn krate_remote(builder: &Builder,
+ compiler: Compiler,
target: &str,
mode: Mode) {
+ let build = builder.build;
let out_dir = build.cargo_out(compiler, mode, target);
let tests = find_tests(&out_dir.join("deps"), target);
build.run(&mut cmd);
// Push all our dylibs to the emulator
- for f in t!(build.sysroot_libdir(compiler, target).read_dir()) {
+ for f in t!(builder.sysroot_libdir(compiler, target).read_dir()) {
let f = t!(f);
let name = f.file_name().into_string().unwrap();
if util::is_dylib(&name) {
#[derive(Serialize)]
pub struct Bootstrap;
-impl<'a> for Step<'a> Bootstrap {
+impl<'a> Step<'a> for Bootstrap {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
use filetime::FileTime;
use rustc_serialize::json;
-use channel::GitInfo;
use util::{exe, libdir, is_dylib, copy};
use {Build, Compiler, Mode};
+use native;
+
+use builder::{Step, Builder};
//
// // Crates which have build scripts need to rely on this rule to ensure that
// different compiler, or from actually building the crate itself (the `dep`
// rule). The `run` rule then mirrors these three cases and links the cases
// forward into the compiler sysroot specified from the correct location.
-fn crate_rule<'a, 'b>(build: &'a Build,
- rules: &'b mut Rules<'a>,
- krate: &'a str,
- dep: &'a str,
- link: fn(&Build, &Compiler, &Compiler, &str))
- -> RuleBuilder<'a, 'b> {
- let mut rule = rules.build(&krate, "path/to/nowhere");
- rule.dep(move |s| {
- if build.force_use_stage1(&s.compiler(), s.target) {
- s.host(&build.build).stage(1)
- } else if s.host == build.build {
- s.name(dep)
- } else {
- s.host(&build.build)
- }
- })
- .run(move |s| {
- if build.force_use_stage1(&s.compiler(), s.target) {
- link(build,
- &s.stage(1).host(&build.build).compiler(),
- &s.compiler(),
- s.target)
- } else if s.host == build.build {
- link(build, &s.compiler(), &s.compiler(), s.target)
- } else {
- link(build,
- &s.host(&build.build).compiler(),
- &s.compiler(),
- s.target)
- }
- });
- rule
-}
+// fn crate_rule<'a, 'b>(build: &'a Build,
+// rules: &'b mut Rules<'a>,
+// krate: &'a str,
+// dep: &'a str,
+// link: fn(&Build, compiler, compiler, &str))
+// -> RuleBuilder<'a, 'b> {
+// let mut rule = rules.build(&krate, "path/to/nowhere");
+// rule.dep(move |s| {
+// if build.force_use_stage1(&s.compiler(), s.target) {
+// s.host(&build.build).stage(1)
+// } else if s.host == build.build {
+// s.name(dep)
+// } else {
+// s.host(&build.build)
+// }
+// })
+// .run(move |s| {
+// if build.force_use_stage1(&s.compiler(), s.target) {
+// link(build,
+// &s.stage(1).host(&build.build).compiler(),
+// &s.compiler(),
+// s.target)
+// } else if s.host == build.build {
+// link(build, &s.compiler(), &s.compiler(), s.target)
+// } else {
+// link(build,
+// &s.host(&build.build).compiler(),
+// &s.compiler(),
+// s.target)
+// }
+// });
+// rule
+// }
// rules.build("libstd", "src/libstd")
// .dep(|s| s.name("rustc").target(s.host))
#[derive(Serialize)]
pub struct Std<'a> {
pub target: &'a str,
- pub compiler: &'a Compiler<'a>,
+ pub compiler: Compiler<'a>,
}
impl<'a> Step<'a> for Std<'a> {
run_cargo(build,
&mut cargo,
- &libstd_stamp(build, &compiler, target));
+ &libstd_stamp(build, compiler, target));
builder.ensure(StdLink {
compiler: builder.compiler(compiler.stage, &build.build),
compiler.host,
target_compiler.host,
target);
- let libdir = build.sysroot_libdir(target_compiler, target);
+ let libdir = builder.sysroot_libdir(target_compiler, target);
add_to_sysroot(&libdir, &libstd_stamp(build, compiler, target));
if target.contains("musl") && !target.contains("mips") {
#[derive(Serialize)]
pub struct StartupObjects<'a> {
- pub for_compiler: Compiler<'a>,
+ pub compiler: Compiler<'a>,
pub target: &'a str,
}
/// no other compilers are guaranteed to be available).
fn run(self, builder: &Builder) {
let build = builder.build;
- let for_compiler = self.for_compiler;
+ let for_compiler = self.compiler;
let target = self.target;
if !target.contains("pc-windows-gnu") {
return
}
- let compiler = Compiler::new(0, &build.build);
- let compiler_path = build.compiler_path(&compiler);
+ let compiler = builder.compiler(0, &build.build);
+ let compiler_path = build.compiler_path(compiler);
let src_dir = &build.src.join("src/rtstartup");
let dst_dir = &build.native_dir(target).join("rtstartup");
- let sysroot_dir = &build.sysroot_libdir(for_compiler, target);
+ let sysroot_dir = &builder.sysroot_libdir(for_compiler, target);
t!(fs::create_dir_all(dst_dir));
t!(fs::create_dir_all(sysroot_dir));
pub target: &'a str,
}
-impl<'a> Step<'a> for Step<'a> {
+impl<'a> Step<'a> for TestLink<'a> {
type Output = ();
/// Same as `std_link`, only for libtest
compiler.host,
target_compiler.host,
target);
- add_to_sysroot(&build.sysroot_libdir(target_compiler, target),
+ add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
&libtest_stamp(build, compiler, target));
}
}
compiler.host,
target_compiler.host,
target);
- add_to_sysroot(&build.sysroot_libdir(target_compiler, target),
+ add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
&librustc_stamp(build, compiler, target));
}
}
/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
-pub fn libstd_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn libstd_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Libstd, target).join(".libstd.stamp")
}
/// Cargo's output path for libtest in a given stage, compiled by a particular
/// compiler for the specified target.
-pub fn libtest_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn libtest_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Libtest, target).join(".libtest.stamp")
}
/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
-pub fn librustc_stamp(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
+pub fn librustc_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
}
}
impl<'a> Step<'a> for Assemble<'a> {
- type Output = ();
+ type Output = Compiler<'a>;
/// Prepare a new compiler from the artifacts in `stage`
///
/// This will assemble a compiler in `build/$host/stage$stage`. The compiler
/// must have been previously produced by the `stage - 1` build.build
/// compiler.
- fn run(self, builder: &Builder) {
+ fn run(self, builder: &Builder) -> Compiler<'a> {
let build = builder.build;
let target_compiler = self.target_compiler;
println!("Assembling stage{} compiler ({})", stage, host);
// Link in all dylibs to the libdir
- let sysroot = build.sysroot(&target_compiler);
+ let sysroot = builder.sysroot(target_compiler);
let sysroot_libdir = sysroot.join(libdir(host));
t!(fs::create_dir_all(&sysroot_libdir));
- let src_libdir = build.sysroot_libdir(&build_compiler, host);
+ let src_libdir = builder.sysroot_libdir(build_compiler, host);
for f in t!(fs::read_dir(&src_libdir)).map(|f| t!(f)) {
let filename = f.file_name().into_string().unwrap();
if is_dylib(&filename) {
}
}
- let out_dir = build.cargo_out(&build_compiler, Mode::Librustc, host);
+ let out_dir = build.cargo_out(build_compiler, Mode::Librustc, host);
// Link the compiler binary itself into place
let rustc = out_dir.join(exe("rustc", host));
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
- let compiler = build.compiler_path(&target_compiler);
+ let compiler = build.compiler_path(target_compiler);
let _ = fs::remove_file(&compiler);
copy(&rustc, &compiler);
let _ = fs::remove_file(&rustdoc_dst);
copy(&rustdoc_src, &rustdoc_dst);
}
+
+ target_compiler
}
}
use {Build, Compiler, Mode};
use channel;
use util::{cp_r, libdir, is_dylib, cp_filtered, copy, exe};
+use builder::{Builder, Step};
+use compile;
+use tool::{self, Tool};
pub fn pkgname(build: &Build, component: &str) -> String {
if component == "cargo" {
build.out.join("tmp/dist")
}
-fn rust_installer(build: &Build) -> Command {
- build.tool_cmd(&Compiler::new(0, &build.build), "rust-installer")
+fn rust_installer(builder: &Builder) -> Command {
+ builder.tool_cmd(Tool::RustInstaller)
}
// rules.dist("dist-docs", "src/doc")
#[derive(Serialize)]
pub struct Docs<'a> {
- stage: u32,
- host: &'a str,
+ pub stage: u32,
+ pub host: &'a str,
}
impl<'a> Step<'a> for Docs<'a> {
let src = build.out.join(host).join("doc");
cp_r(&src, &dst);
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust-Documentation")
.arg("--rel-manifest-dir=rustlib")
// (which is what we want).
make_win_dist(&tmpdir(build), &image, host, &build);
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust-MinGW")
.arg("--rel-manifest-dir=rustlib")
#[derive(Serialize)]
pub struct Rustc<'a> {
- stage: u32,
- host: &'a str,
+ pub stage: u32,
+ pub host: &'a str,
}
impl<'a> Step<'a> for Rustc<'a> {
}
/// Creates the `rustc` installer component.
- fn run(self, builder: &builder) {
+ fn run(self, builder: &Builder) {
let build = builder.build;
let stage = self.stage;
let host = self.host;
}
// Finally, wrap everything up in a nice tarball!
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
fn prepare_image(builder: &Builder, stage: u32, host: &str, image: &Path) {
let build = builder.build;
- let src = build.sysroot(builder.compiler(stage, host));
+ let src = builder.sysroot(builder.compiler(stage, host));
let libdir = libdir(host);
// Copy rustc/rustdoc binaries
}
//rules.test("debugger-scripts", "src/etc/lldb_batchmode.py")
-// .run(move |s| dist::debugger_scripts(build, &build.sysroot(&s.compiler()),
+// .run(move |s| dist::debugger_scripts(build, &builder.sysroot(&s.compiler()),
// s.target));
#[derive(Serialize)]
pub struct DebuggerScripts<'a> {
- sysroot: &'a Path,
- host: &'a str,
+ pub sysroot: &'a Path,
+ pub host: &'a str,
}
impl<'a> Step<'a> for DebuggerScripts<'a> {
#[derive(Serialize)]
pub struct Analysis<'a> {
- compiler: Compiler<'a>,
- target: &'a str,
+ pub compiler: Compiler<'a>,
+ pub target: &'a str,
}
impl<'a> Step<'a> for Analysis<'a> {
println!("image_src: {:?}, dst: {:?}", image_src, dst);
cp_r(&image_src, &dst);
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
copy_src_dirs(build, &std_src_dirs[..], &std_src_dirs_exclude[..], &dst_src);
// Create source tarball in rust-installer format
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
if let Some(dir) = tarball.parent() {
t!(fs::create_dir_all(dir));
}
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("tarball")
.arg("--input").arg(&plain_name)
.arg("--output").arg(&tarball)
#[derive(Serialize)]
pub struct Cargo<'a> {
- stage: u32,
- target: &'a str,
+ pub stage: u32,
+ pub target: &'a str,
}
impl<'a> Step<'a> for Cargo<'a> {
// Prepare the image directory
t!(fs::create_dir_all(image.join("share/zsh/site-functions")));
t!(fs::create_dir_all(image.join("etc/bash_completion.d")));
- let cargo = build.cargo_out(&compiler, Mode::Tool, target)
+ let cargo = build.cargo_out(compiler, Mode::Tool, target)
.join(exe("cargo", target));
install(&cargo, &image.join("bin"), 0o755);
for man in t!(etc.join("man").read_dir()) {
t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes()));
// Generate the installer tarball
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
// .run(move |s| dist::rls(build, s.stage, s.target));
#[derive(Serialize)]
pub struct Rls<'a> {
- stage: u32,
- target: &'a str,
+ pub stage: u32,
+ pub target: &'a str,
}
impl<'a> Step<'a> for Rls<'a> {
t!(fs::create_dir_all(&image));
// Prepare the image directory
- let rls = build.cargo_out(&compiler, Mode::Tool, target)
+ let rls = build.cargo_out(compiler, Mode::Tool, target)
.join(exe("rls", target));
install(&rls, &image.join("bin"), 0o755);
let doc = image.join("share/doc/rls");
t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes()));
// Generate the installer tarball
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("generate")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
path.ends_with("cargo")
}
- fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
+ fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
if path.is_none() && !builder.build.config.extended {
return;
}
builder.ensure(Extended {
- compiler: builder.compiler(builder.top_stage, host),
+ stage: builder.top_stage,
target: target,
});
}
let compiler = builder.compiler(stage, &build.build);
builder.ensure(Std { compiler, target });
- builder.ensure(Rustc { stage, host });
- builder.ensure(Mingw { host });
- builder.ensure(Docs { stage, host });
+ builder.ensure(Rustc { stage, host: target });
+ builder.ensure(Mingw { host: target });
+ builder.ensure(Docs { stage, host: target });
builder.ensure(Cargo { stage, target });
builder.ensure(Rls { stage, target });
builder.ensure(Analysis { compiler, target });
input_tarballs.push(tarball);
}
- let mut cmd = rust_installer(build);
+ let mut cmd = rust_installer(builder);
cmd.arg("combine")
.arg("--product-name=Rust")
.arg("--rel-manifest-dir=rustlib")
use std::path::Path;
use std::process::Command;
-use {Build, Compiler, Mode};
+use Mode;
use util::{cp_r, symlink_dir};
use build_helper::up_to_date;
+use builder::{Builder, Step};
+use tool::Tool;
+use compile;
+
macro_rules! book {
($($name:ident, $path:expr, $book_name:expr;)+) => {
$(
impl<'a> Step<'a> for $name<'a> {
type Output = ();
- const NAME: &'static str = concat!(stringify!($book_name), " - book");
const DEFAULT: bool = true;
fn should_run(_builder: &Builder, path: &Path) -> bool {
);
#[derive(Serialize)]
-struct Rustbook<'a> {
+pub struct Rustbook<'a> {
target: &'a str,
name: &'a str,
}
impl<'a> Step<'a> for UnstableBook<'a> {
type Output = ();
- const NAME: &'static str = "unstable book documentation";
const DEFAULT: bool = true;
fn should_run(_builder: &Builder, path: &Path) -> bool {
// build the index page
let index = format!("{}/index.md", name);
println!("Documenting book index ({})", target);
- invoke_rustdoc(build, target, &index);
+ invoke_rustdoc(builder, target, &index);
// build the redirect pages
println!("Documenting book redirect pages ({})", target);
let path = file.path();
let path = path.to_str().unwrap();
- invoke_rustdoc(build, target, path);
+ invoke_rustdoc(builder, target, path);
}
}
}
-fn invoke_rustdoc(build: &Build, target: &str, markdown: &str) {
+fn invoke_rustdoc(builder: &Builder, target: &str, markdown: &str) {
+ let build = builder.build;
let out = build.doc_out(target);
- let compiler = Compiler::new(0, &build.build);
+ let compiler = builder.compiler(0, &build.build);
let path = build.src.join("src/doc").join(markdown);
- let rustdoc = build.rustdoc(&compiler);
+ let rustdoc = build.rustdoc(compiler);
let favicon = build.src.join("src/doc/favicon.inc");
let footer = build.src.join("src/doc/footer.inc");
let mut cmd = Command::new(&rustdoc);
- build.add_rustc_lib_path(&compiler, &mut cmd);
+ build.add_rustc_lib_path(compiler, &mut cmd);
let out = out.join("book");
}
let html = out.join(filename).with_extension("html");
- let rustdoc = build.rustdoc(&compiler);
+ let rustdoc = build.rustdoc(compiler);
if up_to_date(&path, &html) &&
up_to_date(&footer, &html) &&
up_to_date(&favicon, &html) &&
}
let mut cmd = Command::new(&rustdoc);
- build.add_rustc_lib_path(&compiler, &mut cmd);
+ build.add_rustc_lib_path(compiler, &mut cmd);
cmd.arg("--html-after-content").arg(&footer)
.arg("--html-before-content").arg(&version_info)
.arg("--html-in-header").arg(&favicon)
};
builder.ensure(compile::Std { compiler, target });
- let out_dir = build.stage_out(&compiler, Mode::Libstd)
+ let out_dir = build.stage_out(compiler, Mode::Libstd)
.join(target).join("doc");
- let rustdoc = build.rustdoc(&compiler);
+ let rustdoc = build.rustdoc(compiler);
// Here what we're doing is creating a *symlink* (directory junction on
// Windows) to the final output location. This is not done as an
build.clear_if_dirty(&my_out, &rustdoc);
t!(symlink_dir_force(&my_out, &out_dir));
- let mut cargo = build.cargo(&compiler, Mode::Libstd, target, "doc");
+ let mut cargo = build.cargo(compiler, Mode::Libstd, target, "doc");
cargo.arg("--manifest-path")
.arg(build.src.join("src/libstd/Cargo.toml"))
.arg("--features").arg(build.std_features());
#[derive(Serialize)]
pub struct Test<'a> {
stage: u32,
- test: &'a str,
+ target: &'a str,
}
impl<'a> Step<'a> for Test<'a> {
builder.ensure(Std { stage, target });
builder.ensure(compile::Test { compiler, target });
- let out_dir = build.stage_out(&compiler, Mode::Libtest)
+ let out_dir = build.stage_out(compiler, Mode::Libtest)
.join(target).join("doc");
- let rustdoc = build.rustdoc(&compiler);
+ let rustdoc = build.rustdoc(compiler);
// See docs in std above for why we symlink
let my_out = build.crate_doc_out(target);
build.clear_if_dirty(&my_out, &rustdoc);
t!(symlink_dir_force(&my_out, &out_dir));
- let mut cargo = build.cargo(&compiler, Mode::Libtest, target, "doc");
+ let mut cargo = build.cargo(compiler, Mode::Libtest, target, "doc");
cargo.arg("--manifest-path")
.arg(build.src.join("src/libtest/Cargo.toml"));
build.run(&mut cargo);
builder.ensure(Std { stage, target });
builder.ensure(compile::Rustc { compiler, target });
- let out_dir = build.stage_out(&compiler, Mode::Librustc)
+ let out_dir = build.stage_out(compiler, Mode::Librustc)
.join(target).join("doc");
- let rustdoc = build.rustdoc(&compiler);
+ let rustdoc = build.rustdoc(compiler);
// See docs in std above for why we symlink
let my_out = build.crate_doc_out(target);
build.clear_if_dirty(&my_out, &rustdoc);
t!(symlink_dir_force(&my_out, &out_dir));
- let mut cargo = build.cargo(&compiler, Mode::Librustc, target, "doc");
+ let mut cargo = build.cargo(compiler, Mode::Librustc, target, "doc");
cargo.arg("--manifest-path")
.arg(build.src.join("src/rustc/Cargo.toml"))
.arg("--features").arg(build.rustc_features());
/// Generates the HTML rendered error-index by running the
/// `error_index_generator` tool.
fn run(self, builder: &Builder) {
- let builder = builder.build;
+ let build = builder.build;
let target = self.target;
builder.ensure(compile::Rustc {
println!("Documenting error index ({})", target);
let out = build.doc_out(target);
t!(fs::create_dir_all(&out));
- let compiler = Compiler::new(0, &build.build);
let mut index = builder.tool_cmd(Tool::ErrorIndex);
index.arg("html");
index.arg(out.join("error-index.html"));
let out = build.md_doc_out(target).join("unstable-book");
t!(fs::create_dir_all(&out));
t!(fs::remove_dir_all(&out));
- let compiler = Compiler::new(0, &build.build);
- let mut cmd = build.tool_cmd(&compiler, "unstable-book-gen");
+ let mut cmd = builder.tool_cmd(Tool::UnstableBookGen);
cmd.arg(build.src.join("src"));
cmd.arg(out);
use Build;
use config::Config;
use metadata;
-use step;
/// Deserialized version of all flags for this compile.
pub struct Flags {
config.build = flags.build.clone();
let mut build = Build::new(flags, config);
metadata::build(&mut build);
- let maybe_rules_help = step::build_rules(&build).get_help(subcommand);
- if maybe_rules_help.is_some() {
- extra_help.push_str(maybe_rules_help.unwrap().as_str());
- }
+
+ // FIXME: How should this happen now? Not super clear...
+ // let maybe_rules_help = step::build_rules(&build).get_help(subcommand);
+ // if maybe_rules_help.is_some() {
+ // extra_help.push_str(maybe_rules_help.unwrap().as_str());
+ // }
} else {
extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
subcommand).as_str());
use std::path::{Path, PathBuf, Component};
use std::process::Command;
+use dist::{self, pkgname, sanitize_sh, tmpdir};
+
use Build;
-use dist::{pkgname, sanitize_sh, tmpdir};
+use builder::{Builder, Step};
pub struct Installer<'a> {
build: &'a Build,
impl<'a> Step<'a> for $name<'a> {
type Output = ();
- const NAME: &'static str = concat!("install ", stringify!($name));
const DEFAULT: bool = true;
const ONLY_BUILD_TARGETS: bool = true;
const ONLY_HOSTS: bool = $only_hosts;
//! also check out the `src/bootstrap/README.md` file for more information.
#![deny(warnings)]
+#![feature(associated_consts)]
+#![feature(core_intrinsics)]
#[macro_use]
extern crate build_helper;
+#[macro_use]
+extern crate serde_derive;
+extern crate serde;
+extern crate serde_json;
extern crate cmake;
extern crate filetime;
extern crate gcc;
use std::cell::Cell;
use std::cmp;
-use std::collections::HashMap;
+use std::collections::{HashSet, HashMap};
use std::env;
-use std::ffi::OsString;
use std::fs::{self, File};
use std::io::Read;
use std::path::{PathBuf, Path};
use util::{exe, libdir, add_lib_path, OutputFolder, CiEnv};
-use builder::Builder;
-
mod cc;
mod channel;
mod check;
mod sanity;
pub mod util;
mod builder;
+mod cache;
+mod tool;
#[cfg(windows)]
mod job;
/// Each compiler has a `stage` that it is associated with and a `host` that
/// corresponds to the platform the compiler runs on. This structure is used as
/// a parameter to many methods below.
-#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
+#[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Copy, Hash, Debug)]
pub struct Compiler<'a> {
stage: u32,
host: &'a str,
///
/// These entries currently correspond to the various output directories of the
/// build system, with each mod generating output in a different directory.
-#[derive(Clone, Copy, PartialEq, Eq)]
+#[derive(Serialize, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
/// Build the standard library, placing output in the "stageN-std" directory.
Libstd,
}
}
- fn build_slice(&self) -> &[String] {
- unsafe {
- std::slice::from_raw_parts(&self.build, 1)
- }
- }
-
/// Executes the entire build, as configured by the flags and configuration.
pub fn build(&mut self) {
unsafe {
self.verbose("learning about cargo");
metadata::build(self);
- step::run(self);
+ builder::Builder::run(&self);
}
/// Clear out `dir` if `input` is newer.
/// it will pass the `--target` flag for the specified `target`, and will be
/// executing the Cargo command `cmd`.
fn cargo(&self,
- compiler: &Compiler,
+ compiler: Compiler,
mode: Mode,
target: &str,
cmd: &str) -> Command {
}
/// Get a path to the compiler specified.
- fn compiler_path(&self, compiler: &Compiler) -> PathBuf {
+ fn compiler_path(&self, compiler: Compiler) -> PathBuf {
if compiler.is_snapshot(self) {
self.initial_rustc.clone()
} else {
}
/// Get the specified tool built by the specified compiler
- fn tool(&self, compiler: &Compiler, tool: &str) -> PathBuf {
+ fn tool(&self, compiler: Compiler, tool: &str) -> PathBuf {
self.cargo_out(compiler, Mode::Tool, compiler.host)
.join(exe(tool, compiler.host))
}
/// Get the `rustdoc` executable next to the specified compiler
- fn rustdoc(&self, compiler: &Compiler) -> PathBuf {
+ fn rustdoc(&self, compiler: Compiler) -> PathBuf {
let mut rustdoc = self.compiler_path(compiler);
rustdoc.pop();
rustdoc.push(exe("rustdoc", compiler.host));
/// Get a `Command` which is ready to run `tool` in `stage` built for
/// `host`.
- fn tool_cmd(&self, compiler: &Compiler, tool: &str) -> Command {
- let mut cmd = Command::new(self.tool(&compiler, tool));
+ fn tool_cmd(&self, compiler: Compiler, tool: &str) -> Command {
+ let mut cmd = Command::new(self.tool(compiler, tool));
self.prepare_tool_cmd(compiler, &mut cmd);
cmd
}
///
/// Notably this munges the dynamic library lookup path to point to the
/// right location to run `compiler`.
- fn prepare_tool_cmd(&self, compiler: &Compiler, cmd: &mut Command) {
+ fn prepare_tool_cmd(&self, compiler: Compiler, cmd: &mut Command) {
let host = compiler.host;
let mut paths = vec![
self.sysroot_libdir(compiler, compiler.host),
if self.config.rust_optimize {"release"} else {"debug"}
}
- /// Returns the sysroot for the `compiler` specified that *this build system
- /// generates*.
- ///
- /// That is, the sysroot for the stage0 compiler is not what the compiler
- /// thinks it is by default, but it's the same as the default for stages
- /// 1-3.
- fn sysroot(&self, compiler: &Compiler) -> PathBuf {
- if compiler.stage == 0 {
- self.out.join(compiler.host).join("stage0-sysroot")
- } else {
- self.out.join(compiler.host).join(format!("stage{}", compiler.stage))
- }
- }
-
/// Get the directory for incremental by-products when using the
/// given compiler.
- fn incremental_dir(&self, compiler: &Compiler) -> PathBuf {
+ fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
self.out.join(compiler.host).join(format!("stage{}-incremental", compiler.stage))
}
/// stage when running with a particular host compiler.
///
/// The mode indicates what the root directory is for.
- fn stage_out(&self, compiler: &Compiler, mode: Mode) -> PathBuf {
+ fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
let suffix = match mode {
Mode::Libstd => "-std",
Mode::Libtest => "-test",
/// running a particular compiler, wehther or not we're building the
/// standard library, and targeting the specified architecture.
fn cargo_out(&self,
- compiler: &Compiler,
+ compiler: Compiler,
mode: Mode,
target: &str) -> PathBuf {
self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
self.native_dir(target).join("rust-test-helpers")
}
- /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic
- /// library lookup path.
- fn add_rustc_lib_path(&self, compiler: &Compiler, cmd: &mut Command) {
- // Windows doesn't need dylib path munging because the dlls for the
- // compiler live next to the compiler and the system will find them
- // automatically.
- if cfg!(windows) {
- return
- }
-
- add_lib_path(vec![self.rustc_libdir(compiler)], cmd);
- }
-
/// Adds the `RUST_TEST_THREADS` env var if necessary
fn add_rust_test_threads(&self, cmd: &mut Command) {
if env::var_os("RUST_TEST_THREADS").is_none() {
///
/// For example this returns `<sysroot>/lib` on Unix and `<sysroot>/bin` on
/// Windows.
- fn rustc_libdir(&self, compiler: &Compiler) -> PathBuf {
+ fn rustc_libdir(&self, compiler: Compiler) -> PathBuf {
if compiler.is_snapshot(self) {
self.rustc_snapshot_libdir()
} else {
///
/// When all of these conditions are met the build will lift artifacts from
/// the previous stage forward.
- fn force_use_stage1(&self, compiler: &Compiler, target: &str) -> bool {
+ fn force_use_stage1(&self, compiler: Compiler, target: &str) -> bool {
!self.config.full_bootstrap &&
compiler.stage >= 2 &&
self.config.host.iter().any(|h| h == target)
}
/// Returns whether this is a snapshot compiler for `build`'s configuration
- pub fn is_snapshot(&self, builder: &Build) -> bool {
+ pub fn is_snapshot(&self, build: &Build) -> bool {
self.stage == 0 && self.host == build.build
}
use Build;
use util;
use build_helper::up_to_date;
+use builder::{Builder, Step};
// rules.build("llvm", "src/llvm")
// .host(true)
#[derive(Serialize)]
pub struct TestHelpers<'a> {
- target: &'a str,
+ pub target: &'a str,
}
impl<'a> Step<'a> for TestHelpers<'a> {
}
fn run(self, builder: &Builder) {
- let build = bulder.build;
+ let build = builder.build;
let target = self.target;
let out = match build.openssl_dir(target) {
Some(dir) => dir,
let compiler = builder.compiler(stage, &build.build);
let stamp = match mode {
- Mode::Libstd => libstd_stamp(build, &compiler, target),
- Mode::Libtest => libtest_stamp(build, &compiler, target),
- Mode::Librustc => librustc_stamp(build, &compiler, target),
+ Mode::Libstd => libstd_stamp(build, compiler, target),
+ Mode::Libtest => libtest_stamp(build, compiler, target),
+ Mode::Librustc => librustc_stamp(build, compiler, target),
_ => panic!(),
};
- let out_dir = build.cargo_out(&compiler, Mode::Tool, target);
+ let out_dir = build.cargo_out(compiler, Mode::Tool, target);
build.clear_if_dirty(&out_dir, &stamp);
}
}
let _folder = build.fold_output(|| format!("stage{}-{}", stage, tool));
println!("Building stage{} tool {} ({})", stage, tool, target);
- let mut cargo = build.cargo(&compiler, Mode::Tool, target, "build");
+ let mut cargo = build.cargo(compiler, Mode::Tool, target, "build");
let dir = build.src.join("src/tools").join(tool);
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
impl<'a> Step<'a> for $name<'a> {
type Output = PathBuf;
- const NAME: &'static str = concat!(stringify!($name), " tool");
fn should_run(_builder: &Builder, path: &Path) -> bool {
path.ends_with($path)
// .dep(|s| s.name("maybe-clean-tools"))
// .dep(|s| s.name("libstd-tool"))
// .run(move |s| compile::tool(build, s.stage, s.target, "unstable-book-gen"));
- UnstableBook, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
+ UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
// rules.build("tool-tidy", "src/tools/tidy")
// .dep(|s| s.name("maybe-clean-tools"))
// .dep(|s| s.name("libstd-tool"))
impl<'a> Step<'a> for Cargo<'a> {
type Output = PathBuf;
- const NAME: &'static str = "cargo tool";
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;
impl<'a> Step<'a> for Rls<'a> {
type Output = PathBuf;
- const NAME: &'static str = "RLS tool";
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;