From 44ffb61623741f86fca9f2f51d49dc1778310ee1 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sat, 29 Jul 2017 22:12:53 -0600 Subject: [PATCH 01/11] Unify flags into config. This introduces a slight change in behavior, where we unilaterally respect the --host and --target parameters passed for all sanity checking and runtime configuration. --- src/bootstrap/bin/main.rs | 7 ++-- src/bootstrap/builder.rs | 31 +++++++----------- src/bootstrap/cc.rs | 31 ++++++++---------- src/bootstrap/check.rs | 19 +++-------- src/bootstrap/clean.rs | 2 +- src/bootstrap/compile.rs | 4 +-- src/bootstrap/config.rs | 67 ++++++++++++++++++++++++++++++++------- src/bootstrap/dist.rs | 2 +- src/bootstrap/flags.rs | 15 ++++++--- src/bootstrap/install.rs | 2 +- src/bootstrap/lib.rs | 55 +++++++++++--------------------- src/bootstrap/sanity.rs | 8 ++--- 12 files changed, 126 insertions(+), 117 deletions(-) diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 5ef18b89841f0..d02bc7972ae9a 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -21,11 +21,10 @@ extern crate bootstrap; use std::env; -use bootstrap::{Flags, Config, Build}; +use bootstrap::{Config, Build}; fn main() { let args = env::args().skip(1).collect::>(); - let flags = Flags::parse(&args); - let config = Config::parse(&flags.build, flags.config.clone()); - Build::new(flags, config).build(); + let config = Config::parse(&args); + Build::new(config).build(); } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d7f795e405534..a6cbb0134127d 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -120,28 +120,21 @@ impl StepDescription { fn maybe_run(&self, builder: &Builder, path: Option<&Path>) { let build = builder.build; let hosts = if self.only_build_targets || self.only_build { - &build.config.host[..1] + build.build_triple() } else { &build.hosts }; - // Determine the actual 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. + // Determine the targets participating in this rule. let targets = if self.only_hosts { - // If --target was specified but --host wasn't specified, - // 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 { + // If --target was specified but --host wasn't specified, don't run + // any host-only tests. + if build.config.hosts.is_empty() && !build.config.targets.is_empty() { &[] } else if self.only_build { - &build.config.host[..1] + build.build_triple() } else { - &build.config.host[..] + &build.hosts } } else { &build.targets @@ -288,7 +281,7 @@ impl<'a> Builder<'a> { let builder = Builder { build: build, - top_stage: build.flags.stage.unwrap_or(2), + top_stage: build.config.stage.unwrap_or(2), kind: kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), @@ -307,7 +300,7 @@ impl<'a> Builder<'a> { } 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::Doc { ref paths } => (Kind::Doc, &paths[..]), Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]), @@ -319,7 +312,7 @@ impl<'a> Builder<'a> { let builder = Builder { build: build, - top_stage: build.flags.stage.unwrap_or(2), + top_stage: build.config.stage.unwrap_or(2), kind: kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), @@ -543,12 +536,12 @@ impl<'a> Builder<'a> { // Ignore incremental modes except for stage0, since we're // not guaranteeing correctness across builds if the compiler // 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); 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); } diff --git a/src/bootstrap/cc.rs b/src/bootstrap/cc.rs index 739904e4f7c58..0f25da8a238d0 100644 --- a/src/bootstrap/cc.rs +++ b/src/bootstrap/cc.rs @@ -32,6 +32,7 @@ //! everything. use std::process::Command; +use std::iter; use build_helper::{cc2ar, output}; use gcc; @@ -43,47 +44,41 @@ use cache::Interned; pub fn find(build: &mut Build) { // 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. - // - // This includes targets that aren't necessarily passed on the commandline - // (FIXME: Perhaps it shouldn't?) - for target in &build.config.target { + for target in build.targets.iter().chain(&build.hosts).cloned().chain(iter::once(build.build)) { let mut cfg = gcc::Config::new(); 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); if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { cfg.compiler(cc); } else { - set_compiler(&mut cfg, "gcc", *target, config, build); + set_compiler(&mut cfg, "gcc", target, config, build); } let compiler = cfg.get_compiler(); - let ar = cc2ar(compiler.path(), target); - build.verbose(&format!("CC_{} = {:?}", target, compiler.path())); + let ar = cc2ar(compiler.path(), &target); + build.verbose(&format!("CC_{} = {:?}", &target, compiler.path())); 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 - // - // This includes hosts that aren't necessarily passed on the commandline - // (FIXME: Perhaps it shouldn't?) - for host in &build.config.host { + for host in build.hosts.iter().cloned().chain(iter::once(build.build)) { let mut cfg = gcc::Config::new(); cfg.cargo_metadata(false).opt_level(0).debug(false).cpp(true) - .target(host).host(&build.build); - let config = build.config.target_config.get(host); + .target(&host).host(&build.build); + let config = build.config.target_config.get(&host); if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { cfg.compiler(cxx); } else { - set_compiler(&mut cfg, "g++", *host, config, build); + set_compiler(&mut cfg, "g++", host, config, build); } let compiler = cfg.get_compiler(); build.verbose(&format!("CXX_{} = {:?}", host, compiler.path())); - build.cxx.insert(*host, compiler); + build.cxx.insert(host, compiler); } } diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index c65f5a9fb48bf..0351e9b81585f 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -625,7 +625,7 @@ impl Step for Compiletest { cmd.arg("--system-llvm"); } - cmd.args(&build.flags.cmd.test_args()); + cmd.args(&build.config.cmd.test_args()); if build.is_verbose() { cmd.arg("--verbose"); @@ -820,7 +820,7 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) { cmd.arg(markdown); 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); 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.arg("--"); - cargo.args(&build.flags.cmd.test_args()); + cargo.args(&build.config.cmd.test_args()); if build.config.quiet_tests { cargo.arg("--quiet"); @@ -1147,6 +1147,7 @@ pub struct Distcheck; impl Step for Distcheck { type Output = (); + const ONLY_BUILD: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { run.path("distcheck") @@ -1160,16 +1161,6 @@ impl Step for Distcheck { fn run(self, builder: &Builder) { 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"); let dir = build.out.join("tmp").join("distcheck"); let _ = fs::remove_dir_all(&dir); @@ -1236,7 +1227,7 @@ impl Step for Bootstrap { if !build.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); } diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 308a0ab3076dd..119340a0190c4 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -26,7 +26,7 @@ pub fn clean(build: &Build) { rm_rf(&build.out.join("tmp")); 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() { Ok(iter) => iter, Err(_) => continue, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 92a42b59212b4..a6702300c811f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -679,10 +679,10 @@ impl Step for Assemble { // 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 // 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"); 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 = target_compiler.host; builder.ensure(StdLink { compiler, target_compiler, target }); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c4d5d43152118..c0494bd7fd083 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -19,11 +19,14 @@ use std::fs::{self, File}; use std::io::prelude::*; use std::path::PathBuf; use std::process; +use std::cmp; use num_cpus; use toml; use util::{exe, push_exe_path}; use cache::{INTERNER, Interned}; +use flags::Flags; +pub use flags::Subcommand; /// Global configuration for the entire build and/or bootstrap. /// @@ -52,6 +55,14 @@ pub struct Config { pub sanitizers: bool, pub profiler: bool, + pub on_fail: Option, + pub stage: Option, + pub keep_stage: Option, + pub src: PathBuf, + pub jobs: Option, + pub cmd: Subcommand, + pub incremental: bool, + // llvm codegen options pub llvm_enabled: bool, pub llvm_assertions: bool, @@ -79,8 +90,8 @@ pub struct Config { pub rust_dist_src: bool, pub build: Interned, - pub host: Vec>, - pub target: Vec>, + pub hosts: Vec>, + pub targets: Vec>, pub local_rebuild: bool, // dist misc @@ -265,7 +276,9 @@ struct TomlTarget { } impl Config { - pub fn parse(build: &str, file: Option) -> Config { + pub fn parse(args: &[String]) -> Config { + let flags = Flags::parse(&args); + let file = flags.config.clone(); let mut config = Config::default(); config.llvm_enabled = true; config.llvm_optimize = true; @@ -277,11 +290,19 @@ impl Config { config.docs = true; config.rust_rpath = true; config.rust_codegen_units = 1; - config.build = INTERNER.intern_str(build); + config.build = flags.build; config.channel = "dev".to_string(); config.codegen_tests = 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; + let toml = file.map(|file| { let mut f = t!(File::open(&file)); let mut contents = String::new(); @@ -298,20 +319,41 @@ impl Config { let build = toml.build.clone().unwrap_or(Build::default()); set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x))); - config.host.push(config.build.clone()); + config.hosts.push(config.build.clone()); for host in build.host.iter() { let host = INTERNER.intern_str(host); - if !config.host.contains(&host) { - config.host.push(host); + if !config.hosts.contains(&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))) { - if !config.target.contains(&target) { - config.target.push(target); + if !config.targets.contains(&target) { + config.targets.push(target); } } + config.hosts = if !flags.host.is_empty() { + for host in flags.host.iter() { + if !config.hosts.contains(host) { + panic!("specified host `{}` is not in configuration", host); + } + } + flags.host + } else { + config.hosts + }; + config.targets = if !flags.target.is_empty() { + for target in flags.target.iter() { + if !config.targets.contains(target) { + panic!("specified target `{}` is not in configuration", target); + } + } + flags.target + } else { + config.targets + }; + config.nodejs = build.nodejs.map(PathBuf::from); config.gdb = build.gdb.map(PathBuf::from); config.python = build.python.map(PathBuf::from); @@ -327,6 +369,7 @@ impl Config { set(&mut config.sanitizers, build.sanitizers); set(&mut config.profiler, build.profiler); set(&mut config.openssl_static, build.openssl_static); + config.verbose = cmp::max(config.verbose, flags.verbose); if let Some(ref install) = toml.install { config.prefix = install.prefix.clone().map(PathBuf::from); @@ -505,11 +548,11 @@ impl Config { match key { "CFG_BUILD" if value.len() > 0 => self.build = INTERNER.intern_str(value), "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 => { - 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 => { self.llvm_experimental_targets = Some(value.to_string()); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index c322d75dd5b45..e467ba49b9734 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -546,7 +546,7 @@ impl Step for Std { // 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 == target) { + if build.hosts.iter().any(|t| t == target) { builder.ensure(compile::Rustc { compiler, target }); } else { builder.ensure(compile::Test { compiler, target }); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 1a3a008ed2614..b20801971f19d 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -34,6 +34,7 @@ pub struct Flags { pub stage: Option, pub keep_stage: Option, pub build: Interned, + pub host: Vec>, pub target: Vec>, pub config: Option, @@ -68,6 +69,14 @@ pub enum Subcommand { }, } +impl Default for Subcommand { + fn default() -> Subcommand { + Subcommand::Build { + paths: vec![PathBuf::from("nowhere")], + } + } +} + impl Flags { pub fn parse(args: &[String]) -> Flags { let mut extra_help = String::new(); @@ -243,10 +252,8 @@ Arguments: // All subcommands can have an optional "Available paths" section if matches.opt_present("verbose") { - let flags = Flags::parse(&["build".to_string()]); - let mut config = Config::parse(&flags.build, cfg_file.clone()); - config.build = flags.build.clone(); - let mut build = Build::new(flags, config); + let config = Config::parse(&["build".to_string()]); + let mut build = Build::new(config); metadata::build(&mut build); let maybe_rules_help = Builder::get_help(&build, subcommand.as_str()); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index ebfda1e619bd8..89690e444d1f6 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -28,7 +28,7 @@ pub fn install_docs(builder: &Builder, stage: u32, host: Interned) { } 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)); } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index a8485d1d152d1..e1d2779057f9d 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -136,13 +136,13 @@ extern crate toml; extern crate libc; use std::cell::Cell; -use std::cmp; use std::collections::{HashSet, HashMap}; use std::env; use std::fs::{self, File}; use std::io::Read; use std::path::{PathBuf, Path}; use std::process::Command; +use std::slice; 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 flags::{Flags, Subcommand}; +use flags::Subcommand; use cache::{Interned, INTERNER}; /// A structure representing a Rust compiler. @@ -215,9 +215,6 @@ pub struct Build { // User-specified configuration via config.toml config: Config, - // User-specified configuration via CLI flags - flags: Flags, - // Derived properties from the above two configurations src: PathBuf, out: PathBuf, @@ -288,9 +285,9 @@ impl Build { /// line and the filesystem `config`. /// /// By default all build output will be placed in the current directory. - pub fn new(flags: Flags, config: Config) -> Build { + pub fn new(config: Config) -> Build { let cwd = t!(env::current_dir()); - let src = flags.src.clone(); + let src = config.src.clone(); let out = cwd.join("build"); let is_sudo = match env::var_os("SUDO_USER") { @@ -306,39 +303,17 @@ impl Build { let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo")); let rls_info = channel::GitInfo::new(&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 { initial_rustc: config.initial_rustc.clone(), initial_cargo: config.initial_cargo.clone(), local_rebuild: config.local_rebuild, - fail_fast: flags.cmd.fail_fast(), - verbosity: cmp::max(flags.verbose, config.verbose), + fail_fast: config.cmd.fail_fast(), + verbosity: config.verbose, - build: config.host[0].clone(), - hosts: hosts, - targets: targets, + build: config.build, + hosts: config.hosts.clone(), + targets: config.targets.clone(), - flags: flags, config: config, src: src, out: out, @@ -357,13 +332,19 @@ impl Build { } } + pub fn build_triple(&self) -> &[Interned] { + unsafe { + slice::from_raw_parts(&self.build, 1) + } + } + /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { job::setup(self); } - if let Subcommand::Clean = self.flags.cmd { + if let Subcommand::Clean = self.config.cmd { return clean::clean(self); } @@ -608,7 +589,7 @@ impl Build { /// Returns the number of parallel jobs that have been configured for this /// build. 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. @@ -727,7 +708,7 @@ impl Build { fn force_use_stage1(&self, compiler: Compiler, target: Interned) -> bool { !self.config.full_bootstrap && 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 diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 7063b28f19d01..436a13500f254 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -85,7 +85,7 @@ pub fn check(build: &mut Build) { } // 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)) .any(|config| config.llvm_config.is_none()); 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 // 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 // build the target artifacts, only for testing. For the sake // 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()); // 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); } - for target in &build.config.target { + for target in &build.targets { // Can't compile for iOS unless we're on macOS if target.contains("apple-ios") && !build.build.contains("apple-darwin") { From 84d9a6ee8cb40ea3dc390b8f4e2862289cb14f7e Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sat, 29 Jul 2017 22:26:28 -0600 Subject: [PATCH 02/11] Allow specifiying targets and hosts not in the config file. We no longer care about the source of this information, so there is no reason to restrict users. --- src/bootstrap/config.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index c0494bd7fd083..e1c60b5d19143 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -334,21 +334,11 @@ impl Config { } } config.hosts = if !flags.host.is_empty() { - for host in flags.host.iter() { - if !config.hosts.contains(host) { - panic!("specified host `{}` is not in configuration", host); - } - } flags.host } else { config.hosts }; config.targets = if !flags.target.is_empty() { - for target in flags.target.iter() { - if !config.targets.contains(target) { - panic!("specified target `{}` is not in configuration", target); - } - } flags.target } else { config.targets From 5290c6c8f158004b19fa38aab36ac29511ec1a8a Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sat, 29 Jul 2017 22:45:49 -0600 Subject: [PATCH 03/11] Allow overriding build triple via flag. We first check the configuration, then passed parameters (--build), then fall back to the auto-detection that bootstrap.py does. Fixes #39673. --- src/bootstrap/config.rs | 6 +++++- src/bootstrap/flags.rs | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e1c60b5d19143..008dbbe891422 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -290,7 +290,6 @@ impl Config { config.docs = true; config.rust_rpath = true; config.rust_codegen_units = 1; - config.build = flags.build; config.channel = "dev".to_string(); config.codegen_tests = true; config.rust_dist_src = true; @@ -319,6 +318,11 @@ impl Config { 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, 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() { let host = INTERNER.intern_str(host); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index b20801971f19d..a9cefb65f4963 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -33,7 +33,7 @@ pub struct Flags { pub on_fail: Option, pub stage: Option, pub keep_stage: Option, - pub build: Interned, + pub build: Option>, pub host: Vec>, pub target: Vec>, @@ -327,9 +327,7 @@ Arguments: stage: stage, on_fail: matches.opt_str("on-fail"), keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()), - build: INTERNER.intern_string(matches.opt_str("build").unwrap_or_else(|| { - env::var("BUILD").unwrap() - })), + build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)), host: split(matches.opt_strs("host")) .into_iter().map(|x| INTERNER.intern_string(x)).collect::>(), target: split(matches.opt_strs("target")) From 40dea65ec2675f776a27b67fcb2bb7f29e843da9 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 3 Aug 2017 10:53:56 -0600 Subject: [PATCH 04/11] Add ability to ignore git when building rust. Some users of the build system change the git sha on every build due to utilizing git to push changes to a remote server. This allows them to simply configure that away instead of depending on custom patches to rustbuild. --- config.toml.example | 3 +++ src/bootstrap/channel.rs | 5 +++-- src/bootstrap/config.rs | 4 ++++ src/bootstrap/lib.rs | 6 +++--- src/bootstrap/tool.rs | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/config.toml.example b/config.toml.example index 19678dc779375..962be2e608501 100644 --- a/config.toml.example +++ b/config.toml.example @@ -258,6 +258,9 @@ # saying that the FileCheck executable is missing, you may want to disable this. #codegen-tests = true +# Flag indicating whether git info will be retrieved from .git automatically. +#ignore-git = false + # ============================================================================= # Options for specific targets # diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index beefaeab90b15..9c1ae83d38281 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -21,6 +21,7 @@ use std::process::Command; use build_helper::output; use Build; +use config::Config; // The version number pub const CFG_RELEASE_NUM: &str = "1.21.0"; @@ -41,9 +42,9 @@ struct Info { } 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 - if !dir.join(".git").exists() { + if config.ignore_git || !dir.join(".git").exists() { return GitInfo { inner: None } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 008dbbe891422..3ec1c205dc002 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -54,6 +54,7 @@ pub struct Config { pub extended: bool, pub sanitizers: bool, pub profiler: bool, + pub ignore_git: bool, pub on_fail: Option, pub stage: Option, @@ -260,6 +261,7 @@ struct Rust { optimize_tests: Option, debuginfo_tests: Option, codegen_tests: Option, + ignore_git: Option, } /// TOML representation of how each build target is configured. @@ -292,6 +294,7 @@ impl Config { config.rust_codegen_units = 1; config.channel = "dev".to_string(); config.codegen_tests = true; + config.ignore_git = false; config.rust_dist_src = true; config.on_fail = flags.on_fail; @@ -410,6 +413,7 @@ impl Config { set(&mut config.use_jemalloc, rust.use_jemalloc); set(&mut config.backtrace, rust.backtrace); 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_ar = rust.default_ar.clone(); config.musl_root = rust.musl_root.clone().map(PathBuf::from); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e1d2779057f9d..1452a38f6ed28 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -299,9 +299,9 @@ impl Build { } None => false, }; - let rust_info = channel::GitInfo::new(&src); - let cargo_info = channel::GitInfo::new(&src.join("src/tools/cargo")); - let rls_info = channel::GitInfo::new(&src.join("src/tools/rls")); + let rust_info = channel::GitInfo::new(&config, &src); + let cargo_info = channel::GitInfo::new(&config, &src.join("src/tools/cargo")); + let rls_info = channel::GitInfo::new(&config, &src.join("src/tools/rls")); Build { initial_rustc: config.initial_rustc.clone(), diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 862b3e2b1edb0..da61ad4428999 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -109,7 +109,7 @@ impl Step for ToolBuild { cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel); - let info = GitInfo::new(&dir); + let info = GitInfo::new(&build.config, &dir); if let Some(sha) = info.sha() { cargo.env("CFG_COMMIT_HASH", sha); } From 83b68125e70b2b966439db748a79d36afd274bf3 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 3 Aug 2017 16:06:20 -0600 Subject: [PATCH 05/11] Make the message for building rustdoc slightly nicer --- src/bootstrap/tool.rs | 80 ++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index da61ad4428999..3043c95b5f07e 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -93,36 +93,46 @@ impl Step for ToolBuild { let _folder = build.fold_output(|| format!("stage{}-{}", compiler.stage, tool)); println!("Building stage{} tool {} ({})", compiler.stage, tool, target); - 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"); - } + let mut cargo = prepare_tool_cargo(builder, compiler, target, tool); + build.run(&mut cargo); + build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host)) + } +} - cargo.env("CFG_RELEASE_CHANNEL", &build.config.channel); +fn prepare_tool_cargo( + builder: &Builder, + compiler: Compiler, + target: Interned, + 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"); + } - 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.env("CFG_RELEASE_CHANNEL", &build.config.channel); - build.run(&mut cargo); - build.cargo_out(compiler, Mode::Tool, target).join(exe(tool, &compiler.host)) + 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 { @@ -245,7 +255,9 @@ impl Step for Rustdoc { } fn run(self, builder: &Builder) -> PathBuf { + let build = builder.build; let target_compiler = self.target_compiler; + let target = target_compiler.host; let build_compiler = if target_compiler.stage == 0 { builder.compiler(0, builder.build.build) } else { @@ -255,12 +267,16 @@ impl Step for Rustdoc { builder.compiler(target_compiler.stage - 1, builder.build.build) }; - let tool_rustdoc = builder.ensure(ToolBuild { - compiler: build_compiler, - target: target_compiler.host, - tool: "rustdoc", - mode: Mode::Librustc, - }); + builder.ensure(CleanTools { compiler: build_compiler, target, mode: Mode::Librustc }); + builder.ensure(compile::Rustc { compiler: build_compiler, target }); + + let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); + println!("Building rustdoc for stage{} ({})", target_compiler.stage, target_compiler.host); + + let mut cargo = prepare_tool_cargo(builder, build_compiler, target, "rustdoc"); + build.run(&mut cargo); + let tool_rustdoc = build.cargo_out(build_compiler, Mode::Tool, target) + .join(exe("rustdoc", &target_compiler.host)); // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { From ad4acbaadf7d093f157e4499b2aedda9d91ec03b Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 3 Aug 2017 19:08:20 -0600 Subject: [PATCH 06/11] Build rustdoc with the stageN compiler in N >= 2. This permits proc macro crates to correctly work with rustdoc. --- src/bootstrap/tool.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 3043c95b5f07e..e5783e346f46d 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -260,6 +260,10 @@ impl Step for Rustdoc { let target = target_compiler.host; let build_compiler = if target_compiler.stage == 0 { 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. + target_compiler } else { // 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 From facf5a91c458958de1c11cb9c28e14671af9b6fd Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 4 Aug 2017 16:13:01 -0600 Subject: [PATCH 07/11] Build rustdoc only at the top stage --- src/bootstrap/builder.rs | 19 ++++++++----------- src/bootstrap/check.rs | 6 +++--- src/bootstrap/dist.rs | 3 +-- src/bootstrap/doc.rs | 12 ++++++------ src/bootstrap/tool.rs | 6 +++--- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a6cbb0134127d..d469f7c1722a5 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -407,22 +407,19 @@ impl<'a> Builder<'a> { } } - pub fn rustdoc(&self, compiler: Compiler) -> PathBuf { - self.ensure(tool::Rustdoc { target_compiler: compiler }) + pub fn rustdoc(&self, host: Interned) -> PathBuf { + self.ensure(tool::Rustdoc { host }) } - pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command { + pub fn rustdoc_cmd(&self, host: Interned) -> Command { let mut cmd = Command::new(&self.out.join("bootstrap/debug/rustdoc")); + let compiler = self.compiler(self.top_stage, host); cmd .env("RUSTC_STAGE", compiler.stage.to_string()) - .env("RUSTC_SYSROOT", if compiler.is_snapshot(&self.build) { - INTERNER.intern_path(self.build.rustc_snapshot_libdir()) - } else { - self.sysroot(compiler) - }) - .env("RUSTC_LIBDIR", self.rustc_libdir(compiler)) + .env("RUSTC_SYSROOT", self.sysroot(compiler)) + .env("RUSTC_LIBDIR", self.sysroot_libdir(compiler, self.build.build)) .env("CFG_RELEASE_CHANNEL", &self.build.config.channel) - .env("RUSTDOC_REAL", self.rustdoc(compiler)); + .env("RUSTDOC_REAL", self.rustdoc(host)); cmd } @@ -476,7 +473,7 @@ impl<'a> Builder<'a> { .env("RUSTC_RPATH", self.config.rust_rpath.to_string()) .env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc")) .env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" { - self.rustdoc(compiler) + self.rustdoc(compiler.host) } else { PathBuf::from("/path/to/nowhere/rustdoc/not/required") }) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 0351e9b81585f..d4d6fdc5c1b7d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -164,7 +164,7 @@ impl Step for Cargotest { try_run(build, cmd.arg(&build.initial_cargo) .arg(&out_dir) .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. 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)); @@ -814,7 +814,7 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) { } 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); cmd.arg("--test"); cmd.arg(markdown); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e467ba49b9734..bfcfb5f9a37f8 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -413,8 +413,7 @@ impl Step for Rustc { t!(fs::create_dir_all(image.join("bin"))); cp_r(&src.join("bin"), &image.join("bin")); - install(&builder.ensure(tool::Rustdoc { target_compiler: compiler }), - &image.join("bin"), 0o755); + install(&builder.rustdoc(compiler.host), &image.join("bin"), 0o755); // Copy runtime DLLs needed by the compiler if libdir != "bin" { diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 1ee578bb62b19..f0e0874abed60 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -260,7 +260,7 @@ fn invoke_rustdoc(builder: &Builder, compiler: Compiler, target: Interned, } impl Step for Rustdoc { @@ -250,13 +250,13 @@ impl Step for Rustdoc { fn make_run(run: RunConfig) { run.builder.ensure(Rustdoc { - target_compiler: run.builder.compiler(run.builder.top_stage, run.host), + host: run.host, }); } fn run(self, builder: &Builder) -> PathBuf { let build = builder.build; - let target_compiler = self.target_compiler; + let target_compiler = builder.compiler(builder.top_stage, self.host); let target = target_compiler.host; let build_compiler = if target_compiler.stage == 0 { builder.compiler(0, builder.build.build) From cec68167fd3787500194f261e2fcbb14381cd317 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 10 Aug 2017 10:12:35 +0500 Subject: [PATCH 08/11] Clean tools after building libstd/libtest/librustc. This fixes the bug we previously had where we'd build a libtest tool after building a libstd tool and clear out the libstd tool. Since we clear out all tools for a given stage on invocations of CleanTools after lib{std, test, rustc} change, we need to make sure that all tools built with that stage will be built after the clearing is done. The fix contained here technically isn't perfect; there is still an edge case of compiling a libstd tool, then compiling libtest, which will clear out the libstd tool and it won't ever get rebuilt within that session of rustbuild. This is where the caching system used today shows it's problems -- in effect, all tools depend on a global counter of the stage being cleared out. We can implement such a counter in a future patch to ensure that tools are rebuilt as needed, but it is deemed unlikely that it will be required in practice, since most if not all tools are built after the relevant stage's std/test/rustc are built, though this is only an opinion and hasn't been verified. --- src/bootstrap/compile.rs | 17 +++++++++++++++++ src/bootstrap/tool.rs | 10 ++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index a6702300c811f..33c3638a89473 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -32,6 +32,7 @@ use serde_json; use util::{exe, libdir, is_dylib, copy}; use {Build, Compiler, Mode}; use native; +use tool; use cache::{INTERNER, Interned}; use builder::{Step, RunConfig, ShouldRun, Builder}; @@ -198,6 +199,12 @@ impl Step for StdLink { // for reason why the sanitizers are not built in stage0. 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); add_to_sysroot(&builder.sysroot_libdir(target_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); add_to_sysroot(&builder.sysroot_libdir(target_compiler, target), &librustc_stamp(build, compiler, target)); + builder.ensure(tool::CleanTools { + compiler: target_compiler, + target: target, + mode: Mode::Librustc, + }); } } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 89b1b1137973c..7ccd527b33874 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -23,10 +23,10 @@ use channel::GitInfo; use cache::Interned; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -struct CleanTools { - compiler: Compiler, - target: Interned, - mode: Mode, +pub struct CleanTools { + pub compiler: Compiler, + pub target: Interned, + pub mode: Mode, } impl Step for CleanTools { @@ -82,7 +82,6 @@ impl Step for ToolBuild { let target = self.target; let tool = self.tool; - builder.ensure(CleanTools { compiler, target, mode: self.mode }); match self.mode { Mode::Libstd => builder.ensure(compile::Std { compiler, target }), Mode::Libtest => builder.ensure(compile::Test { compiler, target }), @@ -271,7 +270,6 @@ impl Step for Rustdoc { builder.compiler(target_compiler.stage - 1, builder.build.build) }; - builder.ensure(CleanTools { compiler: build_compiler, target, mode: Mode::Librustc }); builder.ensure(compile::Rustc { compiler: build_compiler, target }); let _folder = build.fold_output(|| format!("stage{}-rustdoc", target_compiler.stage)); From 657196830fd7fdc03eab87b8afa21601faf07975 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Thu, 10 Aug 2017 21:17:42 +0500 Subject: [PATCH 09/11] Correct code to not run host-only tests. --- src/bootstrap/builder.rs | 4 +--- src/bootstrap/config.rs | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d469f7c1722a5..db2c6dfeb9f74 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -127,9 +127,7 @@ impl StepDescription { // Determine the targets participating in this rule. let targets = if self.only_hosts { - // If --target was specified but --host wasn't specified, don't run - // any host-only tests. - if build.config.hosts.is_empty() && !build.config.targets.is_empty() { + if build.config.run_host_only { &[] } else if self.only_build { build.build_triple() diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 3ec1c205dc002..aa688fc66e267 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -56,6 +56,8 @@ pub struct Config { pub profiler: bool, pub ignore_git: bool, + pub run_host_only: bool, + pub on_fail: Option, pub stage: Option, pub keep_stage: Option, @@ -305,6 +307,9 @@ impl Config { 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 mut f = t!(File::open(&file)); let mut contents = String::new(); @@ -351,6 +356,7 @@ impl Config { config.targets }; + config.nodejs = build.nodejs.map(PathBuf::from); config.gdb = build.gdb.map(PathBuf::from); config.python = build.python.map(PathBuf::from); From 82cdf1006e235a318a927b58ab0bc53b7f2a611c Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 13 Aug 2017 05:07:01 +0500 Subject: [PATCH 10/11] Cargotest needs only one rustdoc.exe to exist on Windows --- src/bootstrap/tool.rs | 5 ++++- src/tools/rustdoc/Cargo.toml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 7ccd527b33874..255ded4c3f63f 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -277,8 +277,11 @@ impl Step for Rustdoc { 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", &target_compiler.host)); + .join(exe("rustdoc-tool-binary", &target_compiler.host)); // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index b6edb76d7f98f..344f617ef95bc 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -3,8 +3,11 @@ name = "rustdoc-tool" version = "0.0.0" 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]] -name = "rustdoc" +name = "rustdoc-tool-binary" path = "main.rs" [dependencies] From 01641c70331d704fdab05914f21921e453ae61bb Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 13 Aug 2017 08:58:49 +0500 Subject: [PATCH 11/11] Build rustdoc with the native build triple --- src/bootstrap/tool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 255ded4c3f63f..d798e8de3dffa 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -262,7 +262,7 @@ impl Step for Rustdoc { } else if target_compiler.stage >= 2 { // Past stage 2, we consider the compiler to be ABI-compatible and hence capable of // building rustdoc itself. - target_compiler + builder.compiler(target_compiler.stage, builder.build.build) } else { // 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