about summary refs log tree commit diff
path: root/src/bootstrap/build
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2016-05-02 15:16:15 -0700
committerAlex Crichton <alex@alexcrichton.com>2016-05-03 15:15:27 -0700
commitf72bfe6661b35fd012fee100c673dafd1aec15f7 (patch)
tree6ea314f4f4021214ade02b7d3bf28123d0d6ed8e /src/bootstrap/build
parentd80497e628945c3f11ff351030b4c62a8533e01e (diff)
downloadrust-f72bfe6661b35fd012fee100c673dafd1aec15f7.tar.gz
rust-f72bfe6661b35fd012fee100c673dafd1aec15f7.zip
rustbuild: Document many more parts of the build
This commit expands the bootstrap build system's `README.md` as well as ensuring
that all API documentation is present and up-to-date. Additionally a new
`config.toml.example` file is checked in with commented out versions of all
possible configuration values.
Diffstat (limited to 'src/bootstrap/build')
-rw-r--r--src/bootstrap/build/cc.rs23
-rw-r--r--src/bootstrap/build/channel.rs21
-rw-r--r--src/bootstrap/build/check.rs43
-rw-r--r--src/bootstrap/build/clean.rs7
-rw-r--r--src/bootstrap/build/compile.rs11
-rw-r--r--src/bootstrap/build/config.rs14
-rw-r--r--src/bootstrap/build/dist.rs24
-rw-r--r--src/bootstrap/build/doc.rs36
-rw-r--r--src/bootstrap/build/flags.rs6
-rw-r--r--src/bootstrap/build/mod.rs161
-rw-r--r--src/bootstrap/build/native.rs17
-rw-r--r--src/bootstrap/build/sanity.rs10
-rw-r--r--src/bootstrap/build/step.rs40
-rw-r--r--src/bootstrap/build/util.rs20
14 files changed, 407 insertions, 26 deletions
diff --git a/src/bootstrap/build/cc.rs b/src/bootstrap/build/cc.rs
index 9f962e9d9e6..d0b0f1007c6 100644
--- a/src/bootstrap/build/cc.rs
+++ b/src/bootstrap/build/cc.rs
@@ -8,6 +8,29 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! C-compiler probing and detection.
+//!
+//! This module will fill out the `cc` and `cxx` maps of `Build` by looking for
+//! C and C++ compilers for each target configured. A compiler is found through
+//! a number of vectors (in order of precedence)
+//!
+//! 1. Configuration via `target.$target.cc` in `config.toml`.
+//! 2. Configuration via `target.$target.android-ndk` in `config.toml`, if
+//!    applicable
+//! 3. Special logic to probe on OpenBSD
+//! 4. The `CC_$target` environment variable.
+//! 5. The `CC` environment variable.
+//! 6. "cc"
+//!
+//! Some of this logic is implemented here, but much of it is farmed out to the
+//! `gcc` crate itself, so we end up having the same fallbacks as there.
+//! Similar logic is then used to find a C++ compiler, just some s/cc/c++/ is
+//! used.
+//!
+//! It is intended that after this module has run no C/C++ compiler will
+//! ever be probed for. Instead the compilers found here will be used for
+//! everything.
+
 use std::process::Command;
 
 use build_helper::{cc2ar, output};
diff --git a/src/bootstrap/build/channel.rs b/src/bootstrap/build/channel.rs
index 48dfbfdd90d..76d061eb43e 100644
--- a/src/bootstrap/build/channel.rs
+++ b/src/bootstrap/build/channel.rs
@@ -8,7 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::env;
+//! Build configuration for Rust's release channels.
+//!
+//! Implements the stable/beta/nightly channel distinctions by setting various
+//! flags like the `unstable_features`, calculating variables like `release` and
+//! `package_vers`, and otherwise indicating to the compiler what it should
+//! print out as part of its version information.
+
 use std::fs::{self, File};
 use std::io::prelude::*;
 use std::process::Command;
@@ -19,6 +25,9 @@ use md5;
 use build::Build;
 
 pub fn collect(build: &mut Build) {
+    // Currently the canonical source for the release number (e.g. 1.10.0) and
+    // the prerelease version (e.g. `.1`) is in `mk/main.mk`. We "parse" that
+    // here to learn about those numbers.
     let mut main_mk = String::new();
     t!(t!(File::open(build.src.join("mk/main.mk"))).read_to_string(&mut main_mk));
     let mut release_num = "";
@@ -32,7 +41,8 @@ pub fn collect(build: &mut Build) {
         }
     }
 
-    // FIXME: this is duplicating makefile logic
+    // Depending on the channel, passed in `./configure --release-channel`,
+    // determine various properties of the build.
     match &build.config.channel[..] {
         "stable" => {
             build.release = release_num.to_string();
@@ -58,6 +68,8 @@ pub fn collect(build: &mut Build) {
     }
     build.version = build.release.clone();
 
+    // If we have a git directory, add in some various SHA information of what
+    // commit this compiler was compiled from.
     if fs::metadata(build.src.join(".git")).is_ok() {
         let ver_date = output(Command::new("git").current_dir(&build.src)
                                       .arg("log").arg("-1")
@@ -80,11 +92,14 @@ pub fn collect(build: &mut Build) {
         build.short_ver_hash = Some(short_ver_hash);
     }
 
+    // Calculate this compiler's bootstrap key, which is currently defined as
+    // the first 8 characters of the md5 of the release string.
     let key = md5::compute(build.release.as_bytes());
     build.bootstrap_key = format!("{:02x}{:02x}{:02x}{:02x}",
                                   key[0], key[1], key[2], key[3]);
-    env::set_var("RUSTC_BOOTSTRAP_KEY", &build.bootstrap_key);
 
+    // Slurp up the stage0 bootstrap key as we're bootstrapping from an
+    // otherwise stable compiler.
     let mut s = String::new();
     t!(t!(File::open(build.src.join("src/stage0.txt"))).read_to_string(&mut s));
     if let Some(line) = s.lines().find(|l| l.starts_with("rustc_key")) {
diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs
index a376b021a8a..1e519c62bc5 100644
--- a/src/bootstrap/build/check.rs
+++ b/src/bootstrap/build/check.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of the various `check-*` targets of the build system.
+//!
+//! This file implements the various regression test suites that we execute on
+//! our CI.
+
 use std::fs;
 use std::path::{PathBuf, Path};
 use std::process::Command;
@@ -16,6 +21,10 @@ use build_helper::output;
 
 use build::{Build, Compiler};
 
+/// 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
+/// documentation to ensure we don't have a bunch of dead ones.
 pub fn linkcheck(build: &Build, stage: u32, host: &str) {
     println!("Linkcheck stage{} ({})", stage, host);
     let compiler = Compiler::new(stage, host);
@@ -23,8 +32,11 @@ pub fn linkcheck(build: &Build, stage: u32, host: &str) {
                    .arg(build.out.join(host).join("doc")));
 }
 
+/// Runs the `cargotest` tool as compiled in `stage` by the `host` compiler.
+///
+/// This tool in `src/tools` will check out a few Rust projects and run `cargo
+/// test` to ensure that we don't regress the test suites there.
 pub fn cargotest(build: &Build, stage: u32, host: &str) {
-
     let ref compiler = Compiler::new(stage, host);
 
     // Configure PATH to find the right rustc. NB. we have to use PATH
@@ -47,6 +59,11 @@ pub fn cargotest(build: &Build, stage: u32, host: &str) {
                    .arg(&out_dir));
 }
 
+/// Runs the `tidy` tool as compiled in `stage` by the `host` compiler.
+///
+/// This tool in `src/tools` checks up on various bits and pieces of style and
+/// otherwise just implements a few lint-like checks that are specific to the
+/// compiler itself.
 pub fn tidy(build: &Build, stage: u32, host: &str) {
     println!("tidy check stage{} ({})", stage, host);
     let compiler = Compiler::new(stage, host);
@@ -58,6 +75,11 @@ fn testdir(build: &Build, host: &str) -> PathBuf {
     build.out.join(host).join("test")
 }
 
+/// Executes the `compiletest` tool to run a suite of tests.
+///
+/// Compiles all tests with `compiler` for `target` with the specified
+/// compiletest `mode` and `suite` arguments. For example `mode` can be
+/// "run-pass" or `suite` can be something like `debuginfo`.
 pub fn compiletest(build: &Build,
                    compiler: &Compiler,
                    target: &str,
@@ -65,6 +87,9 @@ pub fn compiletest(build: &Build,
                    suite: &str) {
     let mut cmd = build.tool_cmd(compiler, "compiletest");
 
+    // compiletest currently has... a lot of arguments, so let's just pass all
+    // 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("--rustc-path").arg(build.compiler_path(compiler));
@@ -114,6 +139,8 @@ pub fn compiletest(build: &Build,
         cmd.arg("--verbose");
     }
 
+    // Only pass correct values for these flags for the `run-make` suite as it
+    // requires that a C++ compiler was configured which isn't always the case.
     if suite == "run-make" {
         let llvm_config = build.llvm_config(target);
         let llvm_components = output(Command::new(&llvm_config).arg("--components"));
@@ -140,11 +167,19 @@ pub fn compiletest(build: &Build,
             }
         }
     }
+    build.add_bootstrap_key(compiler, &mut cmd);
 
     build.run(&mut cmd);
 }
 
+/// Run `rustdoc --test` for all documentation in `src/doc`.
+///
+/// This will run all tests in our markdown documentation (e.g. the book)
+/// located in `src/doc`. The `rustdoc` that's run is the one that sits next to
+/// `compiler`.
 pub fn docs(build: &Build, compiler: &Compiler) {
+    // Do a breadth-first traversal of the `src/doc` directory and just run
+    // tests for all files that end in `*.md`
     let mut stack = vec![build.src.join("src/doc")];
 
     while let Some(p) = stack.pop() {
@@ -162,6 +197,12 @@ pub fn docs(build: &Build, compiler: &Compiler) {
     }
 }
 
+/// Run the error index generator tool to execute the tests located in the error
+/// index.
+///
+/// The `error_index_generator` tool lives in `src/tools` and is used to
+/// generate a markdown file from the error indexes of the code base which is
+/// then passed to `rustdoc --test`.
 pub fn error_index(build: &Build, compiler: &Compiler) {
     println!("Testing error-index stage{}", compiler.stage);
 
diff --git a/src/bootstrap/build/clean.rs b/src/bootstrap/build/clean.rs
index 1f6538f5eae..1d407c94132 100644
--- a/src/bootstrap/build/clean.rs
+++ b/src/bootstrap/build/clean.rs
@@ -8,6 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of `make clean` in rustbuild.
+//!
+//! Responsible for cleaning out a build directory of all old and stale
+//! artifacts to prepare for a fresh build. Currently doesn't remove the
+//! `build/cache` directory (download cache) or the `build/$target/llvm`
+//! directory as we want that cached between builds.
+
 use std::fs;
 use std::path::Path;
 
diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs
index fbdf49fb3d7..5ed9c1c18c2 100644
--- a/src/bootstrap/build/compile.rs
+++ b/src/bootstrap/build/compile.rs
@@ -8,6 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of compiling various phases of the compiler and standard
+//! library.
+//!
+//! This module contains some of the real meat in the rustbuild build system
+//! which is where Cargo is used to compiler the standard library, libtest, and
+//! compiler. This module is also responsible for assembling the sysroot as it
+//! goes along from the output of the previous stage.
+
 use std::collections::HashMap;
 use std::fs;
 use std::path::{Path, PathBuf};
@@ -35,6 +43,8 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
     copy(&build.compiler_rt_built.borrow()[target],
          &libdir.join(staticlib("compiler-rt", target)));
 
+    // Some platforms have startup objects that may be required to produce the
+    // libstd dynamic library, for example.
     build_startup_objects(build, target, &libdir);
 
     let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
@@ -154,7 +164,6 @@ pub fn test_link(build: &Build,
     add_to_sysroot(&out_dir, &libdir);
 }
 
-
 /// Build the compiler.
 ///
 /// This will build the compiler for a particular stage of the build using
diff --git a/src/bootstrap/build/config.rs b/src/bootstrap/build/config.rs
index 98fdaae64a5..f75728cf040 100644
--- a/src/bootstrap/build/config.rs
+++ b/src/bootstrap/build/config.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Serialized configuration of a build.
+//!
+//! This module implements parsing `config.mk` and `config.toml` configuration
+//! files to tweak how the build runs.
+
 use std::collections::HashMap;
 use std::env;
 use std::fs::File;
@@ -27,7 +32,9 @@ use toml::{Parser, Decoder, Value};
 /// is generated from `./configure`.
 ///
 /// Note that this structure is not decoded directly into, but rather it is
-/// filled out from the decoded forms of the structs below.
+/// filled out from the decoded forms of the structs below. For documentation
+/// each field, see the corresponding fields in
+/// `src/bootstrap/config.toml.example`.
 #[derive(Default)]
 pub struct Config {
     pub ccache: bool,
@@ -250,6 +257,11 @@ impl Config {
         return config
     }
 
+    /// "Temporary" routine to parse `config.mk` into this configuration.
+    ///
+    /// While we still have `./configure` this implements the ability to decode
+    /// that configuration into this. This isn't exactly a full-blown makefile
+    /// parser, but hey it gets the job done!
     pub fn update_with_config_mk(&mut self) {
         let mut config = String::new();
         File::open("config.mk").unwrap().read_to_string(&mut config).unwrap();
diff --git a/src/bootstrap/build/dist.rs b/src/bootstrap/build/dist.rs
index f2e3117fa97..dd1cf27c982 100644
--- a/src/bootstrap/build/dist.rs
+++ b/src/bootstrap/build/dist.rs
@@ -8,6 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of the various distribution aspects of the compiler.
+//!
+//! This module is responsible for creating tarballs of the standard library,
+//! compiler, and documentation. This ends up being what we distribute to
+//! everyone as well.
+//!
+//! No tarball is actually created literally in this file, but rather we shell
+//! out to `rust-installer` still. This may one day be replaced with bits and
+//! pieces of `rustup.rs`!
+
 use std::fs::{self, File};
 use std::io::Write;
 use std::path::{PathBuf, Path};
@@ -33,6 +43,9 @@ fn tmpdir(build: &Build) -> PathBuf {
     build.out.join("tmp/dist")
 }
 
+/// Builds the `rust-docs` installer component.
+///
+/// Slurps up documentation from the `stage`'s `host`.
 pub fn docs(build: &Build, stage: u32, host: &str) {
     println!("Dist docs stage{} ({})", stage, host);
     let name = format!("rust-docs-{}", package_vers(build));
@@ -68,6 +81,12 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
     }
 }
 
+/// Build the `rust-mingw` installer component.
+///
+/// This contains all the bits and pieces to run the MinGW Windows targets
+/// without any extra installed software (e.g. we bundle gcc, libraries, etc).
+/// Currently just shells out to a python script, but that should be rewritten
+/// in Rust.
 pub fn mingw(build: &Build, host: &str) {
     println!("Dist mingw ({})", host);
     let name = format!("rust-mingw-{}", package_vers(build));
@@ -102,6 +121,7 @@ pub fn mingw(build: &Build, host: &str) {
     t!(fs::remove_dir_all(&image));
 }
 
+/// Creates the `rustc` installer component.
 pub fn rustc(build: &Build, stage: u32, host: &str) {
     println!("Dist rustc stage{} ({})", stage, host);
     let name = format!("rustc-{}", package_vers(build));
@@ -209,6 +229,7 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
     }
 }
 
+/// Copies debugger scripts for `host` into the `sysroot` specified.
 pub fn debugger_scripts(build: &Build,
                         sysroot: &Path,
                         host: &str) {
@@ -237,7 +258,8 @@ pub fn debugger_scripts(build: &Build,
     }
 }
 
-
+/// Creates the `rust-std` installer component as compiled by `compiler` for the
+/// target `target`.
 pub fn std(build: &Build, compiler: &Compiler, target: &str) {
     println!("Dist std stage{} ({} -> {})", compiler.stage, compiler.host,
              target);
diff --git a/src/bootstrap/build/doc.rs b/src/bootstrap/build/doc.rs
index 5782dd5ec28..f7cc742277a 100644
--- a/src/bootstrap/build/doc.rs
+++ b/src/bootstrap/build/doc.rs
@@ -8,6 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Documentation generation for rustbuild.
+//!
+//! This module implements generation for all bits and pieces of documentation
+//! for the Rust project. This notably includes suites like the rust book, the
+//! nomicon, standalone documentation, etc.
+//!
+//! Everything here is basically just a shim around calling either `rustbook` or
+//! `rustdoc`.
+
 use std::fs::{self, File};
 use std::io::prelude::*;
 use std::path::Path;
@@ -16,6 +25,11 @@ use std::process::Command;
 use build::{Build, Compiler, Mode};
 use build::util::{up_to_date, cp_r};
 
+/// Invoke `rustbook` as compiled in `stage` for `target` for the doc book
+/// `name` into the `out` path.
+///
+/// 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));
 
@@ -35,6 +49,14 @@ pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str, out: &Path)
                    .arg(out));
 }
 
+/// Generates all standalone documentation as compiled by the rustdoc in `stage`
+/// for the `target` into `out`.
+///
+/// This will list all of `src/doc` looking for markdown files and appropriately
+/// perform transformations like substituting `VERSION`, `SHORT_HASH`, and
+/// `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) {
     println!("Documenting stage{} standalone ({})", stage, target);
     t!(fs::create_dir_all(out));
@@ -105,6 +127,10 @@ pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) {
     }
 }
 
+/// Compile all standard library documentation.
+///
+/// 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) {
     println!("Documenting stage{} std ({})", stage, target);
     t!(fs::create_dir_all(out));
@@ -123,6 +149,10 @@ pub fn std(build: &Build, stage: u32, target: &str, out: &Path) {
     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) {
     println!("Documenting stage{} test ({})", stage, target);
     let compiler = Compiler::new(stage, &build.config.build);
@@ -139,6 +169,10 @@ pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
     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) {
     println!("Documenting stage{} compiler ({})", stage, target);
     let compiler = Compiler::new(stage, &build.config.build);
@@ -156,6 +190,8 @@ pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) {
     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) {
     println!("Documenting stage{} error index ({})", stage, target);
     t!(fs::create_dir_all(out));
diff --git a/src/bootstrap/build/flags.rs b/src/bootstrap/build/flags.rs
index 67f33e29cae..d925997f36c 100644
--- a/src/bootstrap/build/flags.rs
+++ b/src/bootstrap/build/flags.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Command-line interface of the rustbuild build system.
+//!
+//! This module implements the command-line parsing of the build system which
+//! has various flags to configure how it's run.
+
 use std::fs;
 use std::path::PathBuf;
 use std::process;
@@ -15,6 +20,7 @@ use std::slice;
 
 use getopts::Options;
 
+/// Deserialized version of all flags for this compile.
 pub struct Flags {
     pub verbose: bool,
     pub stage: Option<u32>,
diff --git a/src/bootstrap/build/mod.rs b/src/bootstrap/build/mod.rs
index 97be285ce01..b38532fb3df 100644
--- a/src/bootstrap/build/mod.rs
+++ b/src/bootstrap/build/mod.rs
@@ -8,6 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of rustbuild, the Rust build system.
+//!
+//! This module, and its descendants, are the implementation of the Rust build
+//! system. Most of this build system is backed by Cargo but the outer layer
+//! here serves as the ability to orchestrate calling Cargo, sequencing Cargo
+//! builds, building artifacts like LLVM, etc.
+//!
+//! More documentation can be found in each respective module below.
+
 use std::cell::RefCell;
 use std::collections::HashMap;
 use std::env;
@@ -21,6 +30,14 @@ use num_cpus;
 
 use build::util::{exe, mtime, libdir, add_lib_path};
 
+/// A helper macro to `unwrap` a result except also print out details like:
+///
+/// * The file/line of the panic
+/// * The expression that failed
+/// * The error itself
+///
+/// This is currently used judiciously throughout the build system rather than
+/// using a `Result` with `try!`, but this may change on day...
 macro_rules! t {
     ($e:expr) => (match $e {
         Ok(e) => e,
@@ -53,12 +70,27 @@ mod job {
 pub use build::config::Config;
 pub use build::flags::Flags;
 
+/// A structure representing a Rust compiler.
+///
+/// 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)]
 pub struct Compiler<'a> {
     stage: u32,
     host: &'a str,
 }
 
+/// Global configuration for the build system.
+///
+/// This structure transitively contains all configuration for the build system.
+/// All filesystem-encoded configuration is in `config`, all flags are in
+/// `flags`, and then parsed or probed information is listed in the keys below.
+///
+/// This structure is a parameter of almost all methods in the build system,
+/// although most functions are implemented as free functions rather than
+/// methods specifically on this structure itself (to make it easier to
+/// organize).
 pub struct Build {
     // User-specified configuration via config.toml
     config: Config,
@@ -92,14 +124,33 @@ pub struct Build {
     compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
 }
 
+/// The various "modes" of invoking Cargo.
+///
+/// These entries currently correspond to the various output directories of the
+/// build system, with each mod generating output in a different directory.
 pub enum Mode {
+    /// This cargo is going to build the standard library, placing output in the
+    /// "stageN-std" directory.
     Libstd,
+
+    /// This cargo is going to build libtest, placing output in the
+    /// "stageN-test" directory.
     Libtest,
+
+    /// This cargo is going to build librustc and compiler libraries, placing
+    /// output in the "stageN-rustc" directory.
     Librustc,
+
+    /// This cargo is going to some build tool, placing output in the
+    /// "stageN-tools" directory.
     Tool,
 }
 
 impl Build {
+    /// Creates a new set of build configuration from the `flags` on the command
+    /// line and the filesystem `config`.
+    ///
+    /// By default all build output will be placed in the current directory.
     pub fn new(flags: Flags, config: Config) -> Build {
         let cwd = t!(env::current_dir());
         let src = flags.src.clone().unwrap_or(cwd.clone());
@@ -141,6 +192,7 @@ impl Build {
         }
     }
 
+    /// Executes the entire build, as configured by the flags and configuration.
     pub fn build(&mut self) {
         use build::step::Source::*;
 
@@ -161,6 +213,16 @@ impl Build {
         self.verbose("updating submodules");
         self.update_submodules();
 
+        // The main loop of the build system.
+        //
+        // The `step::all` function returns a topographically sorted list of all
+        // steps that need to be executed as part of this build. Each step has a
+        // corresponding entry in `step.rs` and indicates some unit of work that
+        // needs to be done as part of the build.
+        //
+        // Almost all of these are simple one-liners that shell out to the
+        // corresponding functionality in the extra modules, where more
+        // documentation can be found.
         for target in step::all(self) {
             let doc_out = self.out.join(&target.target).join("doc");
             match target.src {
@@ -338,6 +400,10 @@ impl Build {
         }
     }
 
+    /// Updates all git submodules that we have.
+    ///
+    /// This will detect if any submodules are out of date an run the necessary
+    /// commands to sync them all with upstream.
     fn update_submodules(&self) {
         if !self.config.submodules {
             return
@@ -350,6 +416,11 @@ impl Build {
             cmd.current_dir(&self.src).arg("submodule");
             return cmd
         };
+
+        // FIXME: this takes a seriously long time to execute on Windows and a
+        //        nontrivial amount of time on Unix, we should have a better way
+        //        of detecting whether we need to run all the submodule commands
+        //        below.
         let out = output(git_submodule().arg("status"));
         if !out.lines().any(|l| l.starts_with("+") || l.starts_with("-")) {
             return
@@ -366,8 +437,9 @@ impl Build {
                                 .arg("git").arg("checkout").arg("."));
     }
 
-    /// Clear out `dir` if our build has been flagged as dirty, and also set
-    /// ourselves as dirty if `file` changes when `f` is executed.
+    /// Clear out `dir` if `input` is newer.
+    ///
+    /// After this executes, it will also ensure that `dir` exists.
     fn clear_if_dirty(&self, dir: &Path, input: &Path) {
         let stamp = dir.join(".stamp");
         if mtime(&stamp) < mtime(input) {
@@ -381,8 +453,10 @@ impl Build {
     /// Prepares an invocation of `cargo` to be run.
     ///
     /// This will create a `Command` that represents a pending execution of
-    /// Cargo for the specified stage, whether or not the standard library is
-    /// being built, and using the specified compiler targeting `target`.
+    /// Cargo. This cargo will be configured to use `compiler` as the actual
+    /// rustc compiler, its output will be scoped by `mode`'s output directory,
+    /// it will pass the `--target` flag for the specified `target`, and will be
+    /// executing the Cargo command `cmd`.
     fn cargo(&self,
              compiler: &Compiler,
              mode: Mode,
@@ -398,6 +472,9 @@ impl Build {
         // Customize the compiler we're running. Specify the compiler to cargo
         // as our shim and then pass it some various options used to configure
         // how the actual compiler itself is called.
+        //
+        // These variables are primarily all read by
+        // src/bootstrap/{rustc,rustdoc.rs}
         cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
              .env("RUSTC_REAL", self.compiler_path(compiler))
              .env("RUSTC_STAGE", compiler.stage.to_string())
@@ -414,16 +491,7 @@ impl Build {
              .env("RUSTDOC_REAL", self.rustdoc(compiler))
              .env("RUSTC_FLAGS", self.rustc_flags(target).join(" "));
 
-        // Set the bootstrap key depending on which stage compiler we're using.
-        // In stage0 we're using a previously released stable compiler, so we
-        // use the stage0 bootstrap key. Otherwise we use our own build's
-        // bootstrap key.
-        let bootstrap_key = if compiler.is_snapshot(self) {
-            &self.bootstrap_key_stage0
-        } else {
-            &self.bootstrap_key
-        };
-        cargo.env("RUSTC_BOOTSTRAP_KEY", bootstrap_key);
+        self.add_bootstrap_key(compiler, &mut cargo);
 
         // Specify some various options for build scripts used throughout
         // the build.
@@ -443,7 +511,7 @@ impl Build {
 
         // Environment variables *required* needed throughout the build
         //
-        // FIXME: should update code to not require this env vars
+        // FIXME: should update code to not require this env var
         cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
 
         if self.config.verbose || self.flags.verbose {
@@ -522,6 +590,12 @@ impl Build {
         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")
@@ -530,6 +604,8 @@ impl Build {
         }
     }
 
+    /// Returns the libdir where the standard library and other artifacts are
+    /// found for a compiler's sysroot.
     fn sysroot_libdir(&self, compiler: &Compiler, target: &str) -> PathBuf {
         self.sysroot(compiler).join("lib").join("rustlib")
             .join(target).join("lib")
@@ -561,11 +637,17 @@ impl Build {
     }
 
     /// Root output directory for LLVM compiled for `target`
+    ///
+    /// Note that if LLVM is configured externally then the directory returned
+    /// will likely be empty.
     fn llvm_out(&self, target: &str) -> PathBuf {
         self.out.join(target).join("llvm")
     }
 
-    /// Returns the path to `llvm-config` for the specified target
+    /// Returns the path to `llvm-config` for the specified target.
+    ///
+    /// If a custom `llvm-config` was specified for target then that's returned
+    /// instead.
     fn llvm_config(&self, target: &str) -> PathBuf {
         let target_config = self.config.target_config.get(target);
         if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
@@ -576,7 +658,7 @@ impl Build {
         }
     }
 
-    /// Returns the path to `llvm-config` for the specified target
+    /// Returns the path to `FileCheck` binary for the specified target
     fn llvm_filecheck(&self, target: &str) -> PathBuf {
         let target_config = self.config.target_config.get(target);
         if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
@@ -603,15 +685,37 @@ impl Build {
         self.out.join(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 }
+        if cfg!(windows) {
+            return
+        }
 
         add_lib_path(vec![self.rustc_libdir(compiler)], cmd);
     }
 
+    /// Adds the compiler's bootstrap key to the environment of `cmd`.
+    fn add_bootstrap_key(&self, compiler: &Compiler, cmd: &mut Command) {
+        // In stage0 we're using a previously released stable compiler, so we
+        // use the stage0 bootstrap key. Otherwise we use our own build's
+        // bootstrap key.
+        let bootstrap_key = if compiler.is_snapshot(self) {
+            &self.bootstrap_key_stage0
+        } else {
+            &self.bootstrap_key
+        };
+        cmd.env("RUSTC_BOOTSTRAP_KEY", bootstrap_key);
+    }
+
+    /// Returns the compiler's libdir where it stores the dynamic libraries that
+    /// it itself links against.
+    ///
+    /// For example this returns `<sysroot>/lib` on Unix and `<sysroot>/bin` on
+    /// Windows.
     fn rustc_libdir(&self, compiler: &Compiler) -> PathBuf {
         if compiler.is_snapshot(self) {
             self.rustc_snapshot_libdir()
@@ -620,30 +724,38 @@ impl Build {
         }
     }
 
+    /// Returns the libdir of the snapshot compiler.
     fn rustc_snapshot_libdir(&self) -> PathBuf {
         self.rustc.parent().unwrap().parent().unwrap()
             .join(libdir(&self.config.build))
     }
 
+    /// Runs a command, printing out nice contextual information if it fails.
     fn run(&self, cmd: &mut Command) {
         self.verbose(&format!("running: {:?}", cmd));
         run_silent(cmd)
     }
 
+    /// Prints a message if this build is configured in verbose mode.
     fn verbose(&self, msg: &str) {
         if self.flags.verbose || self.config.verbose {
             println!("{}", msg);
         }
     }
 
+    /// Returns the number of parallel jobs that have been configured for this
+    /// build.
     fn jobs(&self) -> u32 {
         self.flags.jobs.unwrap_or(num_cpus::get() as u32)
     }
 
+    /// Returns the path to the C compiler for the target specified.
     fn cc(&self, target: &str) -> &Path {
         self.cc[target].0.path()
     }
 
+    /// Returns a list of flags to pass to the C compiler for the target
+    /// specified.
     fn cflags(&self, target: &str) -> Vec<String> {
         // Filter out -O and /O (the optimization flags) that we picked up from
         // gcc-rs because the build scripts will determine that for themselves.
@@ -663,15 +775,26 @@ impl Build {
         return base
     }
 
+    /// Returns the path to the `ar` archive utility for the target specified.
     fn ar(&self, target: &str) -> &Path {
         &self.cc[target].1
     }
 
+    /// Returns the path to the C++ compiler for the target specified, may panic
+    /// if no C++ compiler was configured for the target.
     fn cxx(&self, target: &str) -> &Path {
         self.cxx[target].path()
     }
 
+    /// Returns flags to pass to the compiler to generate code for `target`.
     fn rustc_flags(&self, target: &str) -> Vec<String> {
+        // New flags should be added here with great caution!
+        //
+        // It's quite unfortunate to **require** flags to generate code for a
+        // target, so it should only be passed here if absolutely necessary!
+        // Most default configuration should be done through target specs rather
+        // than an entry here.
+
         let mut base = Vec::new();
         if target != self.config.build && !target.contains("msvc") {
             base.push(format!("-Clinker={}", self.cc(target).display()));
@@ -681,10 +804,12 @@ impl Build {
 }
 
 impl<'a> Compiler<'a> {
+    /// Creates a new complier for the specified stage/host
     fn new(stage: u32, host: &'a str) -> Compiler<'a> {
         Compiler { stage: stage, host: host }
     }
 
+    /// Returns whether this is a snapshot compiler for `build`'s configuration
     fn is_snapshot(&self, build: &Build) -> bool {
         self.stage == 0 && self.host == build.config.build
     }
diff --git a/src/bootstrap/build/native.rs b/src/bootstrap/build/native.rs
index 59c928ab7b7..5691b2da6a4 100644
--- a/src/bootstrap/build/native.rs
+++ b/src/bootstrap/build/native.rs
@@ -8,6 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Compilation of native dependencies like LLVM.
+//!
+//! Native projects like LLVM unfortunately aren't suited just yet for
+//! compilation in build scripts that Cargo has. This is because thie
+//! compilation takes a *very* long time but also because we don't want to
+//! compile LLVM 3 times as part of a normal bootstrap (we want it cached).
+//!
+//! LLVM and compiler-rt are essentially just wired up to everything else to
+//! ensure that they're always in place if needed.
+
 use std::path::Path;
 use std::process::Command;
 use std::fs;
@@ -19,6 +29,7 @@ use gcc;
 use build::Build;
 use build::util::{exe, staticlib, up_to_date};
 
+/// Compile LLVM for `target`.
 pub fn llvm(build: &Build, target: &str) {
     // If we're using a custom LLVM bail out here, but we can only use a
     // custom LLVM for the build triple.
@@ -116,6 +127,10 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
     panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
 }
 
+/// Compiles the `compiler-rt` library, or at least the builtins part of it.
+///
+/// This uses the CMake build system and an existing LLVM build directory to
+/// compile the project.
 pub fn compiler_rt(build: &Build, target: &str) {
     let dst = build.compiler_rt_out(target);
     let arch = target.split('-').next().unwrap();
@@ -171,6 +186,8 @@ pub fn compiler_rt(build: &Build, target: &str) {
     cfg.build();
 }
 
+/// Compiles the `rust_test_helpers.c` library which we used in various
+/// `run-pass` test suites for ABI testing.
 pub fn test_helpers(build: &Build, target: &str) {
     let dst = build.test_helpers_out(target);
     let src = build.src.join("src/rt/rust_test_helpers.c");
diff --git a/src/bootstrap/build/sanity.rs b/src/bootstrap/build/sanity.rs
index 09e6e467b06..a2905277429 100644
--- a/src/bootstrap/build/sanity.rs
+++ b/src/bootstrap/build/sanity.rs
@@ -8,6 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Sanity checking performed by rustbuild before actually executing anything.
+//!
+//! This module contains the implementation of ensuring that the build
+//! environment looks reasonable before progressing. This will verify that
+//! various programs like git and python exist, along with ensuring that all C
+//! compilers for cross-compiling are found.
+//!
+//! In theory if we get past this phase it's a bug if a build fails, but in
+//! practice that's likely not true!
+
 use std::collections::HashSet;
 use std::env;
 use std::ffi::{OsStr, OsString};
diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs
index 59d644730a2..4a336589b44 100644
--- a/src/bootstrap/build/step.rs
+++ b/src/bootstrap/build/step.rs
@@ -8,6 +8,18 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Major workhorse of rustbuild, definition and dependencies between stages of
+//! the copmile.
+//!
+//! The primary purpose of this module is to define the various `Step`s of
+//! execution of the build. Each `Step` has a corresponding `Source` indicating
+//! what it's actually doing along with a number of dependencies which must be
+//! executed first.
+//!
+//! This module will take the CLI as input and calculate the steps required for
+//! the build requested, ensuring that all intermediate pieces are in place.
+//! Essentially this module is a `make`-replacement, but not as good.
+
 use std::collections::HashSet;
 
 use build::{Build, Compiler};
@@ -18,6 +30,15 @@ pub struct Step<'a> {
     pub target: &'a str,
 }
 
+/// Macro used to iterate over all targets that are recognized by the build
+/// system.
+///
+/// Whenever a new step is added it will involve adding an entry here, updating
+/// the dependencies section below, and then adding an implementation of the
+/// step in `build/mod.rs`.
+///
+/// This macro takes another macro as an argument and then calls that macro with
+/// all steps that the build system knows about.
 macro_rules! targets {
     ($m:ident) => {
         $m! {
@@ -110,6 +131,9 @@ macro_rules! targets {
     }
 }
 
+// Define the `Source` enum by iterating over all the steps and peeling out just
+// the types that we want to define.
+
 macro_rules! item { ($a:item) => ($a) }
 
 macro_rules! define_source {
@@ -125,6 +149,12 @@ macro_rules! define_source {
 
 targets!(define_source);
 
+/// Calculate a list of all steps described by `build`.
+///
+/// This will inspect the flags passed in on the command line and use that to
+/// build up a list of steps to execute. These steps will then be transformed
+/// into a topologically sorted list which when executed left-to-right will
+/// correctly sequence the entire build.
 pub fn all(build: &Build) -> Vec<Step> {
     let mut ret = Vec::new();
     let mut all = HashSet::new();
@@ -146,6 +176,8 @@ pub fn all(build: &Build) -> Vec<Step> {
     }
 }
 
+/// Determines what top-level targets are requested as part of this build,
+/// returning them as a list.
 fn top_level(build: &Build) -> Vec<Step> {
     let mut targets = Vec::new();
     let stage = build.flags.stage.unwrap_or(2);
@@ -161,8 +193,10 @@ fn top_level(build: &Build) -> Vec<Step> {
                      .unwrap_or(host.target)
     };
 
+    // First, try to find steps on the command line.
     add_steps(build, stage, &host, &target, &mut targets);
 
+    // If none are specified, then build everything.
     if targets.len() == 0 {
         let t = Step {
             src: Source::Llvm { _dummy: () },
@@ -260,8 +294,14 @@ impl<'a> Step<'a> {
         Step { target: target, src: self.src.clone() }
     }
 
+    // Define ergonomic constructors for each step defined above so they can be
+    // easily constructed.
     targets!(constructors);
 
+    /// Mapping of all dependencies for rustbuild.
+    ///
+    /// This function receives a step, the build that we're building for, and
+    /// then returns a list of all the dependencies of that step.
     pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
         match self.src {
             Source::Rustc { stage: 0 } => {
diff --git a/src/bootstrap/build/util.rs b/src/bootstrap/build/util.rs
index 41cf924d44a..36ce0649142 100644
--- a/src/bootstrap/build/util.rs
+++ b/src/bootstrap/build/util.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Various utility functions used throughout rustbuild.
+//!
+//! Simple things like testing the various filesystem operations here and there,
+//! not a lot of interesting happenings here unfortunately.
+
 use std::env;
 use std::path::{Path, PathBuf};
 use std::fs;
@@ -16,6 +21,7 @@ use std::process::Command;
 use bootstrap::{dylib_path, dylib_path_var};
 use filetime::FileTime;
 
+/// Returns the `name` as the filename of a static library for `target`.
 pub fn staticlib(name: &str, target: &str) -> String {
     if target.contains("windows-msvc") {
         format!("{}.lib", name)
@@ -24,12 +30,15 @@ pub fn staticlib(name: &str, target: &str) -> String {
     }
 }
 
+/// Returns the last-modified time for `path`, or zero if it doesn't exist.
 pub fn mtime(path: &Path) -> FileTime {
     fs::metadata(path).map(|f| {
         FileTime::from_last_modification_time(&f)
     }).unwrap_or(FileTime::zero())
 }
 
+/// Copies a file from `src` to `dst`, attempting to use hard links and then
+/// falling back to an actually filesystem copy if necessary.
 pub fn copy(src: &Path, dst: &Path) {
     let res = fs::hard_link(src, dst);
     let res = res.or_else(|_| fs::copy(src, dst).map(|_| ()));
@@ -39,6 +48,8 @@ pub fn copy(src: &Path, dst: &Path) {
     }
 }
 
+/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
+/// when this function is called.
 pub fn cp_r(src: &Path, dst: &Path) {
     for f in t!(fs::read_dir(src)) {
         let f = t!(f);
@@ -66,14 +77,18 @@ pub fn exe(name: &str, target: &str) -> String {
     }
 }
 
+/// Returns whether the file name given looks like a dynamic library.
 pub fn is_dylib(name: &str) -> bool {
     name.ends_with(".dylib") || name.ends_with(".so") || name.ends_with(".dll")
 }
 
+/// Returns the corresponding relative library directory that the compiler's
+/// dylibs will be found in.
 pub fn libdir(target: &str) -> &'static str {
     if target.contains("windows") {"bin"} else {"lib"}
 }
 
+/// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
 pub fn add_lib_path(path: Vec<PathBuf>, cmd: &mut Command) {
     let mut list = dylib_path();
     for path in path {
@@ -82,7 +97,10 @@ pub fn add_lib_path(path: Vec<PathBuf>, cmd: &mut Command) {
     cmd.env(dylib_path_var(), t!(env::join_paths(list)));
 }
 
-#[allow(dead_code)] // this will be used soon
+/// Returns whether `dst` is up to date given that the file or files in `src`
+/// are used to generate it.
+///
+/// Uses last-modified time checks to verify this.
 pub fn up_to_date(src: &Path, dst: &Path) -> bool {
     let threshold = mtime(dst);
     let meta = t!(fs::metadata(src));