2015-11-19 15:20:12 -08:00
|
|
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
//! Definition of steps of the build system.
|
|
|
|
//!
|
|
|
|
//! This is where some of the real meat of rustbuild is located, in how we
|
|
|
|
//! define targets and the dependencies amongst them. This file can sort of be
|
|
|
|
//! viewed as just defining targets in a makefile which shell out to predefined
|
|
|
|
//! functions elsewhere about how to execute the target.
|
|
|
|
//!
|
|
|
|
//! The primary function here you're likely interested in is the `build_rules`
|
|
|
|
//! function. This will create a `Rules` structure which basically just lists
|
|
|
|
//! everything that rustbuild can do. Each rule has a human-readable name, a
|
|
|
|
//! path associated with it, some dependencies, and then a closure of how to
|
|
|
|
//! actually perform the rule.
|
|
|
|
//!
|
|
|
|
//! All steps below are defined in self-contained units, so adding a new target
|
|
|
|
//! to the build system should just involve adding the meta information here
|
|
|
|
//! along with the actual implementation elsewhere. You can find more comments
|
|
|
|
//! about how to define rules themselves below.
|
|
|
|
|
2017-04-11 11:58:25 -07:00
|
|
|
use std::collections::{BTreeMap, HashSet, HashMap};
|
2016-10-21 13:18:09 -07:00
|
|
|
use std::mem;
|
2017-07-10 16:27:46 +02:00
|
|
|
use std::path::PathBuf;
|
2017-06-02 09:27:44 -07:00
|
|
|
use std::process;
|
2016-10-21 13:18:09 -07:00
|
|
|
|
2016-11-25 22:13:59 +01:00
|
|
|
use check::{self, TestKind};
|
2016-10-21 13:18:09 -07:00
|
|
|
use compile;
|
|
|
|
use dist;
|
|
|
|
use doc;
|
|
|
|
use flags::Subcommand;
|
|
|
|
use install;
|
|
|
|
use native;
|
|
|
|
use {Compiler, Build, Mode};
|
|
|
|
|
|
|
|
pub fn run(build: &Build) {
|
|
|
|
let rules = build_rules(build);
|
|
|
|
let steps = rules.plan();
|
|
|
|
rules.run(&steps);
|
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
2016-11-16 12:31:19 -08:00
|
|
|
let mut rules = Rules::new(build);
|
|
|
|
|
|
|
|
// This is the first rule that we're going to define for rustbuild, which is
|
|
|
|
// used to compile LLVM itself. All rules are added through the `rules`
|
|
|
|
// structure created above and are configured through a builder-style
|
|
|
|
// interface.
|
|
|
|
//
|
|
|
|
// First up we see the `build` method. This represents a rule that's part of
|
|
|
|
// the top-level `build` subcommand. For example `./x.py build` is what this
|
|
|
|
// is associating with. Note that this is normally only relevant if you flag
|
|
|
|
// a rule as `default`, which we'll talk about later.
|
|
|
|
//
|
|
|
|
// Next up we'll see two arguments to this method:
|
|
|
|
//
|
|
|
|
// * `llvm` - this is the "human readable" name of this target. This name is
|
|
|
|
// not accessed anywhere outside this file itself (e.g. not in
|
|
|
|
// the CLI nor elsewhere in rustbuild). The purpose of this is to
|
|
|
|
// easily define dependencies between rules. That is, other rules
|
|
|
|
// will depend on this with the name "llvm".
|
|
|
|
// * `src/llvm` - this is the relevant path to the rule that we're working
|
|
|
|
// with. This path is the engine behind how commands like
|
|
|
|
// `./x.py build src/llvm` work. This should typically point
|
|
|
|
// to the relevant component, but if there's not really a
|
|
|
|
// path to be assigned here you can pass something like
|
|
|
|
// `path/to/nowhere` to ignore it.
|
|
|
|
//
|
|
|
|
// After we create the rule with the `build` method we can then configure
|
|
|
|
// various aspects of it. For example this LLVM rule uses `.host(true)` to
|
|
|
|
// flag that it's a rule only for host targets. In other words, LLVM isn't
|
|
|
|
// compiled for targets configured through `--target` (e.g. those we're just
|
|
|
|
// building a standard library for).
|
|
|
|
//
|
|
|
|
// Next up the `dep` method will add a dependency to this rule. The closure
|
|
|
|
// is yielded the step that represents executing the `llvm` rule itself
|
|
|
|
// (containing information like stage, host, target, ...) and then it must
|
|
|
|
// return a target that the step depends on. Here LLVM is actually
|
|
|
|
// interesting where a cross-compiled LLVM depends on the host LLVM, but
|
|
|
|
// otherwise it has no dependencies.
|
|
|
|
//
|
|
|
|
// To handle this we do a bit of dynamic dispatch to see what the dependency
|
|
|
|
// is. If we're building a LLVM for the build triple, then we don't actually
|
2016-11-16 17:37:20 -05:00
|
|
|
// have any dependencies! To do that we return a dependency on the `Step::noop()`
|
2016-11-16 12:31:19 -08:00
|
|
|
// target which does nothing.
|
|
|
|
//
|
|
|
|
// If we're build a cross-compiled LLVM, however, we need to assemble the
|
|
|
|
// libraries from the previous compiler. This step has the same name as
|
|
|
|
// ours (llvm) but we want it for a different target, so we use the
|
|
|
|
// builder-style methods on `Step` to configure this target to the build
|
|
|
|
// triple.
|
|
|
|
//
|
|
|
|
// Finally, to finish off this rule, we define how to actually execute it.
|
|
|
|
// That logic is all defined in the `native` module so we just delegate to
|
|
|
|
// the relevant function there. The argument to the closure passed to `run`
|
|
|
|
// is a `Step` (defined below) which encapsulates information like the
|
|
|
|
// stage, target, host, etc.
|
|
|
|
rules.build("llvm", "src/llvm")
|
|
|
|
.host(true)
|
|
|
|
.dep(move |s| {
|
2017-06-27 15:59:43 -06:00
|
|
|
if s.target == build.build {
|
2016-11-16 17:37:20 -05:00
|
|
|
Step::noop()
|
2016-11-16 12:31:19 -08:00
|
|
|
} else {
|
2017-06-27 15:59:43 -06:00
|
|
|
s.target(&build.build)
|
2016-11-16 12:31:19 -08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.run(move |s| native::llvm(build, s.target));
|
|
|
|
|
|
|
|
// Ok! After that example rule that's hopefully enough to explain what's
|
|
|
|
// going on here. You can check out the API docs below and also see a bunch
|
|
|
|
// more examples of rules directly below as well.
|
|
|
|
|
|
|
|
// the compiler with no target libraries ready to go
|
|
|
|
rules.build("rustc", "src/rustc")
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("create-sysroot").target(s.host))
|
2016-11-16 12:31:19 -08:00
|
|
|
.dep(move |s| {
|
|
|
|
if s.stage == 0 {
|
2016-11-16 17:37:20 -05:00
|
|
|
Step::noop()
|
2016-11-16 12:31:19 -08:00
|
|
|
} else {
|
|
|
|
s.name("librustc")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
2016-11-16 12:31:19 -08:00
|
|
|
.stage(s.stage - 1)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.run(move |s| compile::assemble_rustc(build, s.stage, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
|
|
|
|
// Helper for loading an entire DAG of crates, rooted at `name`
|
|
|
|
let krates = |name: &str| {
|
|
|
|
let mut ret = Vec::new();
|
|
|
|
let mut list = vec![name];
|
|
|
|
let mut visited = HashSet::new();
|
|
|
|
while let Some(krate) = list.pop() {
|
|
|
|
let default = krate == name;
|
|
|
|
let krate = &build.crates[krate];
|
2017-04-08 18:53:57 -04:00
|
|
|
let path = krate.path.strip_prefix(&build.src)
|
|
|
|
// This handles out of tree paths
|
|
|
|
.unwrap_or(&krate.path);
|
2016-10-21 13:18:09 -07:00
|
|
|
ret.push((krate, path.to_str().unwrap(), default));
|
|
|
|
for dep in krate.deps.iter() {
|
|
|
|
if visited.insert(dep) && dep != "build_helper" {
|
|
|
|
list.push(dep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-06-27 09:51:26 -06:00
|
|
|
ret
|
2015-11-19 15:20:12 -08:00
|
|
|
};
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
// ========================================================================
|
|
|
|
// Crate compilations
|
|
|
|
//
|
|
|
|
// Tools used during the build system but not shipped
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
rules.build("create-sysroot", "path/to/nowhere")
|
|
|
|
.run(move |s| compile::create_sysroot(build, &s.compiler()));
|
|
|
|
|
|
|
|
// These rules are "pseudo rules" that don't actually do any work
|
|
|
|
// themselves, but represent a complete sysroot with the relevant compiler
|
|
|
|
// linked into place.
|
|
|
|
//
|
|
|
|
// That is, depending on "libstd" means that when the rule is completed then
|
|
|
|
// the `stage` sysroot for the compiler `host` will be available with a
|
|
|
|
// standard library built for `target` linked in place. Not all rules need
|
|
|
|
// the compiler itself to be available, just the standard library, so
|
|
|
|
// there's a distinction between the two.
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build("libstd", "src/libstd")
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("rustc").target(s.host))
|
|
|
|
.dep(|s| s.name("libstd-link"));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build("libtest", "src/libtest")
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libstd"))
|
|
|
|
.dep(|s| s.name("libtest-link"))
|
|
|
|
.default(true);
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build("librustc", "src/librustc")
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libtest"))
|
|
|
|
.dep(|s| s.name("librustc-link"))
|
|
|
|
.host(true)
|
|
|
|
.default(true);
|
|
|
|
|
|
|
|
// Helper method to define the rules to link a crate into its place in the
|
|
|
|
// sysroot.
|
|
|
|
//
|
|
|
|
// The logic here is a little subtle as there's a few cases to consider.
|
|
|
|
// Not all combinations of (stage, host, target) actually require something
|
|
|
|
// to be compiled, but rather libraries could get propagated from a
|
|
|
|
// different location. For example:
|
|
|
|
//
|
|
|
|
// * Any crate with a `host` that's not the build triple will not actually
|
|
|
|
// compile something. A different `host` means that the build triple will
|
|
|
|
// actually compile the libraries, and then we'll copy them over from the
|
|
|
|
// build triple to the `host` directory.
|
|
|
|
//
|
|
|
|
// * Some crates aren't even compiled by the build triple, but may be copied
|
|
|
|
// from previous stages. For example if we're not doing a full bootstrap
|
|
|
|
// then we may just depend on the stage1 versions of libraries to be
|
|
|
|
// available to get linked forward.
|
|
|
|
//
|
|
|
|
// * Finally, there are some cases, however, which do indeed comiple crates
|
|
|
|
// and link them into place afterwards.
|
|
|
|
//
|
|
|
|
// The rule definition below mirrors these three cases. The `dep` method
|
|
|
|
// calculates the correct dependency which either comes from stage1, a
|
|
|
|
// 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) {
|
2017-06-27 15:59:43 -06:00
|
|
|
s.host(&build.build).stage(1)
|
|
|
|
} else if s.host == build.build {
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
s.name(dep)
|
|
|
|
} else {
|
2017-06-27 15:59:43 -06:00
|
|
|
s.host(&build.build)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.run(move |s| {
|
|
|
|
if build.force_use_stage1(&s.compiler(), s.target) {
|
|
|
|
link(build,
|
2017-06-27 15:59:43 -06:00
|
|
|
&s.stage(1).host(&build.build).compiler(),
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
&s.compiler(),
|
|
|
|
s.target)
|
2017-06-27 15:59:43 -06:00
|
|
|
} else if s.host == build.build {
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
link(build, &s.compiler(), &s.compiler(), s.target)
|
|
|
|
} else {
|
|
|
|
link(build,
|
2017-06-27 15:59:43 -06:00
|
|
|
&s.host(&build.build).compiler(),
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
&s.compiler(),
|
|
|
|
s.target)
|
|
|
|
}
|
|
|
|
});
|
2017-06-27 09:51:26 -06:00
|
|
|
rule
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Similar to the `libstd`, `libtest`, and `librustc` rules above, except
|
|
|
|
// these rules only represent the libraries being available in the sysroot,
|
|
|
|
// not the compiler itself. This is done as not all rules need a compiler in
|
|
|
|
// the sysroot, but may just need the libraries.
|
|
|
|
//
|
|
|
|
// All of these rules use the helper definition above.
|
|
|
|
crate_rule(build,
|
|
|
|
&mut rules,
|
|
|
|
"libstd-link",
|
2017-02-15 08:53:18 -08:00
|
|
|
"build-crate-std",
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
compile::std_link)
|
2016-12-29 18:17:31 -08:00
|
|
|
.dep(|s| s.name("startup-objects"))
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("create-sysroot").target(s.host));
|
|
|
|
crate_rule(build,
|
|
|
|
&mut rules,
|
|
|
|
"libtest-link",
|
2017-02-15 08:53:18 -08:00
|
|
|
"build-crate-test",
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
compile::test_link)
|
|
|
|
.dep(|s| s.name("libstd-link"));
|
|
|
|
crate_rule(build,
|
|
|
|
&mut rules,
|
|
|
|
"librustc-link",
|
|
|
|
"build-crate-rustc-main",
|
|
|
|
compile::rustc_link)
|
|
|
|
.dep(|s| s.name("libtest-link"));
|
|
|
|
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, _default) in krates("std") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build(&krate.build_step, path)
|
2016-12-29 18:17:31 -08:00
|
|
|
.dep(|s| s.name("startup-objects"))
|
2017-06-27 15:59:43 -06:00
|
|
|
.dep(move |s| s.name("rustc").host(&build.build).target(s.host))
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.run(move |s| compile::std(build, s.target, &s.compiler()));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, _default) in krates("test") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build(&krate.build_step, path)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libstd-link"))
|
|
|
|
.run(move |s| compile::test(build, s.target, &s.compiler()));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
for (krate, path, _default) in krates("rustc-main") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build(&krate.build_step, path)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libtest-link"))
|
2017-06-27 15:59:43 -06:00
|
|
|
.dep(move |s| s.name("llvm").host(&build.build).stage(0))
|
2017-02-15 15:57:06 -08:00
|
|
|
.dep(|s| s.name("may-run-build-script"))
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.run(move |s| compile::rustc(build, s.target, &s.compiler()));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
|
2017-02-15 15:57:06 -08:00
|
|
|
// Crates which have build scripts need to rely on this rule to ensure that
|
|
|
|
// the necessary prerequisites for a build script are linked and located in
|
|
|
|
// place.
|
|
|
|
rules.build("may-run-build-script", "path/to/nowhere")
|
|
|
|
.dep(move |s| {
|
|
|
|
s.name("libstd-link")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-02-15 15:57:06 -08:00
|
|
|
});
|
2016-12-29 18:17:31 -08:00
|
|
|
rules.build("startup-objects", "src/rtstartup")
|
|
|
|
.dep(|s| s.name("create-sysroot").target(s.host))
|
|
|
|
.run(move |s| compile::build_startup_objects(build, &s.compiler(), s.target));
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
// ========================================================================
|
|
|
|
// Test targets
|
|
|
|
//
|
|
|
|
// Various unit tests and tests suites we can run
|
|
|
|
{
|
2016-12-29 09:55:16 -08:00
|
|
|
let mut suite = |name, path, mode, dir| {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test(name, path)
|
|
|
|
.dep(|s| s.name("libtest"))
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("test-helpers"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-12-29 09:55:16 -08:00
|
|
|
.default(mode != "pretty") // pretty tests don't run everywhere
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| {
|
2016-12-29 09:55:16 -08:00
|
|
|
check::compiletest(build, &s.compiler(), s.target, mode, dir)
|
2016-10-21 13:18:09 -07:00
|
|
|
});
|
2015-11-19 15:20:12 -08:00
|
|
|
};
|
2016-02-24 23:50:32 -08:00
|
|
|
|
2017-03-03 13:28:22 +03:00
|
|
|
suite("check-ui", "src/test/ui", "ui", "ui");
|
2016-10-21 13:18:09 -07:00
|
|
|
suite("check-rpass", "src/test/run-pass", "run-pass", "run-pass");
|
|
|
|
suite("check-cfail", "src/test/compile-fail", "compile-fail", "compile-fail");
|
|
|
|
suite("check-pfail", "src/test/parse-fail", "parse-fail", "parse-fail");
|
|
|
|
suite("check-rfail", "src/test/run-fail", "run-fail", "run-fail");
|
|
|
|
suite("check-rpass-valgrind", "src/test/run-pass-valgrind",
|
|
|
|
"run-pass-valgrind", "run-pass-valgrind");
|
|
|
|
suite("check-mir-opt", "src/test/mir-opt", "mir-opt", "mir-opt");
|
|
|
|
if build.config.codegen_tests {
|
|
|
|
suite("check-codegen", "src/test/codegen", "codegen", "codegen");
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
suite("check-codegen-units", "src/test/codegen-units", "codegen-units",
|
|
|
|
"codegen-units");
|
|
|
|
suite("check-incremental", "src/test/incremental", "incremental",
|
|
|
|
"incremental");
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
|
2017-06-27 15:59:43 -06:00
|
|
|
if build.build.contains("msvc") {
|
2016-10-21 13:18:09 -07:00
|
|
|
// nothing to do for debuginfo tests
|
2016-12-30 21:55:02 +10:00
|
|
|
} else {
|
|
|
|
rules.test("check-debuginfo-lldb", "src/test/debuginfo-lldb")
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("libtest"))
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("test-helpers"))
|
|
|
|
.dep(|s| s.name("debugger-scripts"))
|
|
|
|
.run(move |s| check::compiletest(build, &s.compiler(), s.target,
|
|
|
|
"debuginfo-lldb", "debuginfo"));
|
2016-12-30 21:55:02 +10:00
|
|
|
rules.test("check-debuginfo-gdb", "src/test/debuginfo-gdb")
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("libtest"))
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("test-helpers"))
|
|
|
|
.dep(|s| s.name("debugger-scripts"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::compiletest(build, &s.compiler(), s.target,
|
|
|
|
"debuginfo-gdb", "debuginfo"));
|
2016-12-30 21:55:02 +10:00
|
|
|
let mut rule = rules.test("check-debuginfo", "src/test/debuginfo");
|
|
|
|
rule.default(true);
|
2017-06-27 15:59:43 -06:00
|
|
|
if build.build.contains("apple") {
|
2016-12-30 21:55:02 +10:00
|
|
|
rule.dep(|s| s.name("check-debuginfo-lldb"));
|
|
|
|
} else {
|
|
|
|
rule.dep(|s| s.name("check-debuginfo-gdb"));
|
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test("debugger-scripts", "src/etc/lldb_batchmode.py")
|
|
|
|
.run(move |s| dist::debugger_scripts(build, &build.sysroot(&s.compiler()),
|
|
|
|
s.target));
|
|
|
|
|
|
|
|
{
|
2016-12-29 09:55:16 -08:00
|
|
|
let mut suite = |name, path, mode, dir| {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test(name, path)
|
|
|
|
.dep(|s| s.name("librustc"))
|
2016-12-29 18:17:31 -08:00
|
|
|
.dep(|s| s.name("test-helpers"))
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
|
2016-12-29 09:55:16 -08:00
|
|
|
.default(mode != "pretty")
|
2016-10-21 13:18:09 -07:00
|
|
|
.host(true)
|
|
|
|
.run(move |s| {
|
2016-12-29 09:55:16 -08:00
|
|
|
check::compiletest(build, &s.compiler(), s.target, mode, dir)
|
2016-10-21 13:18:09 -07:00
|
|
|
});
|
2016-03-07 22:50:25 -08:00
|
|
|
};
|
2016-10-21 13:18:09 -07:00
|
|
|
|
2017-03-03 13:28:22 +03:00
|
|
|
suite("check-ui-full", "src/test/ui-fulldeps", "ui", "ui-fulldeps");
|
2016-10-21 13:18:09 -07:00
|
|
|
suite("check-rpass-full", "src/test/run-pass-fulldeps",
|
|
|
|
"run-pass", "run-pass-fulldeps");
|
2016-12-30 19:50:57 -08:00
|
|
|
suite("check-rfail-full", "src/test/run-fail-fulldeps",
|
|
|
|
"run-fail", "run-fail-fulldeps");
|
2016-10-21 13:18:09 -07:00
|
|
|
suite("check-cfail-full", "src/test/compile-fail-fulldeps",
|
|
|
|
"compile-fail", "compile-fail-fulldeps");
|
|
|
|
suite("check-rmake", "src/test/run-make", "run-make", "run-make");
|
|
|
|
suite("check-rustdoc", "src/test/rustdoc", "rustdoc", "rustdoc");
|
2016-12-28 15:05:17 -08:00
|
|
|
suite("check-pretty", "src/test/pretty", "pretty", "pretty");
|
|
|
|
suite("check-pretty-rpass", "src/test/run-pass/pretty", "pretty",
|
|
|
|
"run-pass");
|
2016-12-29 17:29:32 -08:00
|
|
|
suite("check-pretty-rfail", "src/test/run-fail/pretty", "pretty",
|
2016-12-28 15:05:17 -08:00
|
|
|
"run-fail");
|
2016-12-29 17:29:32 -08:00
|
|
|
suite("check-pretty-valgrind", "src/test/run-pass-valgrind/pretty", "pretty",
|
2016-12-28 15:05:17 -08:00
|
|
|
"run-pass-valgrind");
|
2016-12-29 09:55:16 -08:00
|
|
|
suite("check-pretty-rpass-full", "src/test/run-pass-fulldeps/pretty",
|
2016-10-21 13:18:09 -07:00
|
|
|
"pretty", "run-pass-fulldeps");
|
2016-12-29 09:55:16 -08:00
|
|
|
suite("check-pretty-rfail-full", "src/test/run-fail-fulldeps/pretty",
|
2016-10-21 13:18:09 -07:00
|
|
|
"pretty", "run-fail-fulldeps");
|
|
|
|
}
|
|
|
|
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, _default) in krates("std") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test(&krate.test_step, path)
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
2016-11-25 22:13:59 +01:00
|
|
|
Mode::Libstd, TestKind::Test,
|
|
|
|
Some(&krate.name)));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
rules.test("check-std-all", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2016-11-25 22:13:59 +01:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
|
|
|
Mode::Libstd, TestKind::Test, None));
|
|
|
|
|
|
|
|
// std benchmarks
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, _default) in krates("std") {
|
2016-11-25 22:13:59 +01:00
|
|
|
rules.bench(&krate.bench_step, path)
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-11-25 22:13:59 +01:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
|
|
|
Mode::Libstd, TestKind::Bench,
|
|
|
|
Some(&krate.name)));
|
|
|
|
}
|
|
|
|
rules.bench("bench-std-all", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-11-25 22:13:59 +01:00
|
|
|
.default(true)
|
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
|
|
|
Mode::Libstd, TestKind::Bench, None));
|
|
|
|
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, _default) in krates("test") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test(&krate.test_step, path)
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
2016-11-25 22:13:59 +01:00
|
|
|
Mode::Libtest, TestKind::Test,
|
|
|
|
Some(&krate.name)));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
rules.test("check-test-all", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("libtest"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2016-11-25 22:13:59 +01:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
|
|
|
Mode::Libtest, TestKind::Test, None));
|
2016-10-21 13:18:09 -07:00
|
|
|
for (krate, path, _default) in krates("rustc-main") {
|
|
|
|
rules.test(&krate.test_step, path)
|
2016-11-04 17:44:53 -07:00
|
|
|
.dep(|s| s.name("librustc"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.host(true)
|
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
2016-11-25 22:13:59 +01:00
|
|
|
Mode::Librustc, TestKind::Test,
|
|
|
|
Some(&krate.name)));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
rules.test("check-rustc-all", "path/to/nowhere")
|
2016-11-04 17:44:53 -07:00
|
|
|
.dep(|s| s.name("librustc"))
|
2017-04-11 12:10:05 +02:00
|
|
|
.dep(|s| s.name("remote-copy-libs"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-11-25 22:13:59 +01:00
|
|
|
.run(move |s| check::krate(build, &s.compiler(), s.target,
|
|
|
|
Mode::Librustc, TestKind::Test, None));
|
2016-10-21 13:18:09 -07:00
|
|
|
|
|
|
|
rules.test("check-linkchecker", "src/tools/linkchecker")
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-linkchecker").stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("default:doc"))
|
2017-06-15 13:25:15 +02:00
|
|
|
.default(build.config.docs)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-12-28 15:01:21 -08:00
|
|
|
.run(move |s| check::linkcheck(build, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test("check-cargotest", "src/tools/cargotest")
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-cargotest").stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("librustc"))
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::cargotest(build, s.stage, s.target));
|
2017-07-01 06:58:54 +12:00
|
|
|
rules.test("check-cargo", "src/tools/cargo")
|
2017-04-17 17:24:05 -07:00
|
|
|
.dep(|s| s.name("tool-cargo"))
|
|
|
|
.host(true)
|
|
|
|
.run(move |s| check::cargo(build, s.stage, s.target));
|
2017-07-01 06:58:54 +12:00
|
|
|
rules.test("check-rls", "src/tools/rls")
|
|
|
|
.dep(|s| s.name("tool-rls"))
|
|
|
|
.host(true)
|
|
|
|
.run(move |s| check::rls(build, s.stage, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test("check-tidy", "src/tools/tidy")
|
2016-11-16 12:31:19 -08:00
|
|
|
.dep(|s| s.name("tool-tidy").stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_build(true)
|
2016-12-28 15:01:21 -08:00
|
|
|
.run(move |s| check::tidy(build, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.test("check-error-index", "src/tools/error_index_generator")
|
|
|
|
.dep(|s| s.name("libstd"))
|
2016-12-28 15:01:21 -08:00
|
|
|
.dep(|s| s.name("tool-error-index").host(s.host).stage(0))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::error_index(build, &s.compiler()));
|
|
|
|
rules.test("check-docs", "src/doc")
|
|
|
|
.dep(|s| s.name("libtest"))
|
|
|
|
.default(true)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| check::docs(build, &s.compiler()));
|
2016-12-08 17:13:55 -08:00
|
|
|
rules.test("check-distcheck", "distcheck")
|
2017-05-23 18:11:04 +02:00
|
|
|
.dep(|s| s.name("dist-plain-source-tarball"))
|
2017-05-24 08:45:12 +02:00
|
|
|
.dep(|s| s.name("dist-src"))
|
2016-12-08 17:13:55 -08:00
|
|
|
.run(move |_| check::distcheck(build));
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build("test-helpers", "src/rt/rust_test_helpers.c")
|
|
|
|
.run(move |s| native::test_helpers(build, s.target));
|
2017-02-15 15:57:06 -08:00
|
|
|
rules.build("openssl", "path/to/nowhere")
|
|
|
|
.run(move |s| native::openssl(build, s.target));
|
2017-01-28 13:38:06 -08:00
|
|
|
|
2017-04-11 12:10:05 +02:00
|
|
|
// Some test suites are run inside emulators or on remote devices, and most
|
|
|
|
// of our test binaries are linked dynamically which means we need to ship
|
|
|
|
// the standard library and such to the emulator ahead of time. This step
|
|
|
|
// represents this and is a dependency of all test suites.
|
2017-01-28 13:38:06 -08:00
|
|
|
//
|
|
|
|
// Most of the time this step is a noop (the `check::emulator_copy_libs`
|
|
|
|
// only does work if necessary). For some steps such as shipping data to
|
|
|
|
// QEMU we have to build our own tools so we've got conditional dependencies
|
2017-04-11 12:10:05 +02:00
|
|
|
// on those programs as well. Note that the remote test client is built for
|
|
|
|
// the build target (us) and the server is built for the target.
|
|
|
|
rules.test("remote-copy-libs", "path/to/nowhere")
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("libtest"))
|
2017-01-28 13:38:06 -08:00
|
|
|
.dep(move |s| {
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
if build.remote_tested(s.target) {
|
|
|
|
s.name("tool-remote-test-client").target(s.host).stage(0)
|
2017-01-28 13:38:06 -08:00
|
|
|
} else {
|
|
|
|
Step::noop()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.dep(move |s| {
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
if build.remote_tested(s.target) {
|
|
|
|
s.name("tool-remote-test-server")
|
2017-01-28 13:38:06 -08:00
|
|
|
} else {
|
|
|
|
Step::noop()
|
|
|
|
}
|
|
|
|
})
|
2017-04-11 12:10:05 +02:00
|
|
|
.run(move |s| check::remote_copy_libs(build, &s.compiler(), s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
|
2016-12-30 19:50:57 -08:00
|
|
|
rules.test("check-bootstrap", "src/bootstrap")
|
|
|
|
.default(true)
|
|
|
|
.host(true)
|
|
|
|
.only_build(true)
|
|
|
|
.run(move |_| check::bootstrap(build));
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
// ========================================================================
|
|
|
|
// Build tools
|
|
|
|
//
|
|
|
|
// Tools used during the build system but not shipped
|
|
|
|
rules.build("tool-rustbook", "src/tools/rustbook")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("librustc-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "rustbook"));
|
|
|
|
rules.build("tool-error-index", "src/tools/error_index_generator")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("librustc-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "error_index_generator"));
|
2017-06-12 21:35:47 +02:00
|
|
|
rules.build("tool-unstable-book-gen", "src/tools/unstable-book-gen")
|
|
|
|
.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"));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.build("tool-tidy", "src/tools/tidy")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "tidy"));
|
|
|
|
rules.build("tool-linkchecker", "src/tools/linkchecker")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "linkchecker"));
|
|
|
|
rules.build("tool-cargotest", "src/tools/cargotest")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "cargotest"));
|
|
|
|
rules.build("tool-compiletest", "src/tools/compiletest")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libtest-tool"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "compiletest"));
|
2017-01-24 14:37:04 -08:00
|
|
|
rules.build("tool-build-manifest", "src/tools/build-manifest")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
2017-01-24 14:37:04 -08:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "build-manifest"));
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
rules.build("tool-remote-test-server", "src/tools/remote-test-server")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "remote-test-server"));
|
|
|
|
rules.build("tool-remote-test-client", "src/tools/remote-test-client")
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
travis: Parallelize tests on Android
Currently our slowest test suite on android, run-pass, takes over 5 times longer
than the x86_64 component (~400 -> ~2200s). Typically QEMU emulation does indeed
add overhead, but not 5x for this kind of workload. One of the slowest parts of
the Android process is that *compilation* happens serially. Tests themselves
need to run single-threaded on the emulator (due to how the test harness works)
and this forces the compiles themselves to be single threaded.
Now Travis gives us more than one core per machine, so it'd be much better if we
could take advantage of them! The emulator itself is still fundamentally
single-threaded, but we should see a nice speedup by sending binaries for it to
run much more quickly.
It turns out that we've already got all the tools to do this in-tree. The
qemu-test-{server,client} that are in use for the ARM Linux testing are a
perfect match for the Android emulator. This commit migrates the custom adb
management code in compiletest/rustbuild to the same qemu-test-{server,client}
implementation that ARM Linux uses.
This allows us to lift the parallelism restriction on the compiletest test
suites, namely run-pass. Consequently although we'll still basically run the
tests themselves in single threaded mode we'll be able to compile all of them in
parallel, keeping the pipeline much more full and using more cores for the work
at hand. Additionally the architecture here should be a bit speedier as it
should have less overhead than adb which is a whole new process on both the host
and the emulator!
Locally on an 8 core machine I've seen the run-pass test suite speed up from
taking nearly an hour to only taking 6 minutes. I don't think we'll see quite a
drastic speedup on Travis but I'm hoping this change can place the Android tests
well below 2 hours instead of just above 2 hours.
Because the client/server here are now repurposed for more than just QEMU,
they've been renamed to `remote-test-{server,client}`.
Note that this PR does not currently modify how debuginfo tests are executed on
Android. While parallelizable it wouldn't be quite as easy, so that's left to
another day. Thankfully that test suite is much smaller than the run-pass test
suite.
As a final fix I discovered that the ARM and Android test suites were actually
running all library unit tests (e.g. stdtest, coretest, etc) twice. I've
corrected that to only run tests once which should also give a nice boost in
overall cycle time here.
2017-04-26 08:52:19 -07:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "remote-test-client"));
|
2017-05-08 15:01:13 -07:00
|
|
|
rules.build("tool-rust-installer", "src/tools/rust-installer")
|
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "rust-installer"));
|
2017-04-20 14:32:54 -07:00
|
|
|
rules.build("tool-cargo", "src/tools/cargo")
|
2017-04-28 10:48:49 +02:00
|
|
|
.host(true)
|
2017-04-27 11:51:02 +02:00
|
|
|
.default(build.config.extended)
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("maybe-clean-tools"))
|
|
|
|
.dep(|s| s.name("libstd-tool"))
|
2017-02-15 15:57:06 -08:00
|
|
|
.dep(|s| s.stage(0).host(s.target).name("openssl"))
|
|
|
|
.dep(move |s| {
|
|
|
|
// Cargo depends on procedural macros, which requires a full host
|
|
|
|
// compiler to be available, so we need to depend on that.
|
|
|
|
s.name("librustc-link")
|
2017-06-27 15:59:43 -06:00
|
|
|
.target(&build.build)
|
|
|
|
.host(&build.build)
|
2017-02-15 15:57:06 -08:00
|
|
|
})
|
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
|
2017-04-20 14:32:54 -07:00
|
|
|
rules.build("tool-rls", "src/tools/rls")
|
2017-03-17 09:52:12 +13:00
|
|
|
.host(true)
|
2017-04-27 11:51:02 +02:00
|
|
|
.default(build.config.extended)
|
2017-04-11 11:58:25 -07:00
|
|
|
.dep(|s| s.name("librustc-tool"))
|
|
|
|
.dep(|s| s.stage(0).host(s.target).name("openssl"))
|
2017-04-10 11:22:38 -07:00
|
|
|
.dep(move |s| {
|
|
|
|
// rls, like cargo, uses procedural macros
|
|
|
|
s.name("librustc-link")
|
2017-06-27 15:59:43 -06:00
|
|
|
.target(&build.build)
|
|
|
|
.host(&build.build)
|
2017-04-10 11:22:38 -07:00
|
|
|
})
|
2017-03-17 09:52:12 +13:00
|
|
|
.run(move |s| compile::tool(build, s.stage, s.target, "rls"));
|
2016-10-21 13:18:09 -07:00
|
|
|
|
2017-04-11 11:58:25 -07:00
|
|
|
// "pseudo rule" which represents completely cleaning out the tools dir in
|
|
|
|
// one stage. This needs to happen whenever a dependency changes (e.g.
|
|
|
|
// libstd, libtest, librustc) and all of the tool compilations above will
|
|
|
|
// be sequenced after this rule.
|
|
|
|
rules.build("maybe-clean-tools", "path/to/nowhere")
|
|
|
|
.after("librustc-tool")
|
|
|
|
.after("libtest-tool")
|
|
|
|
.after("libstd-tool");
|
|
|
|
|
|
|
|
rules.build("librustc-tool", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("librustc"))
|
|
|
|
.run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Librustc));
|
|
|
|
rules.build("libtest-tool", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("libtest"))
|
|
|
|
.run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libtest));
|
|
|
|
rules.build("libstd-tool", "path/to/nowhere")
|
|
|
|
.dep(|s| s.name("libstd"))
|
|
|
|
.run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libstd));
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
// ========================================================================
|
|
|
|
// Documentation targets
|
|
|
|
rules.doc("doc-book", "src/doc/book")
|
2017-01-05 11:16:48 -08:00
|
|
|
.dep(move |s| {
|
|
|
|
s.name("tool-rustbook")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-01-05 11:16:48 -08:00
|
|
|
.stage(0)
|
|
|
|
})
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(build.config.docs)
|
2017-03-07 14:49:50 -05:00
|
|
|
.run(move |s| doc::book(build, s.target, "book"));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.doc("doc-nomicon", "src/doc/nomicon")
|
2017-01-05 11:16:48 -08:00
|
|
|
.dep(move |s| {
|
|
|
|
s.name("tool-rustbook")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-01-05 11:16:48 -08:00
|
|
|
.stage(0)
|
|
|
|
})
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(build.config.docs)
|
2016-12-28 15:01:21 -08:00
|
|
|
.run(move |s| doc::rustbook(build, s.target, "nomicon"));
|
2017-02-15 14:57:33 -05:00
|
|
|
rules.doc("doc-reference", "src/doc/reference")
|
|
|
|
.dep(move |s| {
|
|
|
|
s.name("tool-rustbook")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-02-15 14:57:33 -05:00
|
|
|
.stage(0)
|
|
|
|
})
|
|
|
|
.default(build.config.docs)
|
|
|
|
.run(move |s| doc::rustbook(build, s.target, "reference"));
|
2017-02-15 17:43:03 -05:00
|
|
|
rules.doc("doc-unstable-book", "src/doc/unstable-book")
|
|
|
|
.dep(move |s| {
|
|
|
|
s.name("tool-rustbook")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-02-15 17:43:03 -05:00
|
|
|
.stage(0)
|
|
|
|
})
|
2017-06-14 18:49:41 +02:00
|
|
|
.dep(move |s| s.name("doc-unstable-book-gen"))
|
2017-02-15 17:43:03 -05:00
|
|
|
.default(build.config.docs)
|
2017-06-12 21:35:47 +02:00
|
|
|
.run(move |s| doc::rustbook_src(build,
|
|
|
|
s.target,
|
|
|
|
"unstable-book",
|
|
|
|
&build.md_doc_out(s.target)));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.doc("doc-standalone", "src/doc")
|
2016-12-30 19:50:57 -08:00
|
|
|
.dep(move |s| {
|
|
|
|
s.name("rustc")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2016-12-30 19:50:57 -08:00
|
|
|
.stage(0)
|
|
|
|
})
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(build.config.docs)
|
2016-12-30 19:50:57 -08:00
|
|
|
.run(move |s| doc::standalone(build, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.doc("doc-error-index", "src/tools/error_index_generator")
|
2017-06-27 15:59:43 -06:00
|
|
|
.dep(move |s| s.name("tool-error-index").target(&build.build).stage(0))
|
2017-01-12 16:43:44 -08:00
|
|
|
.dep(move |s| s.name("librustc-link"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(build.config.docs)
|
2016-11-05 14:22:19 -07:00
|
|
|
.host(true)
|
2016-12-28 15:01:21 -08:00
|
|
|
.run(move |s| doc::error_index(build, s.target));
|
2017-06-12 21:35:47 +02:00
|
|
|
rules.doc("doc-unstable-book-gen", "src/tools/unstable-book-gen")
|
2017-06-14 18:49:41 +02:00
|
|
|
.dep(move |s| {
|
|
|
|
s.name("tool-unstable-book-gen")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-06-14 18:49:41 +02:00
|
|
|
.stage(0)
|
|
|
|
})
|
|
|
|
.dep(move |s| s.name("libstd-link"))
|
2017-06-12 21:35:47 +02:00
|
|
|
.default(build.config.docs)
|
|
|
|
.host(true)
|
|
|
|
.run(move |s| doc::unstable_book_gen(build, s.target));
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, default) in krates("std") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.doc(&krate.doc_step, path)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libstd-link"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(default && build.config.docs)
|
|
|
|
.run(move |s| doc::std(build, s.stage, s.target));
|
|
|
|
}
|
2017-02-15 08:53:18 -08:00
|
|
|
for (krate, path, default) in krates("test") {
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.doc(&krate.doc_step, path)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("libtest-link"))
|
2017-03-12 02:45:20 +00:00
|
|
|
// Needed so rustdoc generates relative links to std.
|
|
|
|
.dep(|s| s.name("doc-crate-std"))
|
2016-12-15 21:10:29 +00:00
|
|
|
.default(default && build.config.compiler_docs)
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| doc::test(build, s.stage, s.target));
|
|
|
|
}
|
|
|
|
for (krate, path, default) in krates("rustc-main") {
|
|
|
|
rules.doc(&krate.doc_step, path)
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
.dep(|s| s.name("librustc-link"))
|
2017-03-12 02:45:20 +00:00
|
|
|
// Needed so rustdoc generates relative links to std.
|
|
|
|
.dep(|s| s.name("doc-crate-std"))
|
2016-10-21 13:18:09 -07:00
|
|
|
.host(true)
|
2017-03-01 15:34:54 -08:00
|
|
|
.default(default && build.config.docs)
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| doc::rustc(build, s.stage, s.target));
|
|
|
|
}
|
|
|
|
|
|
|
|
// ========================================================================
|
|
|
|
// Distribution targets
|
|
|
|
rules.dist("dist-rustc", "src/librustc")
|
2017-06-27 15:59:43 -06:00
|
|
|
.dep(move |s| s.name("rustc").host(&build.build))
|
2016-10-21 13:18:09 -07:00
|
|
|
.host(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_host_build(true)
|
2016-10-21 13:18:09 -07:00
|
|
|
.default(true)
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| dist::rustc(build, s.stage, s.target));
|
|
|
|
rules.dist("dist-std", "src/libstd")
|
|
|
|
.dep(move |s| {
|
|
|
|
// We want to package up as many target libraries as possible
|
|
|
|
// for the `rust-std` package, so if this is a host target we
|
|
|
|
// depend on librustc and otherwise we just depend on libtest.
|
|
|
|
if build.config.host.iter().any(|t| t == s.target) {
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
s.name("librustc-link")
|
2016-10-21 13:18:09 -07:00
|
|
|
} else {
|
rustbuild: Compile rustc twice, not thrice
This commit switches the rustbuild build system to compiling the
compiler twice for a normal bootstrap rather than the historical three
times.
Rust is a bootstrapped language which means that a previous version of
the compiler is used to build the next version of the compiler. Over
time, however, we change many parts of compiler artifacts such as the
metadata format, symbol names, etc. These changes make artifacts from
one compiler incompatible from another compiler. Consequently if a
compiler wants to be able to use some artifacts then it itself must have
compiled the artifacts.
Historically the rustc build system has achieved this by compiling the
compiler three times:
* An older compiler (stage0) is downloaded to kick off the chain.
* This compiler now compiles a new compiler (stage1)
* The stage1 compiler then compiles another compiler (stage2)
* Finally, the stage2 compiler needs libraries to link against, so it
compiles all the libraries again.
This entire process amounts in compiling the compiler three times.
Additionally, this process always guarantees that the Rust source tree
can compile itself because the stage2 compiler (created by a freshly
created compiler) would successfully compile itself again. This
property, ensuring Rust can compile itself, is quite important!
In general, though, this third compilation is not required for general
purpose development on the compiler. The third compiler (stage2) can
reuse the libraries that were created during the second compile. In
other words, the second compilation can produce both a compiler and the
libraries that compiler will use. These artifacts *must* be compatible
due to the way plugins work today anyway, and they were created by the
same source code so they *should* be compatible as well.
So given all that, this commit switches the default build process to
only compile the compiler three times, avoiding this third compilation
by copying artifacts from the previous one. Along the way a new entry in
the Travis matrix was also added to ensure that our full bootstrap can
succeed. This entry does not run tests, though, as it should not be
necessary.
To restore the old behavior of a full bootstrap (three compiles) you can
either pass:
./configure --enable-full-bootstrap
or if you're using config.toml:
[build]
full-bootstrap = true
Overall this will hopefully be an easy 33% win in build times of the
compiler. If we do 33% less work we should be 33% faster! This in turn
should affect cycle times and such on Travis and AppVeyor positively as
well as making it easier to work on the compiler itself.
2016-12-25 15:20:33 -08:00
|
|
|
s.name("libtest-link")
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.default(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_host_build(true)
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| dist::std(build, &s.compiler(), s.target));
|
|
|
|
rules.dist("dist-mingw", "path/to/nowhere")
|
2016-12-15 10:05:41 -08:00
|
|
|
.default(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_host_build(true)
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-12-15 10:05:41 -08:00
|
|
|
.run(move |s| {
|
|
|
|
if s.target.contains("pc-windows-gnu") {
|
|
|
|
dist::mingw(build, s.target)
|
|
|
|
}
|
|
|
|
});
|
2017-05-18 22:48:14 +02:00
|
|
|
rules.dist("dist-plain-source-tarball", "src")
|
|
|
|
.default(build.config.rust_dist_src)
|
|
|
|
.host(true)
|
|
|
|
.only_build(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
|
|
|
.run(move |_| dist::plain_source_tarball(build));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.dist("dist-src", "src")
|
|
|
|
.default(true)
|
|
|
|
.host(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_build(true)
|
|
|
|
.only_host_build(true)
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-12-30 19:50:57 -08:00
|
|
|
.run(move |_| dist::rust_src(build));
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.dist("dist-docs", "src/doc")
|
2016-11-11 21:47:18 +00:00
|
|
|
.default(true)
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_host_build(true)
|
2016-10-21 13:18:09 -07:00
|
|
|
.dep(|s| s.name("default:doc"))
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-10-21 13:18:09 -07:00
|
|
|
.run(move |s| dist::docs(build, s.stage, s.target));
|
2016-12-12 11:04:26 -08:00
|
|
|
rules.dist("dist-analysis", "analysis")
|
2017-04-12 20:48:18 -07:00
|
|
|
.default(build.config.extended)
|
2016-10-27 11:41:56 +13:00
|
|
|
.dep(|s| s.name("dist-std"))
|
2016-12-30 19:50:57 -08:00
|
|
|
.only_host_build(true)
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2016-10-27 11:41:56 +13:00
|
|
|
.run(move |s| dist::analysis(build, &s.compiler(), s.target));
|
2017-03-17 09:52:12 +13:00
|
|
|
rules.dist("dist-rls", "rls")
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("tool-rls"))
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2017-03-17 09:52:12 +13:00
|
|
|
.run(move |s| dist::rls(build, s.stage, s.target));
|
2017-01-20 17:03:06 -08:00
|
|
|
rules.dist("dist-cargo", "cargo")
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
2017-02-15 15:57:06 -08:00
|
|
|
.dep(|s| s.name("tool-cargo"))
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2017-01-20 17:03:06 -08:00
|
|
|
.run(move |s| dist::cargo(build, s.stage, s.target));
|
|
|
|
rules.dist("dist-extended", "extended")
|
|
|
|
.default(build.config.extended)
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|d| d.name("dist-std"))
|
|
|
|
.dep(|d| d.name("dist-rustc"))
|
|
|
|
.dep(|d| d.name("dist-mingw"))
|
|
|
|
.dep(|d| d.name("dist-docs"))
|
|
|
|
.dep(|d| d.name("dist-cargo"))
|
2017-03-17 09:52:12 +13:00
|
|
|
.dep(|d| d.name("dist-rls"))
|
|
|
|
.dep(|d| d.name("dist-analysis"))
|
2017-05-09 11:43:48 -07:00
|
|
|
.dep(move |s| tool_rust_installer(build, s))
|
2017-01-20 17:03:06 -08:00
|
|
|
.run(move |s| dist::extended(build, s.stage, s.target));
|
2016-10-21 13:18:09 -07:00
|
|
|
|
2017-01-24 14:37:04 -08:00
|
|
|
rules.dist("dist-sign", "hash-and-sign")
|
|
|
|
.host(true)
|
|
|
|
.only_build(true)
|
|
|
|
.only_host_build(true)
|
2017-06-27 15:59:43 -06:00
|
|
|
.dep(move |s| s.name("tool-build-manifest").target(&build.build).stage(0))
|
2017-01-24 14:37:04 -08:00
|
|
|
.run(move |_| dist::hash_and_sign(build));
|
|
|
|
|
2017-05-18 22:48:14 +02:00
|
|
|
rules.install("install-docs", "src/doc")
|
|
|
|
.default(build.config.docs)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-docs"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_docs(s.stage, s.target));
|
|
|
|
rules.install("install-std", "src/libstd")
|
|
|
|
.default(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-std"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_std(s.stage));
|
|
|
|
rules.install("install-cargo", "cargo")
|
|
|
|
.default(build.config.extended)
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-cargo"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_cargo(s.stage, s.target));
|
|
|
|
rules.install("install-rls", "rls")
|
|
|
|
.default(build.config.extended)
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-rls"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_rls(s.stage, s.target));
|
|
|
|
rules.install("install-analysis", "analysis")
|
|
|
|
.default(build.config.extended)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-analysis"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_analysis(s.stage, s.target));
|
|
|
|
rules.install("install-src", "src")
|
|
|
|
.default(build.config.extended)
|
|
|
|
.host(true)
|
|
|
|
.only_build(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-src"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_src(s.stage));
|
|
|
|
rules.install("install-rustc", "src/librustc")
|
|
|
|
.default(true)
|
|
|
|
.host(true)
|
|
|
|
.only_host_build(true)
|
|
|
|
.dep(|s| s.name("dist-rustc"))
|
|
|
|
.run(move |s| install::Installer::new(build).install_rustc(s.stage, s.target));
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
rules.verify();
|
2016-11-16 12:31:19 -08:00
|
|
|
return rules;
|
2017-05-09 11:43:48 -07:00
|
|
|
|
|
|
|
/// Helper to depend on a stage0 build-only rust-installer tool.
|
|
|
|
fn tool_rust_installer<'a>(build: &'a Build, step: &Step<'a>) -> Step<'a> {
|
|
|
|
step.name("tool-rust-installer")
|
2017-06-27 15:59:43 -06:00
|
|
|
.host(&build.build)
|
|
|
|
.target(&build.build)
|
2017-05-09 11:43:48 -07:00
|
|
|
.stage(0)
|
|
|
|
}
|
2016-11-16 12:31:19 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
|
|
|
struct Step<'a> {
|
|
|
|
/// Human readable name of the rule this step is executing. Possible names
|
|
|
|
/// are all defined above in `build_rules`.
|
|
|
|
name: &'a str,
|
|
|
|
|
|
|
|
/// The stage this step is executing in. This is typically 0, 1, or 2.
|
|
|
|
stage: u32,
|
|
|
|
|
|
|
|
/// This step will likely involve a compiler, and the target that compiler
|
|
|
|
/// itself is built for is called the host, this variable. Typically this is
|
|
|
|
/// the target of the build machine itself.
|
|
|
|
host: &'a str,
|
|
|
|
|
|
|
|
/// The target that this step represents generating. If you're building a
|
|
|
|
/// standard library for a new suite of targets, for example, this'll be set
|
|
|
|
/// to those targets.
|
|
|
|
target: &'a str,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Step<'a> {
|
2016-11-16 17:37:20 -05:00
|
|
|
fn noop() -> Step<'a> {
|
|
|
|
Step { name: "", stage: 0, host: "", target: "" }
|
|
|
|
}
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Creates a new step which is the same as this, except has a new name.
|
|
|
|
fn name(&self, name: &'a str) -> Step<'a> {
|
|
|
|
Step { name: name, ..*self }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a new step which is the same as this, except has a new stage.
|
|
|
|
fn stage(&self, stage: u32) -> Step<'a> {
|
|
|
|
Step { stage: stage, ..*self }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a new step which is the same as this, except has a new host.
|
|
|
|
fn host(&self, host: &'a str) -> Step<'a> {
|
|
|
|
Step { host: host, ..*self }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Creates a new step which is the same as this, except has a new target.
|
|
|
|
fn target(&self, target: &'a str) -> Step<'a> {
|
|
|
|
Step { target: target, ..*self }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the `Compiler` structure that this step corresponds to.
|
|
|
|
fn compiler(&self) -> Compiler<'a> {
|
|
|
|
Compiler::new(self.stage, self.host)
|
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Rule<'a> {
|
2016-11-16 12:31:19 -08:00
|
|
|
/// The human readable name of this target, defined in `build_rules`.
|
2016-10-21 13:18:09 -07:00
|
|
|
name: &'a str,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// The path associated with this target, used in the `./x.py` driver for
|
|
|
|
/// easy and ergonomic specification of what to do.
|
2016-10-21 13:18:09 -07:00
|
|
|
path: &'a str,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// The "kind" of top-level command that this rule is associated with, only
|
|
|
|
/// relevant if this is a default rule.
|
2016-10-21 13:18:09 -07:00
|
|
|
kind: Kind,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// List of dependencies this rule has. Each dependency is a function from a
|
|
|
|
/// step that's being executed to another step that should be executed.
|
2016-10-21 13:18:09 -07:00
|
|
|
deps: Vec<Box<Fn(&Step<'a>) -> Step<'a> + 'a>>,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// How to actually execute this rule. Takes a step with contextual
|
|
|
|
/// information and then executes it.
|
2016-10-21 13:18:09 -07:00
|
|
|
run: Box<Fn(&Step<'a>) + 'a>,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// Whether or not this is a "default" rule. That basically means that if
|
|
|
|
/// you run, for example, `./x.py test` whether it's included or not.
|
2016-10-21 13:18:09 -07:00
|
|
|
default: bool,
|
2016-11-16 12:31:19 -08:00
|
|
|
|
|
|
|
/// Whether or not this is a "host" rule, or in other words whether this is
|
|
|
|
/// only intended for compiler hosts and not for targets that are being
|
|
|
|
/// generated.
|
2016-10-21 13:18:09 -07:00
|
|
|
host: bool,
|
2016-12-30 19:50:57 -08:00
|
|
|
|
|
|
|
/// Whether this rule is only for steps where the host is the build triple,
|
|
|
|
/// not anything in hosts or targets.
|
|
|
|
only_host_build: bool,
|
|
|
|
|
|
|
|
/// Whether this rule is only for the build triple, not anything in hosts or
|
|
|
|
/// targets.
|
|
|
|
only_build: bool,
|
2017-04-11 11:58:25 -07:00
|
|
|
|
|
|
|
/// A list of "order only" dependencies. This rules does not actually
|
|
|
|
/// depend on these rules, but if they show up in the dependency graph then
|
|
|
|
/// this rule must be executed after all these rules.
|
|
|
|
after: Vec<&'a str>,
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(PartialEq)]
|
|
|
|
enum Kind {
|
|
|
|
Build,
|
|
|
|
Test,
|
2016-11-25 22:13:59 +01:00
|
|
|
Bench,
|
2016-10-21 13:18:09 -07:00
|
|
|
Dist,
|
|
|
|
Doc,
|
2017-05-18 22:48:14 +02:00
|
|
|
Install,
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Rule<'a> {
|
|
|
|
fn new(name: &'a str, path: &'a str, kind: Kind) -> Rule<'a> {
|
|
|
|
Rule {
|
|
|
|
name: name,
|
|
|
|
deps: Vec::new(),
|
|
|
|
run: Box::new(|_| ()),
|
|
|
|
path: path,
|
|
|
|
kind: kind,
|
|
|
|
default: false,
|
|
|
|
host: false,
|
2016-12-30 19:50:57 -08:00
|
|
|
only_host_build: false,
|
|
|
|
only_build: false,
|
2017-04-11 11:58:25 -07:00
|
|
|
after: Vec::new(),
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Builder pattern returned from the various methods on `Rules` which will add
|
|
|
|
/// the rule to the internal list on `Drop`.
|
2016-10-21 13:18:09 -07:00
|
|
|
struct RuleBuilder<'a: 'b, 'b> {
|
|
|
|
rules: &'b mut Rules<'a>,
|
|
|
|
rule: Rule<'a>,
|
|
|
|
}
|
2016-03-07 22:50:25 -08:00
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
impl<'a, 'b> RuleBuilder<'a, 'b> {
|
|
|
|
fn dep<F>(&mut self, f: F) -> &mut Self
|
|
|
|
where F: Fn(&Step<'a>) -> Step<'a> + 'a,
|
|
|
|
{
|
|
|
|
self.rule.deps.push(Box::new(f));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-11 11:58:25 -07:00
|
|
|
fn after(&mut self, step: &'a str) -> &mut Self {
|
|
|
|
self.rule.after.push(step);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
fn run<F>(&mut self, f: F) -> &mut Self
|
|
|
|
where F: Fn(&Step<'a>) + 'a,
|
|
|
|
{
|
|
|
|
self.rule.run = Box::new(f);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
fn default(&mut self, default: bool) -> &mut Self {
|
|
|
|
self.rule.default = default;
|
|
|
|
self
|
|
|
|
}
|
2016-03-07 23:15:55 -08:00
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
fn host(&mut self, host: bool) -> &mut Self {
|
|
|
|
self.rule.host = host;
|
|
|
|
self
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
|
|
|
|
fn only_build(&mut self, only_build: bool) -> &mut Self {
|
|
|
|
self.rule.only_build = only_build;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
fn only_host_build(&mut self, only_host_build: bool) -> &mut Self {
|
|
|
|
self.rule.only_host_build = only_host_build;
|
|
|
|
self
|
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
impl<'a, 'b> Drop for RuleBuilder<'a, 'b> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
let rule = mem::replace(&mut self.rule, Rule::new("", "", Kind::Build));
|
|
|
|
let prev = self.rules.rules.insert(rule.name, rule);
|
|
|
|
if let Some(prev) = prev {
|
|
|
|
panic!("duplicate rule named: {}", prev.name);
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
pub struct Rules<'a> {
|
|
|
|
build: &'a Build,
|
|
|
|
sbuild: Step<'a>,
|
2017-02-28 20:12:26 +02:00
|
|
|
rules: BTreeMap<&'a str, Rule<'a>>,
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Rules<'a> {
|
|
|
|
fn new(build: &'a Build) -> Rules<'a> {
|
|
|
|
Rules {
|
|
|
|
build: build,
|
|
|
|
sbuild: Step {
|
|
|
|
stage: build.flags.stage.unwrap_or(2),
|
2017-06-27 15:59:43 -06:00
|
|
|
target: &build.build,
|
|
|
|
host: &build.build,
|
2016-10-21 13:18:09 -07:00
|
|
|
name: "",
|
|
|
|
},
|
2017-02-28 20:12:26 +02:00
|
|
|
rules: BTreeMap::new(),
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Creates a new rule of `Kind::Build` with the specified human readable
|
|
|
|
/// name and path associated with it.
|
|
|
|
///
|
|
|
|
/// The builder returned should be configured further with information such
|
|
|
|
/// as how to actually run this rule.
|
2016-10-21 13:18:09 -07:00
|
|
|
fn build<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Build)
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Same as `build`, but for `Kind::Test`.
|
2016-10-21 13:18:09 -07:00
|
|
|
fn test<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Test)
|
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Same as `build`, but for `Kind::Bench`.
|
2016-11-25 22:13:59 +01:00
|
|
|
fn bench<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Bench)
|
|
|
|
}
|
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Same as `build`, but for `Kind::Doc`.
|
2016-10-21 13:18:09 -07:00
|
|
|
fn doc<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Doc)
|
|
|
|
}
|
2016-07-13 15:40:42 +02:00
|
|
|
|
2016-11-16 12:31:19 -08:00
|
|
|
/// Same as `build`, but for `Kind::Dist`.
|
2016-10-21 13:18:09 -07:00
|
|
|
fn dist<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Dist)
|
|
|
|
}
|
2016-03-07 23:15:55 -08:00
|
|
|
|
2017-05-18 22:48:14 +02:00
|
|
|
/// Same as `build`, but for `Kind::Install`.
|
|
|
|
fn install<'b>(&'b mut self, name: &'a str, path: &'a str)
|
|
|
|
-> RuleBuilder<'a, 'b> {
|
|
|
|
self.rule(name, path, Kind::Install)
|
|
|
|
}
|
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
fn rule<'b>(&'b mut self,
|
|
|
|
name: &'a str,
|
|
|
|
path: &'a str,
|
|
|
|
kind: Kind) -> RuleBuilder<'a, 'b> {
|
|
|
|
RuleBuilder {
|
|
|
|
rules: self,
|
|
|
|
rule: Rule::new(name, path, kind),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verify the dependency graph defined by all our rules are correct, e.g.
|
|
|
|
/// everything points to a valid something else.
|
|
|
|
fn verify(&self) {
|
|
|
|
for rule in self.rules.values() {
|
|
|
|
for dep in rule.deps.iter() {
|
|
|
|
let dep = dep(&self.sbuild.name(rule.name));
|
|
|
|
if self.rules.contains_key(&dep.name) || dep.name.starts_with("default:") {
|
2016-11-14 12:50:38 -08:00
|
|
|
continue
|
|
|
|
}
|
2016-11-16 17:37:20 -05:00
|
|
|
if dep == Step::noop() {
|
|
|
|
continue
|
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
panic!("\
|
|
|
|
|
|
|
|
invalid rule dependency graph detected, was a rule added and maybe typo'd?
|
|
|
|
|
|
|
|
`{}` depends on `{}` which does not exist
|
2016-03-13 16:52:19 -07:00
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
", rule.name, dep.name);
|
2016-03-13 16:52:19 -07:00
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-01 15:48:03 -06:00
|
|
|
pub fn get_help(&self, command: &str) -> Option<String> {
|
2016-10-21 13:18:09 -07:00
|
|
|
let kind = match command {
|
|
|
|
"build" => Kind::Build,
|
|
|
|
"doc" => Kind::Doc,
|
|
|
|
"test" => Kind::Test,
|
2016-11-25 22:13:59 +01:00
|
|
|
"bench" => Kind::Bench,
|
2016-10-21 13:18:09 -07:00
|
|
|
"dist" => Kind::Dist,
|
2017-05-18 22:48:14 +02:00
|
|
|
"install" => Kind::Install,
|
2017-04-01 15:48:03 -06:00
|
|
|
_ => return None,
|
2016-10-21 13:18:09 -07:00
|
|
|
};
|
|
|
|
let rules = self.rules.values().filter(|r| r.kind == kind);
|
|
|
|
let rules = rules.filter(|r| !r.path.contains("nowhere"));
|
|
|
|
let mut rules = rules.collect::<Vec<_>>();
|
|
|
|
rules.sort_by_key(|r| r.path);
|
|
|
|
|
2017-04-01 15:48:03 -06:00
|
|
|
let mut help_string = String::from("Available paths:\n");
|
2016-10-21 13:18:09 -07:00
|
|
|
for rule in rules {
|
2017-04-01 15:48:03 -06:00
|
|
|
help_string.push_str(format!(" ./x.py {} {}\n", command, rule.path).as_str());
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2017-04-01 15:48:03 -06:00
|
|
|
Some(help_string)
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Construct the top-level build steps that we're going to be executing,
|
|
|
|
/// given the subcommand that our build is performing.
|
|
|
|
fn plan(&self) -> Vec<Step<'a>> {
|
2016-11-16 12:31:19 -08:00
|
|
|
// Ok, the logic here is pretty subtle, and involves quite a few
|
|
|
|
// conditionals. The basic idea here is to:
|
|
|
|
//
|
|
|
|
// 1. First, filter all our rules to the relevant ones. This means that
|
|
|
|
// the command specified corresponds to one of our `Kind` variants,
|
|
|
|
// and we filter all rules based on that.
|
|
|
|
//
|
|
|
|
// 2. Next, we determine which rules we're actually executing. If a
|
|
|
|
// number of path filters were specified on the command line we look
|
|
|
|
// for those, otherwise we look for anything tagged `default`.
|
2017-02-28 20:13:21 +02:00
|
|
|
// Here we also compute the priority of each rule based on how early
|
|
|
|
// in the command line the matching path filter showed up.
|
2016-11-16 12:31:19 -08:00
|
|
|
//
|
|
|
|
// 3. Finally, we generate some steps with host and target information.
|
|
|
|
//
|
|
|
|
// The last step is by far the most complicated and subtle. The basic
|
|
|
|
// thinking here is that we want to take the cartesian product of
|
|
|
|
// specified hosts and targets and build rules with that. The list of
|
|
|
|
// hosts and targets, if not specified, come from the how this build was
|
|
|
|
// configured. If the rule we're looking at is a host-only rule the we
|
|
|
|
// ignore the list of targets and instead consider the list of hosts
|
|
|
|
// also the list of targets.
|
|
|
|
//
|
|
|
|
// Once the host and target lists are generated we take the cartesian
|
|
|
|
// product of the two and then create a step based off them. Note that
|
|
|
|
// the stage each step is associated was specified with the `--step`
|
|
|
|
// flag on the command line.
|
2016-10-21 13:18:09 -07:00
|
|
|
let (kind, paths) = match self.build.flags.cmd {
|
|
|
|
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
|
|
|
|
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
|
2017-06-02 09:27:44 -07:00
|
|
|
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
|
|
|
|
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
|
2017-05-18 22:48:14 +02:00
|
|
|
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
|
|
|
|
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
|
2016-10-21 13:18:09 -07:00
|
|
|
Subcommand::Clean => panic!(),
|
|
|
|
};
|
2016-08-12 23:38:17 -07:00
|
|
|
|
2017-02-28 20:13:21 +02:00
|
|
|
let mut rules: Vec<_> = self.rules.values().filter_map(|rule| {
|
|
|
|
if rule.kind != kind {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
if paths.len() == 0 && rule.default {
|
|
|
|
Some((rule, 0))
|
|
|
|
} else {
|
2017-07-10 16:27:46 +02:00
|
|
|
paths.iter()
|
|
|
|
.position(|path| path.ends_with(rule.path))
|
2017-02-28 20:13:21 +02:00
|
|
|
.map(|priority| (rule, priority))
|
|
|
|
}
|
|
|
|
}).collect();
|
|
|
|
|
2017-07-10 16:27:46 +02:00
|
|
|
if rules.is_empty() &&
|
|
|
|
!paths.get(0).unwrap_or(&PathBuf::new())
|
|
|
|
.ends_with("nonexistent/path/to/trigger/cargo/metadata") {
|
|
|
|
println!("\nNothing to run...\n");
|
|
|
|
process::exit(1);
|
|
|
|
}
|
|
|
|
|
2017-02-28 20:13:21 +02:00
|
|
|
rules.sort_by_key(|&(_, priority)| priority);
|
|
|
|
|
|
|
|
rules.into_iter().flat_map(|(rule, _)| {
|
2016-12-30 19:50:57 -08:00
|
|
|
let hosts = if rule.only_host_build || rule.only_build {
|
2017-06-27 15:52:46 -06:00
|
|
|
self.build.build_slice()
|
2016-10-21 13:18:09 -07:00
|
|
|
} else {
|
2017-06-27 15:52:46 -06:00
|
|
|
&self.build.hosts
|
2016-10-21 13:18:09 -07:00
|
|
|
};
|
2016-12-28 01:54:09 +08:00
|
|
|
// Determine the actual targets participating in this rule.
|
2016-12-28 01:49:25 +08:00
|
|
|
// NOTE: We should keep the full projection from build triple to
|
|
|
|
// the hosts for the dist steps, now that the hosts array above is
|
|
|
|
// truncated to avoid duplication of work in that case. Therefore
|
|
|
|
// the original non-shadowed hosts array is used below.
|
2016-11-16 12:31:19 -08:00
|
|
|
let arr = if rule.host {
|
2016-12-28 01:54:09 +08:00
|
|
|
// If --target was specified but --host wasn't specified,
|
2017-06-27 15:52:46 -06:00
|
|
|
// don't run any host-only tests.
|
2016-12-28 01:49:25 +08:00
|
|
|
if self.build.flags.host.len() > 0 {
|
2017-06-27 15:52:46 -06:00
|
|
|
&self.build.hosts
|
2016-12-28 01:49:25 +08:00
|
|
|
} else if self.build.flags.target.len() > 0 {
|
2016-12-28 03:39:35 +08:00
|
|
|
&[]
|
2016-12-30 19:50:57 -08:00
|
|
|
} else if rule.only_build {
|
2017-06-27 15:52:46 -06:00
|
|
|
self.build.build_slice()
|
2016-11-16 12:31:19 -08:00
|
|
|
} else {
|
2017-06-27 15:52:46 -06:00
|
|
|
&self.build.hosts
|
2016-11-16 12:31:19 -08:00
|
|
|
}
|
|
|
|
} else {
|
2017-06-27 15:52:46 -06:00
|
|
|
&self.build.targets
|
2016-11-16 12:31:19 -08:00
|
|
|
};
|
2016-10-21 13:18:09 -07:00
|
|
|
|
|
|
|
hosts.iter().flat_map(move |host| {
|
|
|
|
arr.iter().map(move |target| {
|
|
|
|
self.sbuild.name(rule.name).target(target).host(host)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}).collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Execute all top-level targets indicated by `steps`.
|
|
|
|
///
|
|
|
|
/// This will take the list returned by `plan` and then execute each step
|
|
|
|
/// along with all required dependencies as it goes up the chain.
|
|
|
|
fn run(&self, steps: &[Step<'a>]) {
|
|
|
|
self.build.verbose("bootstrap top targets:");
|
|
|
|
for step in steps.iter() {
|
|
|
|
self.build.verbose(&format!("\t{:?}", step));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Using `steps` as the top-level targets, make a topological ordering
|
|
|
|
// of what we need to do.
|
2016-12-30 19:50:57 -08:00
|
|
|
let order = self.expand(steps);
|
2016-06-28 13:31:30 -07:00
|
|
|
|
2016-10-21 13:18:09 -07:00
|
|
|
// Print out what we're doing for debugging
|
|
|
|
self.build.verbose("bootstrap build plan:");
|
|
|
|
for step in order.iter() {
|
|
|
|
self.build.verbose(&format!("\t{:?}", step));
|
|
|
|
}
|
|
|
|
|
|
|
|
// And finally, iterate over everything and execute it.
|
|
|
|
for step in order.iter() {
|
2016-12-12 23:21:42 +01:00
|
|
|
if self.build.flags.keep_stage.map_or(false, |s| step.stage <= s) {
|
|
|
|
self.build.verbose(&format!("keeping step {:?}", step));
|
|
|
|
continue;
|
|
|
|
}
|
2016-11-05 14:22:19 -07:00
|
|
|
self.build.verbose(&format!("executing step {:?}", step));
|
2016-10-21 13:18:09 -07:00
|
|
|
(self.rules[step.name].run)(step);
|
|
|
|
}
|
2017-06-02 09:27:44 -07:00
|
|
|
|
|
|
|
// Check for postponed failures from `test --no-fail-fast`.
|
|
|
|
let failures = self.build.delayed_failures.get();
|
|
|
|
if failures > 0 {
|
|
|
|
println!("\n{} command(s) did not execute successfully.\n", failures);
|
|
|
|
process::exit(1);
|
|
|
|
}
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
|
2016-12-30 19:50:57 -08:00
|
|
|
/// From the top level targets `steps` generate a topological ordering of
|
|
|
|
/// all steps needed to run those steps.
|
|
|
|
fn expand(&self, steps: &[Step<'a>]) -> Vec<Step<'a>> {
|
2017-04-11 11:58:25 -07:00
|
|
|
// First up build a graph of steps and their dependencies. The `nodes`
|
|
|
|
// map is a map from step to a unique number. The `edges` map is a
|
|
|
|
// map from these unique numbers to a list of other numbers,
|
|
|
|
// representing dependencies.
|
|
|
|
let mut nodes = HashMap::new();
|
|
|
|
nodes.insert(Step::noop(), 0);
|
|
|
|
let mut edges = HashMap::new();
|
|
|
|
edges.insert(0, HashSet::new());
|
|
|
|
for step in steps {
|
|
|
|
self.build_graph(step.clone(), &mut nodes, &mut edges);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now that we've built up the actual dependency graph, draw more
|
|
|
|
// dependency edges to satisfy the `after` dependencies field for each
|
|
|
|
// rule.
|
|
|
|
self.satisfy_after_deps(&nodes, &mut edges);
|
|
|
|
|
|
|
|
// And finally, perform a topological sort to return a list of steps to
|
|
|
|
// execute.
|
2016-12-30 19:50:57 -08:00
|
|
|
let mut order = Vec::new();
|
2017-04-11 11:58:25 -07:00
|
|
|
let mut visited = HashSet::new();
|
|
|
|
visited.insert(0);
|
|
|
|
let idx_to_node = nodes.iter().map(|p| (*p.1, p.0)).collect::<HashMap<_, _>>();
|
2017-04-15 03:33:12 +03:00
|
|
|
for idx in 0..nodes.len() {
|
|
|
|
self.topo_sort(idx, &idx_to_node, &edges, &mut visited, &mut order);
|
2016-12-30 19:50:57 -08:00
|
|
|
}
|
2017-06-27 09:51:26 -06:00
|
|
|
order
|
2016-12-30 19:50:57 -08:00
|
|
|
}
|
|
|
|
|
2017-04-11 11:58:25 -07:00
|
|
|
/// Builds the dependency graph rooted at `step`.
|
2016-11-16 12:31:19 -08:00
|
|
|
///
|
2017-04-11 11:58:25 -07:00
|
|
|
/// The `nodes` and `edges` maps are filled out according to the rule
|
|
|
|
/// described by `step.name`.
|
|
|
|
fn build_graph(&self,
|
|
|
|
step: Step<'a>,
|
|
|
|
nodes: &mut HashMap<Step<'a>, usize>,
|
|
|
|
edges: &mut HashMap<usize, HashSet<usize>>) -> usize {
|
|
|
|
use std::collections::hash_map::Entry;
|
|
|
|
|
|
|
|
let idx = nodes.len();
|
|
|
|
match nodes.entry(step.clone()) {
|
|
|
|
Entry::Vacant(e) => { e.insert(idx); }
|
|
|
|
Entry::Occupied(e) => return *e.get(),
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
2017-04-11 11:58:25 -07:00
|
|
|
|
|
|
|
let mut deps = Vec::new();
|
2016-10-21 13:18:09 -07:00
|
|
|
for dep in self.rules[step.name].deps.iter() {
|
|
|
|
let dep = dep(&step);
|
|
|
|
if dep.name.starts_with("default:") {
|
|
|
|
let kind = match &dep.name[8..] {
|
|
|
|
"doc" => Kind::Doc,
|
|
|
|
"dist" => Kind::Dist,
|
|
|
|
kind => panic!("unknown kind: `{}`", kind),
|
|
|
|
};
|
2016-11-14 12:50:38 -08:00
|
|
|
let host = self.build.config.host.iter().any(|h| h == dep.target);
|
2016-10-21 13:18:09 -07:00
|
|
|
let rules = self.rules.values().filter(|r| r.default);
|
2016-11-14 12:50:38 -08:00
|
|
|
for rule in rules.filter(|r| r.kind == kind && (!r.host || host)) {
|
2017-04-11 11:58:25 -07:00
|
|
|
deps.push(self.build_graph(dep.name(rule.name), nodes, edges));
|
2016-10-21 13:18:09 -07:00
|
|
|
}
|
|
|
|
} else {
|
2017-04-11 11:58:25 -07:00
|
|
|
deps.push(self.build_graph(dep, nodes, edges));
|
2016-06-28 13:31:30 -07:00
|
|
|
}
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
2017-04-11 11:58:25 -07:00
|
|
|
|
|
|
|
edges.entry(idx).or_insert(HashSet::new()).extend(deps);
|
2017-06-27 09:51:26 -06:00
|
|
|
idx
|
2017-04-11 11:58:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Given a dependency graph with a finished list of `nodes`, fill out more
|
|
|
|
/// dependency `edges`.
|
|
|
|
///
|
|
|
|
/// This is the step which satisfies all `after` listed dependencies in
|
|
|
|
/// `Rule` above.
|
|
|
|
fn satisfy_after_deps(&self,
|
|
|
|
nodes: &HashMap<Step<'a>, usize>,
|
|
|
|
edges: &mut HashMap<usize, HashSet<usize>>) {
|
|
|
|
// Reverse map from the name of a step to the node indices that it
|
|
|
|
// appears at.
|
|
|
|
let mut name_to_idx = HashMap::new();
|
|
|
|
for (step, &idx) in nodes {
|
|
|
|
name_to_idx.entry(step.name).or_insert(Vec::new()).push(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (step, idx) in nodes {
|
|
|
|
if *step == Step::noop() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for after in self.rules[step.name].after.iter() {
|
|
|
|
// This is the critical piece of an `after` dependency. If the
|
|
|
|
// dependency isn't actually in our graph then no edge is drawn,
|
|
|
|
// only if it's already present do we draw the edges.
|
|
|
|
if let Some(idxs) = name_to_idx.get(after) {
|
|
|
|
edges.get_mut(idx).unwrap()
|
|
|
|
.extend(idxs.iter().cloned());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn topo_sort(&self,
|
|
|
|
cur: usize,
|
|
|
|
nodes: &HashMap<usize, &Step<'a>>,
|
|
|
|
edges: &HashMap<usize, HashSet<usize>>,
|
|
|
|
visited: &mut HashSet<usize>,
|
|
|
|
order: &mut Vec<Step<'a>>) {
|
|
|
|
if !visited.insert(cur) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
for dep in edges[&cur].iter() {
|
|
|
|
self.topo_sort(*dep, nodes, edges, visited, order);
|
|
|
|
}
|
|
|
|
order.push(nodes[&cur].clone());
|
2015-11-19 15:20:12 -08:00
|
|
|
}
|
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use std::env;
|
|
|
|
|
|
|
|
use Build;
|
|
|
|
use config::Config;
|
|
|
|
use flags::Flags;
|
|
|
|
|
|
|
|
fn build(args: &[&str],
|
|
|
|
extra_host: &[&str],
|
|
|
|
extra_target: &[&str]) -> Build {
|
2017-06-15 13:24:08 +02:00
|
|
|
build_(args, extra_host, extra_target, true)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn build_(args: &[&str],
|
|
|
|
extra_host: &[&str],
|
|
|
|
extra_target: &[&str],
|
|
|
|
docs: bool) -> Build {
|
2016-12-30 19:50:57 -08:00
|
|
|
let mut args = args.iter().map(|s| s.to_string()).collect::<Vec<_>>();
|
|
|
|
args.push("--build".to_string());
|
|
|
|
args.push("A".to_string());
|
|
|
|
let flags = Flags::parse(&args);
|
|
|
|
|
|
|
|
let mut config = Config::default();
|
2017-06-15 13:24:08 +02:00
|
|
|
config.docs = docs;
|
2016-12-30 19:50:57 -08:00
|
|
|
config.build = "A".to_string();
|
|
|
|
config.host = vec![config.build.clone()];
|
|
|
|
config.host.extend(extra_host.iter().map(|s| s.to_string()));
|
|
|
|
config.target = config.host.clone();
|
|
|
|
config.target.extend(extra_target.iter().map(|s| s.to_string()));
|
|
|
|
|
|
|
|
let mut build = Build::new(flags, config);
|
|
|
|
let cwd = env::current_dir().unwrap();
|
2017-02-15 08:53:18 -08:00
|
|
|
build.crates.insert("std".to_string(), ::Crate {
|
|
|
|
name: "std".to_string(),
|
2016-12-30 19:50:57 -08:00
|
|
|
deps: Vec::new(),
|
2017-02-15 08:53:18 -08:00
|
|
|
path: cwd.join("src/std"),
|
2017-03-12 05:09:10 +00:00
|
|
|
doc_step: "doc-crate-std".to_string(),
|
2017-02-15 08:53:18 -08:00
|
|
|
build_step: "build-crate-std".to_string(),
|
2017-03-12 05:09:10 +00:00
|
|
|
test_step: "test-crate-std".to_string(),
|
|
|
|
bench_step: "bench-crate-std".to_string(),
|
2017-02-15 15:57:06 -08:00
|
|
|
version: String::new(),
|
2016-12-30 19:50:57 -08:00
|
|
|
});
|
2017-02-15 08:53:18 -08:00
|
|
|
build.crates.insert("test".to_string(), ::Crate {
|
|
|
|
name: "test".to_string(),
|
2016-12-30 19:50:57 -08:00
|
|
|
deps: Vec::new(),
|
2017-02-15 08:53:18 -08:00
|
|
|
path: cwd.join("src/test"),
|
2017-03-12 05:09:10 +00:00
|
|
|
doc_step: "doc-crate-test".to_string(),
|
2017-02-15 08:53:18 -08:00
|
|
|
build_step: "build-crate-test".to_string(),
|
2017-03-12 05:09:10 +00:00
|
|
|
test_step: "test-crate-test".to_string(),
|
|
|
|
bench_step: "bench-crate-test".to_string(),
|
2017-02-15 15:57:06 -08:00
|
|
|
version: String::new(),
|
2016-12-30 19:50:57 -08:00
|
|
|
});
|
|
|
|
build.crates.insert("rustc-main".to_string(), ::Crate {
|
|
|
|
name: "rustc-main".to_string(),
|
|
|
|
deps: Vec::new(),
|
2017-02-15 15:57:06 -08:00
|
|
|
version: String::new(),
|
2016-12-30 19:50:57 -08:00
|
|
|
path: cwd.join("src/rustc-main"),
|
2017-03-12 05:09:10 +00:00
|
|
|
doc_step: "doc-crate-rustc-main".to_string(),
|
2016-12-30 19:50:57 -08:00
|
|
|
build_step: "build-crate-rustc-main".to_string(),
|
2017-03-12 05:09:10 +00:00
|
|
|
test_step: "test-crate-rustc-main".to_string(),
|
|
|
|
bench_step: "bench-crate-rustc-main".to_string(),
|
2016-12-30 19:50:57 -08:00
|
|
|
});
|
|
|
|
return build
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_baseline() {
|
|
|
|
let build = build(&["dist"], &[], &[]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
assert!(plan.iter().all(|s| s.host == "A" ));
|
|
|
|
assert!(plan.iter().all(|s| s.target == "A" ));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.name("dist-std")));
|
|
|
|
assert!(plan.contains(&step.name("dist-src")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_with_targets() {
|
|
|
|
let build = build(&["dist"], &[], &["B"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
assert!(plan.iter().all(|s| s.host == "A" ));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.name("dist-std")));
|
|
|
|
assert!(plan.contains(&step.name("dist-src")));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-mingw")));
|
|
|
|
assert!(!plan.contains(&step.target("B").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-std")));
|
|
|
|
assert!(!plan.contains(&step.target("B").name("dist-src")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_with_hosts() {
|
|
|
|
let build = build(&["dist"], &["B"], &[]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.name("dist-std")));
|
|
|
|
assert!(plan.contains(&step.name("dist-src")));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-std")));
|
|
|
|
assert!(!plan.contains(&step.target("B").name("dist-src")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_with_targets_and_hosts() {
|
|
|
|
let build = build(&["dist"], &["B"], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "C"));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.name("dist-std")));
|
|
|
|
assert!(plan.contains(&step.name("dist-src")));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-std")));
|
|
|
|
assert!(!plan.contains(&step.target("B").name("dist-src")));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-mingw")));
|
|
|
|
assert!(!plan.contains(&step.target("C").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-std")));
|
|
|
|
assert!(!plan.contains(&step.target("C").name("dist-src")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_target_with_target_flag() {
|
|
|
|
let build = build(&["dist", "--target=C"], &["B"], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(!plan.iter().any(|s| s.target == "A"));
|
|
|
|
assert!(!plan.iter().any(|s| s.target == "B"));
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "C"));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-mingw")));
|
|
|
|
assert!(!plan.contains(&step.target("C").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("C").name("dist-std")));
|
|
|
|
assert!(!plan.contains(&step.target("C").name("dist-src")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dist_host_with_target_flag() {
|
|
|
|
let build = build(&["dist", "--host=B", "--target=B"], &["B"], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
assert!(!plan.iter().any(|s| s.target == "A"));
|
|
|
|
assert!(!plan.iter().any(|s| s.target == "C"));
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "B"));
|
|
|
|
assert!(!plan.iter().any(|s| s.host == "C"));
|
|
|
|
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-docs")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-mingw")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-rustc")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-std")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("dist-src")));
|
|
|
|
|
|
|
|
let all = rules.expand(&plan);
|
|
|
|
println!("all rules: {:#?}", all);
|
|
|
|
assert!(!all.contains(&step.name("rustc")));
|
2017-02-15 15:57:06 -08:00
|
|
|
assert!(!all.contains(&step.name("build-crate-test").stage(1)));
|
2017-01-12 16:43:44 -08:00
|
|
|
|
|
|
|
// all stage0 compiles should be for the build target, A
|
|
|
|
for step in all.iter().filter(|s| s.stage == 0) {
|
|
|
|
if !step.name.contains("build-crate") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
println!("step: {:?}", step);
|
|
|
|
assert!(step.host != "B");
|
|
|
|
assert!(step.target != "B");
|
|
|
|
assert!(step.host != "C");
|
|
|
|
assert!(step.target != "C");
|
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn build_default() {
|
|
|
|
let build = build(&["build"], &["B"], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
let step = super::Step {
|
|
|
|
name: "",
|
|
|
|
stage: 2,
|
2017-06-27 15:59:43 -06:00
|
|
|
host: &build.build,
|
|
|
|
target: &build.build,
|
2016-12-30 19:50:57 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
// rustc built for all for of (A, B) x (A, B)
|
|
|
|
assert!(plan.contains(&step.name("librustc")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("librustc")));
|
|
|
|
assert!(plan.contains(&step.host("B").target("A").name("librustc")));
|
|
|
|
assert!(plan.contains(&step.host("B").target("B").name("librustc")));
|
|
|
|
|
|
|
|
// rustc never built for C
|
|
|
|
assert!(!plan.iter().any(|s| {
|
|
|
|
s.name.contains("rustc") && (s.host == "C" || s.target == "C")
|
|
|
|
}));
|
|
|
|
|
|
|
|
// test built for everything
|
|
|
|
assert!(plan.contains(&step.name("libtest")));
|
|
|
|
assert!(plan.contains(&step.target("B").name("libtest")));
|
|
|
|
assert!(plan.contains(&step.host("B").target("A").name("libtest")));
|
|
|
|
assert!(plan.contains(&step.host("B").target("B").name("libtest")));
|
|
|
|
assert!(plan.contains(&step.host("A").target("C").name("libtest")));
|
|
|
|
assert!(plan.contains(&step.host("B").target("C").name("libtest")));
|
|
|
|
|
|
|
|
let all = rules.expand(&plan);
|
|
|
|
println!("all rules: {:#?}", all);
|
|
|
|
assert!(all.contains(&step.name("rustc")));
|
|
|
|
assert!(all.contains(&step.name("libstd")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn build_filtered() {
|
|
|
|
let build = build(&["build", "--target=C"], &["B"], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rustc")));
|
|
|
|
assert!(plan.iter().all(|s| {
|
2017-02-15 08:53:18 -08:00
|
|
|
!s.name.contains("test") || s.target == "C"
|
2016-12-30 19:50:57 -08:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_default() {
|
|
|
|
let build = build(&["test"], &[], &[]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
assert!(plan.iter().all(|s| s.host == "A"));
|
|
|
|
assert!(plan.iter().all(|s| s.target == "A"));
|
|
|
|
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("-ui")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("cfail")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("cfail-full")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("codegen-units")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("debuginfo")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("docs")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("error-index")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("incremental")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("linkchecker")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("mir-opt")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("pfail")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rfail")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rfail-full")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rmake")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rpass")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rpass-full")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rustc-all")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rustdoc")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("std-all")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("test-all")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("tidy")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("valgrind")));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_with_a_target() {
|
|
|
|
let build = build(&["test", "--target=C"], &[], &["C"]);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(plan.iter().all(|s| s.stage == 2));
|
|
|
|
assert!(plan.iter().all(|s| s.host == "A"));
|
|
|
|
assert!(plan.iter().all(|s| s.target == "C"));
|
|
|
|
|
2017-03-03 13:28:22 +03:00
|
|
|
assert!(plan.iter().any(|s| s.name.contains("-ui")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("ui-full")));
|
2016-12-30 19:50:57 -08:00
|
|
|
assert!(plan.iter().any(|s| s.name.contains("cfail")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("cfail-full")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("codegen-units")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("debuginfo")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("docs")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("error-index")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("incremental")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("linkchecker")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("mir-opt")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("pfail")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rfail")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rfail-full")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rmake")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("rpass")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rpass-full")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rustc-all")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("rustdoc")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("std-all")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("test-all")));
|
|
|
|
assert!(!plan.iter().any(|s| s.name.contains("tidy")));
|
|
|
|
assert!(plan.iter().any(|s| s.name.contains("valgrind")));
|
|
|
|
}
|
2017-06-15 13:24:08 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_disable_docs() {
|
|
|
|
let build = build_(&["test"], &[], &[], false);
|
|
|
|
let rules = super::build_rules(&build);
|
|
|
|
let plan = rules.plan();
|
|
|
|
println!("rules: {:#?}", plan);
|
|
|
|
assert!(!plan.iter().any(|s| {
|
|
|
|
s.name.contains("doc-") || s.name.contains("default:doc")
|
|
|
|
}));
|
|
|
|
// none of the dependencies should be a doc rule either
|
|
|
|
assert!(!plan.iter().any(|s| {
|
|
|
|
rules.rules[s.name].deps.iter().any(|dep| {
|
|
|
|
let dep = dep(&rules.sbuild.name(s.name));
|
|
|
|
dep.name.contains("doc-") || dep.name.contains("default:doc")
|
|
|
|
})
|
|
|
|
}));
|
|
|
|
}
|
2016-12-30 19:50:57 -08:00
|
|
|
}
|