Auto merge of #43630 - Mark-Simulacrum:rustbuild-cleanups, r=alexcrichton
Rustbuild cleanups/fixes and improvements Each commit is a standalone change, and can/should be reviewed separately. This adds two new functionalities: - `--target` and `--host` can be passed without changing config.toml, and we'll respect the users' wishes, instead of requiring that all possible targets are passed. - Note that this means that `./x.py clean` won't be quite as wide-spread as before, since it limits itself to the configured hosts, not all hosts. This could be considered a feature as well. - `ignore-git` field in `config.toml` which tells Rustbuild to not attempt to load git hashes from `.git`. This is a precursor to eventual further simplification of the configuration system, but I want to get this merged first so that later work can be made in individual PRs. r? @alexcrichton
This commit is contained in:
commit
adbce60d6f
17 changed files with 240 additions and 190 deletions
|
@ -258,6 +258,9 @@
|
||||||
# saying that the FileCheck executable is missing, you may want to disable this.
|
# saying that the FileCheck executable is missing, you may want to disable this.
|
||||||
#codegen-tests = true
|
#codegen-tests = true
|
||||||
|
|
||||||
|
# Flag indicating whether git info will be retrieved from .git automatically.
|
||||||
|
#ignore-git = false
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Options for specific targets
|
# Options for specific targets
|
||||||
#
|
#
|
||||||
|
|
|
@ -21,11 +21,10 @@ extern crate bootstrap;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use bootstrap::{Flags, Config, Build};
|
use bootstrap::{Config, Build};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||||
let flags = Flags::parse(&args);
|
let config = Config::parse(&args);
|
||||||
let config = Config::parse(&flags.build, flags.config.clone());
|
Build::new(config).build();
|
||||||
Build::new(flags, config).build();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,28 +120,19 @@ impl StepDescription {
|
||||||
fn maybe_run(&self, builder: &Builder, path: Option<&Path>) {
|
fn maybe_run(&self, builder: &Builder, path: Option<&Path>) {
|
||||||
let build = builder.build;
|
let build = builder.build;
|
||||||
let hosts = if self.only_build_targets || self.only_build {
|
let hosts = if self.only_build_targets || self.only_build {
|
||||||
&build.config.host[..1]
|
build.build_triple()
|
||||||
} else {
|
} else {
|
||||||
&build.hosts
|
&build.hosts
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine the actual targets participating in this rule.
|
// Determine the targets participating in this rule.
|
||||||
// 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.
|
|
||||||
let targets = if self.only_hosts {
|
let targets = if self.only_hosts {
|
||||||
// If --target was specified but --host wasn't specified,
|
if build.config.run_host_only {
|
||||||
// don't run any host-only tests. Also, respect any `--host`
|
|
||||||
// overrides as done for `hosts`.
|
|
||||||
if build.flags.host.len() > 0 {
|
|
||||||
&build.flags.host[..]
|
|
||||||
} else if build.flags.target.len() > 0 {
|
|
||||||
&[]
|
&[]
|
||||||
} else if self.only_build {
|
} else if self.only_build {
|
||||||
&build.config.host[..1]
|
build.build_triple()
|
||||||
} else {
|
} else {
|
||||||
&build.config.host[..]
|
&build.hosts
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
&build.targets
|
&build.targets
|
||||||
|
@ -288,7 +279,7 @@ impl<'a> Builder<'a> {
|
||||||
|
|
||||||
let builder = Builder {
|
let builder = Builder {
|
||||||
build: build,
|
build: build,
|
||||||
top_stage: build.flags.stage.unwrap_or(2),
|
top_stage: build.config.stage.unwrap_or(2),
|
||||||
kind: kind,
|
kind: kind,
|
||||||
cache: Cache::new(),
|
cache: Cache::new(),
|
||||||
stack: RefCell::new(Vec::new()),
|
stack: RefCell::new(Vec::new()),
|
||||||
|
@ -307,7 +298,7 @@ impl<'a> Builder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(build: &Build) {
|
pub fn run(build: &Build) {
|
||||||
let (kind, paths) = match build.flags.cmd {
|
let (kind, paths) = match build.config.cmd {
|
||||||
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
|
Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
|
||||||
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
|
Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
|
||||||
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
|
Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
|
||||||
|
@ -319,7 +310,7 @@ impl<'a> Builder<'a> {
|
||||||
|
|
||||||
let builder = Builder {
|
let builder = Builder {
|
||||||
build: build,
|
build: build,
|
||||||
top_stage: build.flags.stage.unwrap_or(2),
|
top_stage: build.config.stage.unwrap_or(2),
|
||||||
kind: kind,
|
kind: kind,
|
||||||
cache: Cache::new(),
|
cache: Cache::new(),
|
||||||
stack: RefCell::new(Vec::new()),
|
stack: RefCell::new(Vec::new()),
|
||||||
|
@ -414,22 +405,19 @@ impl<'a> Builder<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
|
pub fn rustdoc(&self, host: Interned<String>) -> PathBuf {
|
||||||
self.ensure(tool::Rustdoc { target_compiler: compiler })
|
self.ensure(tool::Rustdoc { host })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command {
|
pub fn rustdoc_cmd(&self, host: Interned<String>) -> Command {
|
||||||
let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc"));
|
let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc"));
|
||||||
|
let compiler = self.compiler(self.top_stage, host);
|
||||||
cmd
|
cmd
|
||||||
.env("RUSTC_STAGE", compiler.stage.to_string())
|
.env("RUSTC_STAGE", compiler.stage.to_string())
|
||||||
.env("RUSTC_SYSROOT", if compiler.is_snapshot(&self.build) {
|
.env("RUSTC_SYSROOT", self.sysroot(compiler))
|
||||||
INTERNER.intern_path(self.build.rustc_snapshot_libdir())
|
.env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build))
|
||||||
} else {
|
|
||||||
self.sysroot(compiler)
|
|
||||||
})
|
|
||||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
|
||||||
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
|
.env("CFG_RELEASE_CHANNEL", &self.build.config.channel)
|
||||||
.env("RUSTDOC_REAL", self.rustdoc(compiler));
|
.env("RUSTDOC_REAL", self.rustdoc(host));
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +471,7 @@ impl<'a> Builder<'a> {
|
||||||
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
||||||
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
||||||
.env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" {
|
.env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" {
|
||||||
self.rustdoc(compiler)
|
self.rustdoc(compiler.host)
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
||||||
})
|
})
|
||||||
|
@ -543,12 +531,12 @@ impl<'a> Builder<'a> {
|
||||||
// Ignore incremental modes except for stage0, since we're
|
// Ignore incremental modes except for stage0, since we're
|
||||||
// not guaranteeing correctness across builds if the compiler
|
// not guaranteeing correctness across builds if the compiler
|
||||||
// is changing under your feet.`
|
// is changing under your feet.`
|
||||||
if self.flags.incremental && compiler.stage == 0 {
|
if self.config.incremental && compiler.stage == 0 {
|
||||||
let incr_dir = self.incremental_dir(compiler);
|
let incr_dir = self.incremental_dir(compiler);
|
||||||
cargo.env("RUSTC_INCREMENTAL", incr_dir);
|
cargo.env("RUSTC_INCREMENTAL", incr_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref on_fail) = self.flags.on_fail {
|
if let Some(ref on_fail) = self.config.on_fail {
|
||||||
cargo.env("RUSTC_ON_FAIL", on_fail);
|
cargo.env("RUSTC_ON_FAIL", on_fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
//! everything.
|
//! everything.
|
||||||
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
use build_helper::{cc2ar, output};
|
use build_helper::{cc2ar, output};
|
||||||
use gcc;
|
use gcc;
|
||||||
|
@ -43,47 +44,41 @@ use cache::Interned;
|
||||||
pub fn find(build: &mut Build) {
|
pub fn find(build: &mut Build) {
|
||||||
// For all targets we're going to need a C compiler for building some shims
|
// For all targets we're going to need a C compiler for building some shims
|
||||||
// and such as well as for being a linker for Rust code.
|
// and such as well as for being a linker for Rust code.
|
||||||
//
|
for target in build.targets.iter().chain(&build.hosts).cloned().chain(iter::once(build.build)) {
|
||||||
// This includes targets that aren't necessarily passed on the commandline
|
|
||||||
// (FIXME: Perhaps it shouldn't?)
|
|
||||||
for target in &build.config.target {
|
|
||||||
let mut cfg = gcc::Config::new();
|
let mut cfg = gcc::Config::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).debug(false)
|
cfg.cargo_metadata(false).opt_level(0).debug(false)
|
||||||
.target(target).host(&build.build);
|
.target(&target).host(&build.build);
|
||||||
|
|
||||||
let config = build.config.target_config.get(&target);
|
let config = build.config.target_config.get(&target);
|
||||||
if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
|
if let Some(cc) = config.and_then(|c| c.cc.as_ref()) {
|
||||||
cfg.compiler(cc);
|
cfg.compiler(cc);
|
||||||
} else {
|
} else {
|
||||||
set_compiler(&mut cfg, "gcc", *target, config, build);
|
set_compiler(&mut cfg, "gcc", target, config, build);
|
||||||
}
|
}
|
||||||
|
|
||||||
let compiler = cfg.get_compiler();
|
let compiler = cfg.get_compiler();
|
||||||
let ar = cc2ar(compiler.path(), target);
|
let ar = cc2ar(compiler.path(), &target);
|
||||||
build.verbose(&format!("CC_{} = {:?}", target, compiler.path()));
|
build.verbose(&format!("CC_{} = {:?}", &target, compiler.path()));
|
||||||
if let Some(ref ar) = ar {
|
if let Some(ref ar) = ar {
|
||||||
build.verbose(&format!("AR_{} = {:?}", target, ar));
|
build.verbose(&format!("AR_{} = {:?}", &target, ar));
|
||||||
}
|
}
|
||||||
build.cc.insert(*target, (compiler, ar));
|
build.cc.insert(target, (compiler, ar));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all host triples we need to find a C++ compiler as well
|
// For all host triples we need to find a C++ compiler as well
|
||||||
//
|
for host in build.hosts.iter().cloned().chain(iter::once(build.build)) {
|
||||||
// This includes hosts that aren't necessarily passed on the commandline
|
|
||||||
// (FIXME: Perhaps it shouldn't?)
|
|
||||||
for host in &build.config.host {
|
|
||||||
let mut cfg = gcc::Config::new();
|
let mut cfg = gcc::Config::new();
|
||||||
cfg.cargo_metadata(false).opt_level(0).debug(false).cpp(true)
|
cfg.cargo_metadata(false).opt_level(0).debug(false).cpp(true)
|
||||||
.target(host).host(&build.build);
|
.target(&host).host(&build.build);
|
||||||
let config = build.config.target_config.get(host);
|
let config = build.config.target_config.get(&host);
|
||||||
if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
|
if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
|
||||||
cfg.compiler(cxx);
|
cfg.compiler(cxx);
|
||||||
} else {
|
} else {
|
||||||
set_compiler(&mut cfg, "g++", *host, config, build);
|
set_compiler(&mut cfg, "g++", host, config, build);
|
||||||
}
|
}
|
||||||
let compiler = cfg.get_compiler();
|
let compiler = cfg.get_compiler();
|
||||||
build.verbose(&format!("CXX_{} = {:?}", host, compiler.path()));
|
build.verbose(&format!("CXX_{} = {:?}", host, compiler.path()));
|
||||||
build.cxx.insert(*host, compiler);
|
build.cxx.insert(host, compiler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ use std::process::Command;
|
||||||
use build_helper::output;
|
use build_helper::output;
|
||||||
|
|
||||||
use Build;
|
use Build;
|
||||||
|
use config::Config;
|
||||||
|
|
||||||
// The version number
|
// The version number
|
||||||
pub const CFG_RELEASE_NUM: &str = "1.21.0";
|
pub const CFG_RELEASE_NUM: &str = "1.21.0";
|
||||||
|
@ -41,9 +42,9 @@ struct Info {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GitInfo {
|
impl GitInfo {
|
||||||
pub fn new(dir: &Path) -> GitInfo {
|
pub fn new(config: &Config, dir: &Path) -> GitInfo {
|
||||||
// See if this even begins to look like a git dir
|
// See if this even begins to look like a git dir
|
||||||
if !dir.join(".git").exists() {
|
if config.ignore_git || !dir.join(".git").exists() {
|
||||||
return GitInfo { inner: None }
|
return GitInfo { inner: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl Step for Cargotest {
|
||||||
try_run(build, cmd.arg(&build.initial_cargo)
|
try_run(build, cmd.arg(&build.initial_cargo)
|
||||||
.arg(&out_dir)
|
.arg(&out_dir)
|
||||||
.env("RUSTC", builder.rustc(compiler))
|
.env("RUSTC", builder.rustc(compiler))
|
||||||
.env("RUSTDOC", builder.rustdoc(compiler)));
|
.env("RUSTDOC", builder.rustdoc(compiler.host)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +565,7 @@ impl Step for Compiletest {
|
||||||
|
|
||||||
// Avoid depending on rustdoc when we don't need it.
|
// Avoid depending on rustdoc when we don't need it.
|
||||||
if mode == "rustdoc" || mode == "run-make" {
|
if mode == "rustdoc" || mode == "run-make" {
|
||||||
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
|
cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler.host));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
|
cmd.arg("--src-base").arg(build.src.join("src/test").join(suite));
|
||||||
|
@ -625,7 +625,7 @@ impl Step for Compiletest {
|
||||||
cmd.arg("--system-llvm");
|
cmd.arg("--system-llvm");
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.args(&build.flags.cmd.test_args());
|
cmd.args(&build.config.cmd.test_args());
|
||||||
|
|
||||||
if build.is_verbose() {
|
if build.is_verbose() {
|
||||||
cmd.arg("--verbose");
|
cmd.arg("--verbose");
|
||||||
|
@ -814,13 +814,13 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("doc tests for: {}", markdown.display());
|
println!("doc tests for: {}", markdown.display());
|
||||||
let mut cmd = builder.rustdoc_cmd(compiler);
|
let mut cmd = builder.rustdoc_cmd(compiler.host);
|
||||||
build.add_rust_test_threads(&mut cmd);
|
build.add_rust_test_threads(&mut cmd);
|
||||||
cmd.arg("--test");
|
cmd.arg("--test");
|
||||||
cmd.arg(markdown);
|
cmd.arg(markdown);
|
||||||
cmd.env("RUSTC_BOOTSTRAP", "1");
|
cmd.env("RUSTC_BOOTSTRAP", "1");
|
||||||
|
|
||||||
let test_args = build.flags.cmd.test_args().join(" ");
|
let test_args = build.config.cmd.test_args().join(" ");
|
||||||
cmd.arg("--test-args").arg(test_args);
|
cmd.arg("--test-args").arg(test_args);
|
||||||
|
|
||||||
if build.config.quiet_tests {
|
if build.config.quiet_tests {
|
||||||
|
@ -1051,7 +1051,7 @@ impl Step for Crate {
|
||||||
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||||
|
|
||||||
cargo.arg("--");
|
cargo.arg("--");
|
||||||
cargo.args(&build.flags.cmd.test_args());
|
cargo.args(&build.config.cmd.test_args());
|
||||||
|
|
||||||
if build.config.quiet_tests {
|
if build.config.quiet_tests {
|
||||||
cargo.arg("--quiet");
|
cargo.arg("--quiet");
|
||||||
|
@ -1147,6 +1147,7 @@ pub struct Distcheck;
|
||||||
|
|
||||||
impl Step for Distcheck {
|
impl Step for Distcheck {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
const ONLY_BUILD: bool = true;
|
||||||
|
|
||||||
fn should_run(run: ShouldRun) -> ShouldRun {
|
fn should_run(run: ShouldRun) -> ShouldRun {
|
||||||
run.path("distcheck")
|
run.path("distcheck")
|
||||||
|
@ -1160,16 +1161,6 @@ impl Step for Distcheck {
|
||||||
fn run(self, builder: &Builder) {
|
fn run(self, builder: &Builder) {
|
||||||
let build = builder.build;
|
let build = builder.build;
|
||||||
|
|
||||||
if *build.build != *"x86_64-unknown-linux-gnu" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !build.config.target.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Distcheck");
|
println!("Distcheck");
|
||||||
let dir = build.out.join("tmp").join("distcheck");
|
let dir = build.out.join("tmp").join("distcheck");
|
||||||
let _ = fs::remove_dir_all(&dir);
|
let _ = fs::remove_dir_all(&dir);
|
||||||
|
@ -1236,7 +1227,7 @@ impl Step for Bootstrap {
|
||||||
if !build.fail_fast {
|
if !build.fail_fast {
|
||||||
cmd.arg("--no-fail-fast");
|
cmd.arg("--no-fail-fast");
|
||||||
}
|
}
|
||||||
cmd.arg("--").args(&build.flags.cmd.test_args());
|
cmd.arg("--").args(&build.config.cmd.test_args());
|
||||||
try_run(build, &mut cmd);
|
try_run(build, &mut cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub fn clean(build: &Build) {
|
||||||
rm_rf(&build.out.join("tmp"));
|
rm_rf(&build.out.join("tmp"));
|
||||||
rm_rf(&build.out.join("dist"));
|
rm_rf(&build.out.join("dist"));
|
||||||
|
|
||||||
for host in build.config.host.iter() {
|
for host in &build.hosts {
|
||||||
let entries = match build.out.join(host).read_dir() {
|
let entries = match build.out.join(host).read_dir() {
|
||||||
Ok(iter) => iter,
|
Ok(iter) => iter,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
|
|
|
@ -32,6 +32,7 @@ use serde_json;
|
||||||
use util::{exe, libdir, is_dylib, copy};
|
use util::{exe, libdir, is_dylib, copy};
|
||||||
use {Build, Compiler, Mode};
|
use {Build, Compiler, Mode};
|
||||||
use native;
|
use native;
|
||||||
|
use tool;
|
||||||
|
|
||||||
use cache::{INTERNER, Interned};
|
use cache::{INTERNER, Interned};
|
||||||
use builder::{Step, RunConfig, ShouldRun, Builder};
|
use builder::{Step, RunConfig, ShouldRun, Builder};
|
||||||
|
@ -198,6 +199,12 @@ impl Step for StdLink {
|
||||||
// for reason why the sanitizers are not built in stage0.
|
// for reason why the sanitizers are not built in stage0.
|
||||||
copy_apple_sanitizer_dylibs(&build.native_dir(target), "osx", &libdir);
|
copy_apple_sanitizer_dylibs(&build.native_dir(target), "osx", &libdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
builder.ensure(tool::CleanTools {
|
||||||
|
compiler: target_compiler,
|
||||||
|
target: target,
|
||||||
|
mode: Mode::Libstd,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,6 +396,11 @@ impl Step for TestLink {
|
||||||
target);
|
target);
|
||||||
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
||||||
&libtest_stamp(build, compiler, target));
|
&libtest_stamp(build, compiler, target));
|
||||||
|
builder.ensure(tool::CleanTools {
|
||||||
|
compiler: target_compiler,
|
||||||
|
target: target,
|
||||||
|
mode: Mode::Libtest,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,6 +579,11 @@ impl Step for RustcLink {
|
||||||
target);
|
target);
|
||||||
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
||||||
&librustc_stamp(build, compiler, target));
|
&librustc_stamp(build, compiler, target));
|
||||||
|
builder.ensure(tool::CleanTools {
|
||||||
|
compiler: target_compiler,
|
||||||
|
target: target,
|
||||||
|
mode: Mode::Librustc,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,10 +696,10 @@ impl Step for Assemble {
|
||||||
// link to these. (FIXME: Is that correct? It seems to be correct most
|
// link to these. (FIXME: Is that correct? It seems to be correct most
|
||||||
// of the time but I think we do link to these for stage2/bin compilers
|
// of the time but I think we do link to these for stage2/bin compilers
|
||||||
// when not performing a full bootstrap).
|
// when not performing a full bootstrap).
|
||||||
if builder.build.flags.keep_stage.map_or(false, |s| target_compiler.stage <= s) {
|
if builder.build.config.keep_stage.map_or(false, |s| target_compiler.stage <= s) {
|
||||||
builder.verbose("skipping compilation of compiler due to --keep-stage");
|
builder.verbose("skipping compilation of compiler due to --keep-stage");
|
||||||
let compiler = build_compiler;
|
let compiler = build_compiler;
|
||||||
for stage in 0..min(target_compiler.stage, builder.flags.keep_stage.unwrap()) {
|
for stage in 0..min(target_compiler.stage, builder.config.keep_stage.unwrap()) {
|
||||||
let target_compiler = builder.compiler(stage, target_compiler.host);
|
let target_compiler = builder.compiler(stage, target_compiler.host);
|
||||||
let target = target_compiler.host;
|
let target = target_compiler.host;
|
||||||
builder.ensure(StdLink { compiler, target_compiler, target });
|
builder.ensure(StdLink { compiler, target_compiler, target });
|
||||||
|
|
|
@ -19,11 +19,14 @@ use std::fs::{self, File};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use std::cmp;
|
||||||
|
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
use toml;
|
use toml;
|
||||||
use util::{exe, push_exe_path};
|
use util::{exe, push_exe_path};
|
||||||
use cache::{INTERNER, Interned};
|
use cache::{INTERNER, Interned};
|
||||||
|
use flags::Flags;
|
||||||
|
pub use flags::Subcommand;
|
||||||
|
|
||||||
/// Global configuration for the entire build and/or bootstrap.
|
/// Global configuration for the entire build and/or bootstrap.
|
||||||
///
|
///
|
||||||
|
@ -51,6 +54,17 @@ pub struct Config {
|
||||||
pub extended: bool,
|
pub extended: bool,
|
||||||
pub sanitizers: bool,
|
pub sanitizers: bool,
|
||||||
pub profiler: bool,
|
pub profiler: bool,
|
||||||
|
pub ignore_git: bool,
|
||||||
|
|
||||||
|
pub run_host_only: bool,
|
||||||
|
|
||||||
|
pub on_fail: Option<String>,
|
||||||
|
pub stage: Option<u32>,
|
||||||
|
pub keep_stage: Option<u32>,
|
||||||
|
pub src: PathBuf,
|
||||||
|
pub jobs: Option<u32>,
|
||||||
|
pub cmd: Subcommand,
|
||||||
|
pub incremental: bool,
|
||||||
|
|
||||||
// llvm codegen options
|
// llvm codegen options
|
||||||
pub llvm_enabled: bool,
|
pub llvm_enabled: bool,
|
||||||
|
@ -79,8 +93,8 @@ pub struct Config {
|
||||||
pub rust_dist_src: bool,
|
pub rust_dist_src: bool,
|
||||||
|
|
||||||
pub build: Interned<String>,
|
pub build: Interned<String>,
|
||||||
pub host: Vec<Interned<String>>,
|
pub hosts: Vec<Interned<String>>,
|
||||||
pub target: Vec<Interned<String>>,
|
pub targets: Vec<Interned<String>>,
|
||||||
pub local_rebuild: bool,
|
pub local_rebuild: bool,
|
||||||
|
|
||||||
// dist misc
|
// dist misc
|
||||||
|
@ -249,6 +263,7 @@ struct Rust {
|
||||||
optimize_tests: Option<bool>,
|
optimize_tests: Option<bool>,
|
||||||
debuginfo_tests: Option<bool>,
|
debuginfo_tests: Option<bool>,
|
||||||
codegen_tests: Option<bool>,
|
codegen_tests: Option<bool>,
|
||||||
|
ignore_git: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TOML representation of how each build target is configured.
|
/// TOML representation of how each build target is configured.
|
||||||
|
@ -265,7 +280,9 @@ struct TomlTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
|
pub fn parse(args: &[String]) -> Config {
|
||||||
|
let flags = Flags::parse(&args);
|
||||||
|
let file = flags.config.clone();
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.llvm_enabled = true;
|
config.llvm_enabled = true;
|
||||||
config.llvm_optimize = true;
|
config.llvm_optimize = true;
|
||||||
|
@ -277,11 +294,22 @@ impl Config {
|
||||||
config.docs = true;
|
config.docs = true;
|
||||||
config.rust_rpath = true;
|
config.rust_rpath = true;
|
||||||
config.rust_codegen_units = 1;
|
config.rust_codegen_units = 1;
|
||||||
config.build = INTERNER.intern_str(build);
|
|
||||||
config.channel = "dev".to_string();
|
config.channel = "dev".to_string();
|
||||||
config.codegen_tests = true;
|
config.codegen_tests = true;
|
||||||
|
config.ignore_git = false;
|
||||||
config.rust_dist_src = true;
|
config.rust_dist_src = true;
|
||||||
|
|
||||||
|
config.on_fail = flags.on_fail;
|
||||||
|
config.stage = flags.stage;
|
||||||
|
config.src = flags.src;
|
||||||
|
config.jobs = flags.jobs;
|
||||||
|
config.cmd = flags.cmd;
|
||||||
|
config.incremental = flags.incremental;
|
||||||
|
config.keep_stage = flags.keep_stage;
|
||||||
|
|
||||||
|
// If --target was specified but --host wasn't specified, don't run any host-only tests.
|
||||||
|
config.run_host_only = flags.host.is_empty() && !flags.target.is_empty();
|
||||||
|
|
||||||
let toml = file.map(|file| {
|
let toml = file.map(|file| {
|
||||||
let mut f = t!(File::open(&file));
|
let mut f = t!(File::open(&file));
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
|
@ -298,20 +326,37 @@ impl Config {
|
||||||
|
|
||||||
let build = toml.build.clone().unwrap_or(Build::default());
|
let build = toml.build.clone().unwrap_or(Build::default());
|
||||||
set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x)));
|
set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x)));
|
||||||
config.host.push(config.build.clone());
|
set(&mut config.build, flags.build);
|
||||||
|
if config.build.is_empty() {
|
||||||
|
// set by bootstrap.py
|
||||||
|
config.build = INTERNER.intern_str(&env::var("BUILD").unwrap());
|
||||||
|
}
|
||||||
|
config.hosts.push(config.build.clone());
|
||||||
for host in build.host.iter() {
|
for host in build.host.iter() {
|
||||||
let host = INTERNER.intern_str(host);
|
let host = INTERNER.intern_str(host);
|
||||||
if !config.host.contains(&host) {
|
if !config.hosts.contains(&host) {
|
||||||
config.host.push(host);
|
config.hosts.push(host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for target in config.host.iter().cloned()
|
for target in config.hosts.iter().cloned()
|
||||||
.chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
|
.chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
|
||||||
{
|
{
|
||||||
if !config.target.contains(&target) {
|
if !config.targets.contains(&target) {
|
||||||
config.target.push(target);
|
config.targets.push(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
config.hosts = if !flags.host.is_empty() {
|
||||||
|
flags.host
|
||||||
|
} else {
|
||||||
|
config.hosts
|
||||||
|
};
|
||||||
|
config.targets = if !flags.target.is_empty() {
|
||||||
|
flags.target
|
||||||
|
} else {
|
||||||
|
config.targets
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
config.nodejs = build.nodejs.map(PathBuf::from);
|
config.nodejs = build.nodejs.map(PathBuf::from);
|
||||||
config.gdb = build.gdb.map(PathBuf::from);
|
config.gdb = build.gdb.map(PathBuf::from);
|
||||||
config.python = build.python.map(PathBuf::from);
|
config.python = build.python.map(PathBuf::from);
|
||||||
|
@ -327,6 +372,7 @@ impl Config {
|
||||||
set(&mut config.sanitizers, build.sanitizers);
|
set(&mut config.sanitizers, build.sanitizers);
|
||||||
set(&mut config.profiler, build.profiler);
|
set(&mut config.profiler, build.profiler);
|
||||||
set(&mut config.openssl_static, build.openssl_static);
|
set(&mut config.openssl_static, build.openssl_static);
|
||||||
|
config.verbose = cmp::max(config.verbose, flags.verbose);
|
||||||
|
|
||||||
if let Some(ref install) = toml.install {
|
if let Some(ref install) = toml.install {
|
||||||
config.prefix = install.prefix.clone().map(PathBuf::from);
|
config.prefix = install.prefix.clone().map(PathBuf::from);
|
||||||
|
@ -373,6 +419,7 @@ impl Config {
|
||||||
set(&mut config.use_jemalloc, rust.use_jemalloc);
|
set(&mut config.use_jemalloc, rust.use_jemalloc);
|
||||||
set(&mut config.backtrace, rust.backtrace);
|
set(&mut config.backtrace, rust.backtrace);
|
||||||
set(&mut config.channel, rust.channel.clone());
|
set(&mut config.channel, rust.channel.clone());
|
||||||
|
set(&mut config.ignore_git, rust.ignore_git);
|
||||||
config.rustc_default_linker = rust.default_linker.clone();
|
config.rustc_default_linker = rust.default_linker.clone();
|
||||||
config.rustc_default_ar = rust.default_ar.clone();
|
config.rustc_default_ar = rust.default_ar.clone();
|
||||||
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
config.musl_root = rust.musl_root.clone().map(PathBuf::from);
|
||||||
|
@ -505,11 +552,11 @@ impl Config {
|
||||||
match key {
|
match key {
|
||||||
"CFG_BUILD" if value.len() > 0 => self.build = INTERNER.intern_str(value),
|
"CFG_BUILD" if value.len() > 0 => self.build = INTERNER.intern_str(value),
|
||||||
"CFG_HOST" if value.len() > 0 => {
|
"CFG_HOST" if value.len() > 0 => {
|
||||||
self.host.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
self.hosts.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
||||||
|
|
||||||
}
|
}
|
||||||
"CFG_TARGET" if value.len() > 0 => {
|
"CFG_TARGET" if value.len() > 0 => {
|
||||||
self.target.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
self.targets.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
||||||
}
|
}
|
||||||
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
|
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
|
||||||
self.llvm_experimental_targets = Some(value.to_string());
|
self.llvm_experimental_targets = Some(value.to_string());
|
||||||
|
|
|
@ -413,8 +413,7 @@ impl Step for Rustc {
|
||||||
t!(fs::create_dir_all(image.join("bin")));
|
t!(fs::create_dir_all(image.join("bin")));
|
||||||
cp_r(&src.join("bin"), &image.join("bin"));
|
cp_r(&src.join("bin"), &image.join("bin"));
|
||||||
|
|
||||||
install(&builder.ensure(tool::Rustdoc { target_compiler: compiler }),
|
install(&builder.rustdoc(compiler.host), &image.join("bin"), 0o755);
|
||||||
&image.join("bin"), 0o755);
|
|
||||||
|
|
||||||
// Copy runtime DLLs needed by the compiler
|
// Copy runtime DLLs needed by the compiler
|
||||||
if libdir != "bin" {
|
if libdir != "bin" {
|
||||||
|
@ -546,7 +545,7 @@ impl Step for Std {
|
||||||
// We want to package up as many target libraries as possible
|
// We want to package up as many target libraries as possible
|
||||||
// for the `rust-std` package, so if this is a host target we
|
// for the `rust-std` package, so if this is a host target we
|
||||||
// depend on librustc and otherwise we just depend on libtest.
|
// depend on librustc and otherwise we just depend on libtest.
|
||||||
if build.config.host.iter().any(|t| t == target) {
|
if build.hosts.iter().any(|t| t == target) {
|
||||||
builder.ensure(compile::Rustc { compiler, target });
|
builder.ensure(compile::Rustc { compiler, target });
|
||||||
} else {
|
} else {
|
||||||
builder.ensure(compile::Test { compiler, target });
|
builder.ensure(compile::Test { compiler, target });
|
||||||
|
|
|
@ -260,7 +260,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned<String
|
||||||
t!(t!(File::create(&version_info)).write_all(info.as_bytes()));
|
t!(t!(File::create(&version_info)).write_all(info.as_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cmd = builder.rustdoc_cmd(compiler);
|
let mut cmd = builder.rustdoc_cmd(compiler.host);
|
||||||
|
|
||||||
let out = out.join("book");
|
let out = out.join("book");
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ impl Step for Standalone {
|
||||||
}
|
}
|
||||||
|
|
||||||
let html = out.join(filename).with_extension("html");
|
let html = out.join(filename).with_extension("html");
|
||||||
let rustdoc = builder.rustdoc(compiler);
|
let rustdoc = builder.rustdoc(compiler.host);
|
||||||
if up_to_date(&path, &html) &&
|
if up_to_date(&path, &html) &&
|
||||||
up_to_date(&footer, &html) &&
|
up_to_date(&footer, &html) &&
|
||||||
up_to_date(&favicon, &html) &&
|
up_to_date(&favicon, &html) &&
|
||||||
|
@ -353,7 +353,7 @@ impl Step for Standalone {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut cmd = builder.rustdoc_cmd(compiler);
|
let mut cmd = builder.rustdoc_cmd(compiler.host);
|
||||||
cmd.arg("--html-after-content").arg(&footer)
|
cmd.arg("--html-after-content").arg(&footer)
|
||||||
.arg("--html-before-content").arg(&version_info)
|
.arg("--html-before-content").arg(&version_info)
|
||||||
.arg("--html-in-header").arg(&favicon)
|
.arg("--html-in-header").arg(&favicon)
|
||||||
|
@ -408,7 +408,7 @@ impl Step for Std {
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = builder.compiler(stage, build.build);
|
let compiler = builder.compiler(stage, build.build);
|
||||||
let rustdoc = builder.rustdoc(compiler);
|
let rustdoc = builder.rustdoc(compiler.host);
|
||||||
let compiler = if build.force_use_stage1(compiler, target) {
|
let compiler = if build.force_use_stage1(compiler, target) {
|
||||||
builder.compiler(1, compiler.host)
|
builder.compiler(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
|
@ -493,7 +493,7 @@ impl Step for Test {
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = builder.compiler(stage, build.build);
|
let compiler = builder.compiler(stage, build.build);
|
||||||
let rustdoc = builder.rustdoc(compiler);
|
let rustdoc = builder.rustdoc(compiler.host);
|
||||||
let compiler = if build.force_use_stage1(compiler, target) {
|
let compiler = if build.force_use_stage1(compiler, target) {
|
||||||
builder.compiler(1, compiler.host)
|
builder.compiler(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
|
@ -554,7 +554,7 @@ impl Step for Rustc {
|
||||||
let out = build.doc_out(target);
|
let out = build.doc_out(target);
|
||||||
t!(fs::create_dir_all(&out));
|
t!(fs::create_dir_all(&out));
|
||||||
let compiler = builder.compiler(stage, build.build);
|
let compiler = builder.compiler(stage, build.build);
|
||||||
let rustdoc = builder.rustdoc(compiler);
|
let rustdoc = builder.rustdoc(compiler.host);
|
||||||
let compiler = if build.force_use_stage1(compiler, target) {
|
let compiler = if build.force_use_stage1(compiler, target) {
|
||||||
builder.compiler(1, compiler.host)
|
builder.compiler(1, compiler.host)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,7 +33,8 @@ pub struct Flags {
|
||||||
pub on_fail: Option<String>,
|
pub on_fail: Option<String>,
|
||||||
pub stage: Option<u32>,
|
pub stage: Option<u32>,
|
||||||
pub keep_stage: Option<u32>,
|
pub keep_stage: Option<u32>,
|
||||||
pub build: Interned<String>,
|
pub build: Option<Interned<String>>,
|
||||||
|
|
||||||
pub host: Vec<Interned<String>>,
|
pub host: Vec<Interned<String>>,
|
||||||
pub target: Vec<Interned<String>>,
|
pub target: Vec<Interned<String>>,
|
||||||
pub config: Option<PathBuf>,
|
pub config: Option<PathBuf>,
|
||||||
|
@ -68,6 +69,14 @@ pub enum Subcommand {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Subcommand {
|
||||||
|
fn default() -> Subcommand {
|
||||||
|
Subcommand::Build {
|
||||||
|
paths: vec![PathBuf::from("nowhere")],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Flags {
|
impl Flags {
|
||||||
pub fn parse(args: &[String]) -> Flags {
|
pub fn parse(args: &[String]) -> Flags {
|
||||||
let mut extra_help = String::new();
|
let mut extra_help = String::new();
|
||||||
|
@ -243,10 +252,8 @@ Arguments:
|
||||||
|
|
||||||
// All subcommands can have an optional "Available paths" section
|
// All subcommands can have an optional "Available paths" section
|
||||||
if matches.opt_present("verbose") {
|
if matches.opt_present("verbose") {
|
||||||
let flags = Flags::parse(&["build".to_string()]);
|
let config = Config::parse(&["build".to_string()]);
|
||||||
let mut config = Config::parse(&flags.build, cfg_file.clone());
|
let mut build = Build::new(config);
|
||||||
config.build = flags.build.clone();
|
|
||||||
let mut build = Build::new(flags, config);
|
|
||||||
metadata::build(&mut build);
|
metadata::build(&mut build);
|
||||||
|
|
||||||
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
|
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
|
||||||
|
@ -320,9 +327,7 @@ Arguments:
|
||||||
stage: stage,
|
stage: stage,
|
||||||
on_fail: matches.opt_str("on-fail"),
|
on_fail: matches.opt_str("on-fail"),
|
||||||
keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
|
keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
|
||||||
build: INTERNER.intern_string(matches.opt_str("build").unwrap_or_else(|| {
|
build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
|
||||||
env::var("BUILD").unwrap()
|
|
||||||
})),
|
|
||||||
host: split(matches.opt_strs("host"))
|
host: split(matches.opt_strs("host"))
|
||||||
.into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
|
.into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
|
||||||
target: split(matches.opt_strs("target"))
|
target: split(matches.opt_strs("target"))
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn install_docs(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install_std(builder: &Builder, stage: u32) {
|
pub fn install_std(builder: &Builder, stage: u32) {
|
||||||
for target in builder.build.config.target.iter() {
|
for target in &builder.build.targets {
|
||||||
install_sh(builder, "std", "rust-std", stage, Some(*target));
|
install_sh(builder, "std", "rust-std", stage, Some(*target));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,13 +136,13 @@ extern crate toml;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp;
|
|
||||||
use std::collections::{HashSet, HashMap};
|
use std::collections::{HashSet, HashMap};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::{PathBuf, Path};
|
use std::path::{PathBuf, Path};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime};
|
use build_helper::{run_silent, run_suppressed, try_run_silent, try_run_suppressed, output, mtime};
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ mod job {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use flags::{Flags, Subcommand};
|
use flags::Subcommand;
|
||||||
use cache::{Interned, INTERNER};
|
use cache::{Interned, INTERNER};
|
||||||
|
|
||||||
/// A structure representing a Rust compiler.
|
/// A structure representing a Rust compiler.
|
||||||
|
@ -215,9 +215,6 @@ pub struct Build {
|
||||||
// User-specified configuration via config.toml
|
// User-specified configuration via config.toml
|
||||||
config: Config,
|
config: Config,
|
||||||
|
|
||||||
// User-specified configuration via CLI flags
|
|
||||||
flags: Flags,
|
|
||||||
|
|
||||||
// Derived properties from the above two configurations
|
// Derived properties from the above two configurations
|
||||||
src: PathBuf,
|
src: PathBuf,
|
||||||
out: PathBuf,
|
out: PathBuf,
|
||||||
|
@ -288,9 +285,9 @@ impl Build {
|
||||||
/// line and the filesystem `config`.
|
/// line and the filesystem `config`.
|
||||||
///
|
///
|
||||||
/// By default all build output will be placed in the current directory.
|
/// By default all build output will be placed in the current directory.
|
||||||
pub fn new(flags: Flags, config: Config) -> Build {
|
pub fn new(config: Config) -> Build {
|
||||||
let cwd = t!(env::current_dir());
|
let cwd = t!(env::current_dir());
|
||||||
let src = flags.src.clone();
|
let src = config.src.clone();
|
||||||
let out = cwd.join("build");
|
let out = cwd.join("build");
|
||||||
|
|
||||||
let is_sudo = match env::var_os("SUDO_USER") {
|
let is_sudo = match env::var_os("SUDO_USER") {
|
||||||
|
@ -302,43 +299,21 @@ impl Build {
|
||||||
}
|
}
|
||||||
None => false,
|
None => false,
|
||||||
};
|
};
|
||||||
let rust_info = channel::GitInfo::new(&src);
|
let rust_info = channel::GitInfo::new(&config, &src);
|
||||||
let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo"));
|
let cargo_info = channel::GitInfo::new(&config, &src.join("src/tools/cargo"));
|
||||||
let rls_info = channel::GitInfo::new(&src.join("src/tools/rls"));
|
let rls_info = channel::GitInfo::new(&config, &src.join("src/tools/rls"));
|
||||||
|
|
||||||
let hosts = if !flags.host.is_empty() {
|
|
||||||
for host in flags.host.iter() {
|
|
||||||
if !config.host.contains(host) {
|
|
||||||
panic!("specified host `{}` is not in configuration", host);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flags.host.clone()
|
|
||||||
} else {
|
|
||||||
config.host.clone()
|
|
||||||
};
|
|
||||||
let targets = if !flags.target.is_empty() {
|
|
||||||
for target in flags.target.iter() {
|
|
||||||
if !config.target.contains(target) {
|
|
||||||
panic!("specified target `{}` is not in configuration", target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flags.target.clone()
|
|
||||||
} else {
|
|
||||||
config.target.clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
Build {
|
Build {
|
||||||
initial_rustc: config.initial_rustc.clone(),
|
initial_rustc: config.initial_rustc.clone(),
|
||||||
initial_cargo: config.initial_cargo.clone(),
|
initial_cargo: config.initial_cargo.clone(),
|
||||||
local_rebuild: config.local_rebuild,
|
local_rebuild: config.local_rebuild,
|
||||||
fail_fast: flags.cmd.fail_fast(),
|
fail_fast: config.cmd.fail_fast(),
|
||||||
verbosity: cmp::max(flags.verbose, config.verbose),
|
verbosity: config.verbose,
|
||||||
|
|
||||||
build: config.host[0].clone(),
|
build: config.build,
|
||||||
hosts: hosts,
|
hosts: config.hosts.clone(),
|
||||||
targets: targets,
|
targets: config.targets.clone(),
|
||||||
|
|
||||||
flags: flags,
|
|
||||||
config: config,
|
config: config,
|
||||||
src: src,
|
src: src,
|
||||||
out: out,
|
out: out,
|
||||||
|
@ -357,13 +332,19 @@ impl Build {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_triple(&self) -> &[Interned<String>] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts(&self.build, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Executes the entire build, as configured by the flags and configuration.
|
/// Executes the entire build, as configured by the flags and configuration.
|
||||||
pub fn build(&mut self) {
|
pub fn build(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
job::setup(self);
|
job::setup(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Subcommand::Clean = self.flags.cmd {
|
if let Subcommand::Clean = self.config.cmd {
|
||||||
return clean::clean(self);
|
return clean::clean(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +589,7 @@ impl Build {
|
||||||
/// Returns the number of parallel jobs that have been configured for this
|
/// Returns the number of parallel jobs that have been configured for this
|
||||||
/// build.
|
/// build.
|
||||||
fn jobs(&self) -> u32 {
|
fn jobs(&self) -> u32 {
|
||||||
self.flags.jobs.unwrap_or_else(|| num_cpus::get() as u32)
|
self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path to the C compiler for the target specified.
|
/// Returns the path to the C compiler for the target specified.
|
||||||
|
@ -727,7 +708,7 @@ impl Build {
|
||||||
fn force_use_stage1(&self, compiler: Compiler, target: Interned<String>) -> bool {
|
fn force_use_stage1(&self, compiler: Compiler, target: Interned<String>) -> bool {
|
||||||
!self.config.full_bootstrap &&
|
!self.config.full_bootstrap &&
|
||||||
compiler.stage >= 2 &&
|
compiler.stage >= 2 &&
|
||||||
self.config.host.iter().any(|h| *h == target)
|
self.hosts.iter().any(|h| *h == target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the directory that OpenSSL artifacts are compiled into if
|
/// Returns the directory that OpenSSL artifacts are compiled into if
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub fn check(build: &mut Build) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need cmake, but only if we're actually building LLVM or sanitizers.
|
// We need cmake, but only if we're actually building LLVM or sanitizers.
|
||||||
let building_llvm = build.config.host.iter()
|
let building_llvm = build.hosts.iter()
|
||||||
.filter_map(|host| build.config.target_config.get(host))
|
.filter_map(|host| build.config.target_config.get(host))
|
||||||
.any(|config| config.llvm_config.is_none());
|
.any(|config| config.llvm_config.is_none());
|
||||||
if building_llvm || build.config.sanitizers {
|
if building_llvm || build.config.sanitizers {
|
||||||
|
@ -114,7 +114,7 @@ pub fn check(build: &mut Build) {
|
||||||
|
|
||||||
// We're gonna build some custom C code here and there, host triples
|
// We're gonna build some custom C code here and there, host triples
|
||||||
// also build some C++ shims for LLVM so we need a C++ compiler.
|
// also build some C++ shims for LLVM so we need a C++ compiler.
|
||||||
for target in &build.config.target {
|
for target in &build.targets {
|
||||||
// On emscripten we don't actually need the C compiler to just
|
// On emscripten we don't actually need the C compiler to just
|
||||||
// build the target artifacts, only for testing. For the sake
|
// build the target artifacts, only for testing. For the sake
|
||||||
// of easier bot configuration, just skip detection.
|
// of easier bot configuration, just skip detection.
|
||||||
|
@ -128,7 +128,7 @@ pub fn check(build: &mut Build) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for host in build.config.host.iter() {
|
for host in &build.hosts {
|
||||||
cmd_finder.must_have(build.cxx(*host).unwrap());
|
cmd_finder.must_have(build.cxx(*host).unwrap());
|
||||||
|
|
||||||
// The msvc hosts don't use jemalloc, turn it off globally to
|
// The msvc hosts don't use jemalloc, turn it off globally to
|
||||||
|
@ -144,7 +144,7 @@ pub fn check(build: &mut Build) {
|
||||||
panic!("FileCheck executable {:?} does not exist", filecheck);
|
panic!("FileCheck executable {:?} does not exist", filecheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
for target in &build.config.target {
|
for target in &build.targets {
|
||||||
// Can't compile for iOS unless we're on macOS
|
// Can't compile for iOS unless we're on macOS
|
||||||
if target.contains("apple-ios") &&
|
if target.contains("apple-ios") &&
|
||||||
!build.build.contains("apple-darwin") {
|
!build.build.contains("apple-darwin") {
|
||||||
|
|
|
@ -23,10 +23,10 @@ use channel::GitInfo;
|
||||||
use cache::Interned;
|
use cache::Interned;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
struct CleanTools {
|
pub struct CleanTools {
|
||||||
compiler: Compiler,
|
pub compiler: Compiler,
|
||||||
target: Interned<String>,
|
pub target: Interned<String>,
|
||||||
mode: Mode,
|
pub mode: Mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step for CleanTools {
|
impl Step for CleanTools {
|
||||||
|
@ -82,7 +82,6 @@ impl Step for ToolBuild {
|
||||||
let target = self.target;
|
let target = self.target;
|
||||||
let tool = self.tool;
|
let tool = self.tool;
|
||||||
|
|
||||||
builder.ensure(CleanTools { compiler, target, mode: self.mode });
|
|
||||||
match self.mode {
|
match self.mode {
|
||||||
Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
|
Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
|
||||||
Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
|
Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
|
||||||
|
@ -93,38 +92,48 @@ impl Step for ToolBuild {
|
||||||
let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
|
let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
|
||||||
println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
|
println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
|
||||||
|
|
||||||
let mut cargo = builder.cargo(compiler, Mode::Tool, target, "build");
|
let mut cargo = prepare_tool_cargo(builder, compiler, target, tool);
|
||||||
let dir = build.src.join("src/tools").join(tool);
|
|
||||||
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
|
|
||||||
|
|
||||||
// We don't want to build tools dynamically as they'll be running across
|
|
||||||
// stages and such and it's just easier if they're not dynamically linked.
|
|
||||||
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
|
||||||
|
|
||||||
if let Some(dir) = build.openssl_install_dir(target) {
|
|
||||||
cargo.env("OPENSSL_STATIC", "1");
|
|
||||||
cargo.env("OPENSSL_DIR", dir);
|
|
||||||
cargo.env("LIBZ_SYS_STATIC", "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel);
|
|
||||||
|
|
||||||
let info = GitInfo::new(&dir);
|
|
||||||
if let Some(sha) = info.sha() {
|
|
||||||
cargo.env("CFG_COMMIT_HASH", sha);
|
|
||||||
}
|
|
||||||
if let Some(sha_short) = info.sha_short() {
|
|
||||||
cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
|
|
||||||
}
|
|
||||||
if let Some(date) = info.commit_date() {
|
|
||||||
cargo.env("CFG_COMMIT_DATE", date);
|
|
||||||
}
|
|
||||||
|
|
||||||
build.run(&mut cargo);
|
build.run(&mut cargo);
|
||||||
build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host))
|
build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn prepare_tool_cargo(
|
||||||
|
builder: &Builder,
|
||||||
|
compiler: Compiler,
|
||||||
|
target: Interned<String>,
|
||||||
|
tool: &'static str,
|
||||||
|
) -> Command {
|
||||||
|
let build = builder.build;
|
||||||
|
let mut cargo = builder.cargo(compiler, Mode::Tool, target, "build");
|
||||||
|
let dir = build.src.join("src/tools").join(tool);
|
||||||
|
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
|
||||||
|
|
||||||
|
// We don't want to build tools dynamically as they'll be running across
|
||||||
|
// stages and such and it's just easier if they're not dynamically linked.
|
||||||
|
cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
|
||||||
|
|
||||||
|
if let Some(dir) = build.openssl_install_dir(target) {
|
||||||
|
cargo.env("OPENSSL_STATIC", "1");
|
||||||
|
cargo.env("OPENSSL_DIR", dir);
|
||||||
|
cargo.env("LIBZ_SYS_STATIC", "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel);
|
||||||
|
|
||||||
|
let info = GitInfo::new(&build.config, &dir);
|
||||||
|
if let Some(sha) = info.sha() {
|
||||||
|
cargo.env("CFG_COMMIT_HASH", sha);
|
||||||
|
}
|
||||||
|
if let Some(sha_short) = info.sha_short() {
|
||||||
|
cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
|
||||||
|
}
|
||||||
|
if let Some(date) = info.commit_date() {
|
||||||
|
cargo.env("CFG_COMMIT_DATE", date);
|
||||||
|
}
|
||||||
|
cargo
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! tool {
|
macro_rules! tool {
|
||||||
($($name:ident, $path:expr, $tool_name:expr, $mode:expr;)+) => {
|
($($name:ident, $path:expr, $tool_name:expr, $mode:expr;)+) => {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -226,7 +235,7 @@ impl Step for RemoteTestServer {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
pub struct Rustdoc {
|
pub struct Rustdoc {
|
||||||
pub target_compiler: Compiler,
|
pub host: Interned<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step for Rustdoc {
|
impl Step for Rustdoc {
|
||||||
|
@ -240,14 +249,20 @@ impl Step for Rustdoc {
|
||||||
|
|
||||||
fn make_run(run: RunConfig) {
|
fn make_run(run: RunConfig) {
|
||||||
run.builder.ensure(Rustdoc {
|
run.builder.ensure(Rustdoc {
|
||||||
target_compiler: run.builder.compiler(run.builder.top_stage, run.host),
|
host: run.host,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(self, builder: &Builder) -> PathBuf {
|
fn run(self, builder: &Builder) -> PathBuf {
|
||||||
let target_compiler = self.target_compiler;
|
let build = builder.build;
|
||||||
|
let target_compiler = builder.compiler(builder.top_stage, self.host);
|
||||||
|
let target = target_compiler.host;
|
||||||
let build_compiler = if target_compiler.stage == 0 {
|
let build_compiler = if target_compiler.stage == 0 {
|
||||||
builder.compiler(0, builder.build.build)
|
builder.compiler(0, builder.build.build)
|
||||||
|
} else if target_compiler.stage >= 2 {
|
||||||
|
// Past stage 2, we consider the compiler to be ABI-compatible and hence capable of
|
||||||
|
// building rustdoc itself.
|
||||||
|
builder.compiler(target_compiler.stage, builder.build.build)
|
||||||
} else {
|
} else {
|
||||||
// Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
|
// Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
|
||||||
// we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage
|
// we'd have stageN/bin/rustc and stageN/bin/rustdoc be effectively different stage
|
||||||
|
@ -255,12 +270,18 @@ impl Step for Rustdoc {
|
||||||
builder.compiler(target_compiler.stage - 1, builder.build.build)
|
builder.compiler(target_compiler.stage - 1, builder.build.build)
|
||||||
};
|
};
|
||||||
|
|
||||||
let tool_rustdoc = builder.ensure(ToolBuild {
|
builder.ensure(compile::Rustc { compiler: build_compiler, target });
|
||||||
compiler: build_compiler,
|
|
||||||
target: target_compiler.host,
|
let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage));
|
||||||
tool: "rustdoc",
|
println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host);
|
||||||
mode: Mode::Librustc,
|
|
||||||
});
|
let mut cargo = prepare_tool_cargo(builder, build_compiler, target, "rustdoc");
|
||||||
|
build.run(&mut cargo);
|
||||||
|
// Cargo adds a number of paths to the dylib search path on windows, which results in
|
||||||
|
// the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
|
||||||
|
// rustdoc a different name.
|
||||||
|
let tool_rustdoc = build.cargo_out(build_compiler, Mode::Tool, target)
|
||||||
|
.join(exe("rustdoc-tool-binary", &target_compiler.host));
|
||||||
|
|
||||||
// don't create a stage0-sysroot/bin directory.
|
// don't create a stage0-sysroot/bin directory.
|
||||||
if target_compiler.stage > 0 {
|
if target_compiler.stage > 0 {
|
||||||
|
|
|
@ -3,8 +3,11 @@ name = "rustdoc-tool"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
authors = ["The Rust Project Developers"]
|
authors = ["The Rust Project Developers"]
|
||||||
|
|
||||||
|
# Cargo adds a number of paths to the dylib search path on windows, which results in
|
||||||
|
# the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
|
||||||
|
# rustdoc a different name.
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "rustdoc"
|
name = "rustdoc-tool-binary"
|
||||||
path = "main.rs"
|
path = "main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue