mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-11 16:15:03 +00:00
Utilize interning to allow Copy/Clone steps
This commit is contained in:
parent
e7b1a60ad7
commit
528646e127
9
src/Cargo.lock
generated
9
src/Cargo.lock
generated
@ -134,10 +134,11 @@ dependencies = [
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -155,8 +156,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
name = "build-manifest"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -40,3 +40,4 @@ serde = "1.0.8"
|
||||
serde_derive = "1.0.8"
|
||||
serde_json = "1.0.2"
|
||||
toml = "0.4"
|
||||
lazy_static = "0.2"
|
||||
|
@ -8,20 +8,21 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::cell::RefCell;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use std::fs;
|
||||
use std::ops::Deref;
|
||||
use std::any::{TypeId, Any};
|
||||
|
||||
use compile;
|
||||
use install;
|
||||
use dist;
|
||||
use util::{exe, libdir, add_lib_path};
|
||||
use {Build, Mode};
|
||||
use cache::{Cache, Key};
|
||||
use cache::{INTERNER, Interned, Cache};
|
||||
use check;
|
||||
use flags::Subcommand;
|
||||
use doc;
|
||||
@ -34,7 +35,7 @@ pub struct Builder<'a> {
|
||||
pub top_stage: u32,
|
||||
pub kind: Kind,
|
||||
cache: Cache,
|
||||
stack: RefCell<Vec<Key>>,
|
||||
stack: RefCell<Vec<(TypeId, Box<Any>)>>,
|
||||
}
|
||||
|
||||
impl<'a> Deref for Builder<'a> {
|
||||
@ -45,19 +46,10 @@ impl<'a> Deref for Builder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Step<'a>: Serialize + Sized {
|
||||
/// The output type of this step. This is used in a few places to return a
|
||||
pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
|
||||
/// `PathBuf` when directories are created or to return a `Compiler` once
|
||||
/// it's been assembled.
|
||||
///
|
||||
/// When possible, this should be used instead of implicitly creating files
|
||||
/// in a prearranged directory that will later be used by the build system.
|
||||
/// It's not always practical, however, since it makes avoiding rebuilds
|
||||
/// somewhat harder.
|
||||
type Output: Serialize + Deserialize<'a> + 'a;
|
||||
|
||||
/// This type, but with a 'static bound. Used for caching the step.
|
||||
type Id: 'static;
|
||||
type Output: Clone;
|
||||
|
||||
const DEFAULT: bool = false;
|
||||
|
||||
@ -72,13 +64,13 @@ pub trait Step<'a>: Serialize + Sized {
|
||||
|
||||
/// Primary function to execute this rule. Can call `builder.ensure(...)`
|
||||
/// with other steps to run those.
|
||||
fn run(self, builder: &'a Builder) -> Self::Output;
|
||||
fn run(self, builder: &Builder) -> Self::Output;
|
||||
|
||||
/// When bootstrap is passed a set of paths, this controls whether this rule
|
||||
/// will execute. However, it does not get called in a "default" context
|
||||
/// when we are not passed any paths; in that case, make_run is called
|
||||
/// directly.
|
||||
fn should_run(_builder: &'a Builder, _path: &Path) -> bool { false }
|
||||
fn should_run(_builder: &Builder, _path: &Path) -> bool { false }
|
||||
|
||||
/// Build up a "root" rule, either as a default rule or from a path passed
|
||||
/// to us.
|
||||
@ -87,10 +79,10 @@ pub trait Step<'a>: Serialize + Sized {
|
||||
/// passed. When `./x.py build` is run, for example, this rule could get
|
||||
/// called if it is in the correct list below with a path of `None`.
|
||||
fn make_run(
|
||||
_builder: &'a Builder,
|
||||
_builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: &'a str,
|
||||
_target: &'a str,
|
||||
_host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) { unimplemented!() }
|
||||
}
|
||||
|
||||
@ -176,26 +168,27 @@ impl<'a> Builder<'a> {
|
||||
/// not take `Compiler` since all `Compiler` instances are meant to be
|
||||
/// obtained through this function, since it ensures that they are valid
|
||||
/// (i.e., built and assembled).
|
||||
pub fn compiler(&'a self, stage: u32, host: &'a str) -> Compiler<'a> {
|
||||
pub fn compiler(&self, stage: u32, host: Interned<String>) -> Compiler {
|
||||
self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } })
|
||||
}
|
||||
|
||||
pub fn sysroot(&self, compiler: Compiler<'a>) -> PathBuf {
|
||||
pub fn sysroot(&self, compiler: Compiler) -> Interned<PathBuf> {
|
||||
self.ensure(compile::Sysroot { compiler })
|
||||
}
|
||||
|
||||
/// Returns the libdir where the standard library and other artifacts are
|
||||
/// found for a compiler's sysroot.
|
||||
pub fn sysroot_libdir(&self, compiler: Compiler<'a>, target: &'a str) -> PathBuf {
|
||||
#[derive(Serialize)]
|
||||
struct Libdir<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
target: &'a str,
|
||||
pub fn sysroot_libdir(
|
||||
&self, compiler: Compiler, target: Interned<String>
|
||||
) -> Interned<PathBuf> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
struct Libdir {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
}
|
||||
impl<'a> Step<'a> for Libdir<'a> {
|
||||
type Id = Libdir<'static>;
|
||||
type Output = PathBuf;
|
||||
fn run(self, builder: &Builder) -> PathBuf {
|
||||
impl Step for Libdir {
|
||||
type Output = Interned<PathBuf>;
|
||||
fn run(self, builder: &Builder) -> Interned<PathBuf> {
|
||||
let compiler = self.compiler;
|
||||
let lib = if compiler.stage >= 2 && builder.build.config.libdir_relative.is_some() {
|
||||
builder.build.config.libdir_relative.clone().unwrap()
|
||||
@ -206,7 +199,7 @@ impl<'a> Builder<'a> {
|
||||
.join("rustlib").join(self.target).join("lib");
|
||||
let _ = fs::remove_dir_all(&sysroot);
|
||||
t!(fs::create_dir_all(&sysroot));
|
||||
sysroot
|
||||
INTERNER.intern_path(sysroot)
|
||||
}
|
||||
}
|
||||
self.ensure(Libdir { compiler, target })
|
||||
@ -221,7 +214,7 @@ impl<'a> Builder<'a> {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.build.rustc_snapshot_libdir()
|
||||
} else {
|
||||
self.sysroot(compiler).join(libdir(compiler.host))
|
||||
self.sysroot(compiler).join(libdir(&compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,7 +236,7 @@ impl<'a> Builder<'a> {
|
||||
if compiler.is_snapshot(self) {
|
||||
self.initial_rustc.clone()
|
||||
} else {
|
||||
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
|
||||
self.sysroot(compiler).join("bin").join(exe("rustc", &compiler.host))
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,7 +244,7 @@ impl<'a> Builder<'a> {
|
||||
pub fn rustdoc(&self, compiler: Compiler) -> PathBuf {
|
||||
let mut rustdoc = self.rustc(compiler);
|
||||
rustdoc.pop();
|
||||
rustdoc.push(exe("rustdoc", compiler.host));
|
||||
rustdoc.push(exe("rustdoc", &compiler.host));
|
||||
rustdoc
|
||||
}
|
||||
|
||||
@ -265,7 +258,7 @@ impl<'a> Builder<'a> {
|
||||
pub fn cargo(&self,
|
||||
compiler: Compiler,
|
||||
mode: Mode,
|
||||
target: &str,
|
||||
target: Interned<String>,
|
||||
cmd: &str) -> Command {
|
||||
let mut cargo = Command::new(&self.initial_cargo);
|
||||
let out_dir = self.stage_out(compiler, mode);
|
||||
@ -427,7 +420,7 @@ impl<'a> Builder<'a> {
|
||||
cargo
|
||||
}
|
||||
|
||||
fn maybe_run<S: Step<'a>>(&'a self, path: Option<&Path>) {
|
||||
fn maybe_run<S: Step>(&self, path: Option<&Path>) {
|
||||
let build = self.build;
|
||||
let hosts = if S::ONLY_BUILD_TARGETS || S::ONLY_BUILD {
|
||||
&build.config.host[..1]
|
||||
@ -459,7 +452,7 @@ impl<'a> Builder<'a> {
|
||||
|
||||
for host in hosts {
|
||||
for target in targets {
|
||||
S::make_run(self, path, host, target);
|
||||
S::make_run(self, path, *host, *target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,33 +460,37 @@ impl<'a> Builder<'a> {
|
||||
/// Ensure that a given step is built, returning it's output. This will
|
||||
/// cache the step, so it is safe (and good!) to call this as often as
|
||||
/// needed to ensure that all dependencies are built.
|
||||
pub fn ensure<S: Step<'a>>(&'a self, step: S) -> S::Output {
|
||||
let key = Cache::to_key(&step);
|
||||
pub fn ensure<S: Step>(&'a self, step: S) -> S::Output {
|
||||
let type_id = TypeId::of::<S>();
|
||||
{
|
||||
let mut stack = self.stack.borrow_mut();
|
||||
if stack.contains(&key) {
|
||||
for &(stack_type_id, ref stack_step) in stack.iter() {
|
||||
if !(type_id == stack_type_id && step == *stack_step.downcast_ref().unwrap()) {
|
||||
continue
|
||||
}
|
||||
let mut out = String::new();
|
||||
out += &format!("\n\nCycle in build detected when adding {:?}\n", key);
|
||||
out += &format!("\n\nCycle in build detected when adding {:?}\n", step);
|
||||
for el in stack.iter().rev() {
|
||||
out += &format!("\t{:?}\n", el);
|
||||
}
|
||||
panic!(out);
|
||||
}
|
||||
if let Some(out) = self.cache.get::<S::Output>(&key) {
|
||||
self.build.verbose(&format!("{}c {:?}", " ".repeat(stack.len()), key));
|
||||
if let Some(out) = self.cache.get(&step) {
|
||||
self.build.verbose(&format!("{}c {:?}", " ".repeat(stack.len()), step));
|
||||
|
||||
return out;
|
||||
}
|
||||
self.build.verbose(&format!("{}> {:?}", " ".repeat(stack.len()), key));
|
||||
stack.push(key.clone());
|
||||
self.build.verbose(&format!("{}> {:?}", " ".repeat(stack.len()), step));
|
||||
stack.push((type_id, Box::new(step.clone())));
|
||||
}
|
||||
let out = step.run(self);
|
||||
let out = step.clone().run(self);
|
||||
{
|
||||
let mut stack = self.stack.borrow_mut();
|
||||
assert_eq!(stack.pop().as_ref(), Some(&key));
|
||||
let (cur_type_id, cur_step) = stack.pop().expect("step stack empty");
|
||||
assert_eq!((cur_type_id, cur_step.downcast_ref()), (type_id, Some(&step)));
|
||||
}
|
||||
self.build.verbose(&format!("{}< {:?}", " ".repeat(self.stack.borrow().len()), key));
|
||||
self.cache.put(key.clone(), &out);
|
||||
self.cache.get::<S::Output>(&key).unwrap()
|
||||
self.build.verbose(&format!("{}< {:?}", " ".repeat(self.stack.borrow().len()), step));
|
||||
self.cache.put(step, out.clone());
|
||||
out
|
||||
}
|
||||
}
|
||||
|
@ -8,15 +8,250 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use serde_json;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::any::TypeId;
|
||||
use serde::Deserialize;
|
||||
use serde::de::{self, Deserializer, Visitor};
|
||||
|
||||
use std::any::{Any, TypeId};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::AsRef;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use builder::Step;
|
||||
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::collections::HashMap;
|
||||
use std::cell::RefCell;
|
||||
pub struct Interned<T>(usize, PhantomData<*const T>);
|
||||
|
||||
impl<'de> Deserialize<'de> for Interned<String> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where D: Deserializer<'de>
|
||||
{
|
||||
struct StrVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for StrVisitor {
|
||||
type Value = &'de str;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a str")
|
||||
}
|
||||
|
||||
fn visit_borrowed_str<E>(self, value: &'de str) -> Result<&'de str, E>
|
||||
where E: de::Error
|
||||
{
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(INTERNER.intern_str(deserializer.deserialize_str(StrVisitor)?))
|
||||
}
|
||||
}
|
||||
impl Default for Interned<String> {
|
||||
fn default() -> Self {
|
||||
INTERNER.intern_string(String::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Interned<PathBuf> {
|
||||
fn default() -> Self {
|
||||
INTERNER.intern_path(PathBuf::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for Interned<T> {}
|
||||
impl<T> Clone for Interned<T> {
|
||||
fn clone(&self) -> Interned<T> {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PartialEq for Interned<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
impl<T> Eq for Interned<T> {}
|
||||
|
||||
impl PartialEq<str> for Interned<String> {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
*self == other
|
||||
}
|
||||
}
|
||||
impl<'a> PartialEq<&'a str> for Interned<String> {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
**self == **other
|
||||
}
|
||||
}
|
||||
impl<'a, T> PartialEq<&'a Interned<T>> for Interned<T> {
|
||||
fn eq(&self, other: &&Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
impl<'a, T> PartialEq<Interned<T>> for &'a Interned<T> {
|
||||
fn eq(&self, other: &Interned<T>) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for Interned<T> {}
|
||||
unsafe impl<T> Sync for Interned<T> {}
|
||||
|
||||
impl fmt::Display for Interned<String> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s: &str = &*self;
|
||||
f.write_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Interned<String> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s: &str = &*self;
|
||||
f.write_fmt(format_args!("{:?}", s))
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for Interned<PathBuf> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let s: &Path = &*self;
|
||||
f.write_fmt(format_args!("{:?}", s))
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Interned<String> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let l = INTERNER.strs.lock().unwrap();
|
||||
l.get(*self).hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for Interned<PathBuf> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let l = INTERNER.paths.lock().unwrap();
|
||||
l.get(*self).hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Interned<String> {
|
||||
type Target = str;
|
||||
fn deref(&self) -> &'static str {
|
||||
let l = INTERNER.strs.lock().unwrap();
|
||||
unsafe { mem::transmute::<&str, &'static str>(l.get(*self)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Interned<PathBuf> {
|
||||
type Target = Path;
|
||||
fn deref(&self) -> &'static Path {
|
||||
let l = INTERNER.paths.lock().unwrap();
|
||||
unsafe { mem::transmute::<&Path, &'static Path>(l.get(*self)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Interned<PathBuf> {
|
||||
fn as_ref(&self) -> &'static Path {
|
||||
let l = INTERNER.paths.lock().unwrap();
|
||||
unsafe { mem::transmute::<&Path, &'static Path>(l.get(*self)) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Interned<String> {
|
||||
fn as_ref(&self) -> &'static Path {
|
||||
let l = INTERNER.strs.lock().unwrap();
|
||||
unsafe { mem::transmute::<&Path, &'static Path>(l.get(*self).as_ref()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<OsStr> for Interned<PathBuf> {
|
||||
fn as_ref(&self) -> &'static OsStr {
|
||||
let l = INTERNER.paths.lock().unwrap();
|
||||
unsafe { mem::transmute::<&OsStr, &'static OsStr>(l.get(*self).as_ref()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<OsStr> for Interned<String> {
|
||||
fn as_ref(&self) -> &'static OsStr {
|
||||
let l = INTERNER.strs.lock().unwrap();
|
||||
unsafe { mem::transmute::<&OsStr, &'static OsStr>(l.get(*self).as_ref()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct TyIntern<T> {
|
||||
items: Vec<T>,
|
||||
set: HashMap<T, Interned<T>>,
|
||||
}
|
||||
|
||||
impl<T: Hash + Clone + Eq> TyIntern<T> {
|
||||
fn new() -> TyIntern<T> {
|
||||
TyIntern {
|
||||
items: Vec::new(),
|
||||
set: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn intern_borrow<B>(&mut self, item: &B) -> Interned<T>
|
||||
where
|
||||
B: Eq + Hash + ToOwned<Owned=T> + ?Sized,
|
||||
T: Borrow<B>,
|
||||
{
|
||||
if let Some(i) = self.set.get(&item) {
|
||||
return *i;
|
||||
}
|
||||
let item = item.to_owned();
|
||||
let interned = Interned(self.items.len(), PhantomData::<*const T>);
|
||||
self.set.insert(item.clone(), interned);
|
||||
self.items.push(item);
|
||||
interned
|
||||
}
|
||||
|
||||
fn intern(&mut self, item: T) -> Interned<T> {
|
||||
if let Some(i) = self.set.get(&item) {
|
||||
return *i;
|
||||
}
|
||||
let interned = Interned(self.items.len(), PhantomData::<*const T>);
|
||||
self.set.insert(item.clone(), interned);
|
||||
self.items.push(item);
|
||||
interned
|
||||
}
|
||||
|
||||
fn get(&self, i: Interned<T>) -> &T {
|
||||
&self.items[i.0]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Interner {
|
||||
strs: Mutex<TyIntern<String>>,
|
||||
paths: Mutex<TyIntern<PathBuf>>,
|
||||
}
|
||||
|
||||
impl Interner {
|
||||
fn new() -> Interner {
|
||||
Interner {
|
||||
strs: Mutex::new(TyIntern::new()),
|
||||
paths: Mutex::new(TyIntern::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intern_str(&self, s: &str) -> Interned<String> {
|
||||
self.strs.lock().unwrap().intern_borrow(s)
|
||||
}
|
||||
pub fn intern_string(&self, s: String) -> Interned<String> {
|
||||
self.strs.lock().unwrap().intern(s)
|
||||
}
|
||||
|
||||
pub fn intern_path(&self, s: PathBuf) -> Interned<PathBuf> {
|
||||
self.paths.lock().unwrap().intern(s)
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref INTERNER: Interner = Interner::new();
|
||||
}
|
||||
|
||||
/// This is essentially a HashMap which allows storing any type in its input and
|
||||
/// any type in its output. It is a write-once cache; values are never evicted,
|
||||
@ -25,68 +260,37 @@ use std::cell::RefCell;
|
||||
//
|
||||
// FIXME: This type does not permit retrieving &Path from a PathBuf, primarily
|
||||
// due to a lack of any obvious way to ensure that this is safe, but also not
|
||||
// penalize other cases (e.g., deserializing u32 -> &u32, which is non-optimal).
|
||||
#[derive(Debug)]
|
||||
pub struct Cache(RefCell<HashMap<Key, Box<str>>>);
|
||||
|
||||
fn to_json<T: Serialize>(element: &T) -> String {
|
||||
t!(serde_json::to_string(element))
|
||||
}
|
||||
|
||||
fn from_json<'a, O: Deserialize<'a>>(data: &'a str) -> O {
|
||||
t!(serde_json::from_str(data))
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Key(TypeId, String);
|
||||
|
||||
impl fmt::Debug for Key {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&format!("{:?}; ", self.0))?;
|
||||
fmt.write_str(&self.1)
|
||||
}
|
||||
}
|
||||
pub struct Cache(
|
||||
RefCell<HashMap<
|
||||
TypeId,
|
||||
Box<Any>, // actually a HashMap<Step, Interned<Step::Output>>
|
||||
>>
|
||||
);
|
||||
|
||||
impl Cache {
|
||||
pub fn new() -> Cache {
|
||||
Cache(RefCell::new(HashMap::new()))
|
||||
}
|
||||
|
||||
pub fn to_key<'a, K: Step<'a>>(key: &K) -> Key {
|
||||
Key(TypeId::of::<K::Id>(), to_json(key))
|
||||
}
|
||||
|
||||
/// Puts a value into the cache. Will panic if called more than once with
|
||||
/// the same key.
|
||||
///
|
||||
/// Returns the internal key utilized, as an opaque structure, useful only
|
||||
/// for debugging.
|
||||
pub fn put<V>(&self, key: Key, value: &V)
|
||||
where
|
||||
V: Serialize,
|
||||
{
|
||||
pub fn put<S: Step>(&self, step: S, value: S::Output) {
|
||||
let mut cache = self.0.borrow_mut();
|
||||
let value = to_json(value);
|
||||
assert!(!cache.contains_key(&key), "processing {:?} a second time", key);
|
||||
// Store a boxed str so that it's location in memory never changes and
|
||||
// it's safe for us to return references to it (so long as they live as
|
||||
// long as us).
|
||||
cache.insert(key, value.into_boxed_str());
|
||||
let type_id = TypeId::of::<S>();
|
||||
let stepcache = cache.entry(type_id)
|
||||
.or_insert_with(|| Box::new(HashMap::<S, S::Output>::new()))
|
||||
.downcast_mut::<HashMap<S, S::Output>>()
|
||||
.expect("invalid type mapped");
|
||||
assert!(!stepcache.contains_key(&step), "processing {:?} a second time", step);
|
||||
stepcache.insert(step, value);
|
||||
}
|
||||
|
||||
pub fn get<'a, V>(&'a self, key: &Key) -> Option<V>
|
||||
where
|
||||
V: Deserialize<'a> + 'a,
|
||||
{
|
||||
let cache = self.0.borrow();
|
||||
cache.get(key).map(|v| {
|
||||
// Change the lifetime. This borrow is valid for as long as self lives;
|
||||
// the data we're accessing will live as long as us and will be in a
|
||||
// stable location, since we use Box<str>.
|
||||
let v = unsafe {
|
||||
mem::transmute::<&str, &'a str>(v)
|
||||
};
|
||||
from_json(v)
|
||||
})
|
||||
pub fn get<S: Step>(&self, step: &S) -> Option<S::Output> {
|
||||
let mut cache = self.0.borrow_mut();
|
||||
let type_id = TypeId::of::<S>();
|
||||
let stepcache = cache.entry(type_id)
|
||||
.or_insert_with(|| Box::new(HashMap::<S, S::Output>::new()))
|
||||
.downcast_mut::<HashMap<S, S::Output>>()
|
||||
.expect("invalid type mapped");
|
||||
stepcache.get(step).cloned()
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ use gcc;
|
||||
|
||||
use Build;
|
||||
use config::Target;
|
||||
use cache::Interned;
|
||||
|
||||
pub fn find(build: &mut Build) {
|
||||
// For all targets we're going to need a C compiler for building some shims
|
||||
@ -50,11 +51,11 @@ pub fn find(build: &mut Build) {
|
||||
cfg.cargo_metadata(false).opt_level(0).debug(false)
|
||||
.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()) {
|
||||
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();
|
||||
@ -63,7 +64,7 @@ pub fn find(build: &mut Build) {
|
||||
if let Some(ref ar) = ar {
|
||||
build.verbose(&format!("AR_{} = {:?}", target, ar));
|
||||
}
|
||||
build.cc.insert(target.to_string(), (compiler, ar));
|
||||
build.cc.insert(*target, (compiler, ar));
|
||||
}
|
||||
|
||||
// For all host triples we need to find a C++ compiler as well
|
||||
@ -78,20 +79,20 @@ pub fn find(build: &mut Build) {
|
||||
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.to_string(), compiler);
|
||||
build.cxx.insert(*host, compiler);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_compiler(cfg: &mut gcc::Config,
|
||||
gnu_compiler: &str,
|
||||
target: &str,
|
||||
target: Interned<String>,
|
||||
config: Option<&Target>,
|
||||
build: &Build) {
|
||||
match target {
|
||||
match &*target {
|
||||
// When compiling for android we may have the NDK configured in the
|
||||
// config.toml in which case we look there. Otherwise the default
|
||||
// compiler already takes into account the triple in question.
|
||||
|
@ -33,11 +33,12 @@ use compile;
|
||||
use native;
|
||||
use builder::{Kind, Builder, Compiler, Step};
|
||||
use tool::{self, Tool};
|
||||
use cache::{INTERNER, Interned};
|
||||
|
||||
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
||||
|
||||
/// The two modes of the test runner; tests or benchmarks.
|
||||
#[derive(Serialize, Copy, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum TestKind {
|
||||
/// Run `cargo test`
|
||||
Test,
|
||||
@ -93,13 +94,12 @@ fn try_run_quiet(build: &Build, cmd: &mut Command) {
|
||||
// .host(true)
|
||||
// .run(move |s| check::linkcheck(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Linkcheck<'a> {
|
||||
host: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Linkcheck {
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Linkcheck<'a> {
|
||||
type Id = Linkcheck<'static>;
|
||||
impl Step for Linkcheck {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
const DEFAULT: bool = true;
|
||||
@ -125,7 +125,12 @@ impl<'a> Step<'a> for Linkcheck<'a> {
|
||||
path.ends_with("src/tools/linkchecker")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
if path.is_some() {
|
||||
builder.ensure(Linkcheck { host });
|
||||
} else {
|
||||
@ -142,14 +147,13 @@ impl<'a> Step<'a> for Linkcheck<'a> {
|
||||
// .host(true)
|
||||
// .run(move |s| check::cargotest(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Cargotest<'a> {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Cargotest {
|
||||
stage: u32,
|
||||
host: &'a str,
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Cargotest<'a> {
|
||||
type Id = Cargotest<'static>;
|
||||
impl Step for Cargotest {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -157,7 +161,12 @@ impl<'a> Step<'a> for Cargotest<'a> {
|
||||
path.ends_with("src/tools/cargotest")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Cargotest {
|
||||
stage: builder.top_stage,
|
||||
host: host,
|
||||
@ -193,14 +202,13 @@ impl<'a> Step<'a> for Cargotest<'a> {
|
||||
// .host(true)
|
||||
// .run(move |s| check::cargo(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Cargo<'a> {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Cargo {
|
||||
stage: u32,
|
||||
host: &'a str,
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Cargo<'a> {
|
||||
type Id = Cargo<'static>;
|
||||
impl Step for Cargo {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -208,7 +216,12 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
path.ends_with("src/tools/cargo")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Cargotest {
|
||||
stage: builder.top_stage,
|
||||
host: target,
|
||||
@ -304,13 +317,12 @@ fn path_for_cargo(build: &Build, compiler: &Compiler) -> OsString {
|
||||
// .only_build(true)
|
||||
// .run(move |s| check::tidy(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Tidy<'a> {
|
||||
host: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Tidy {
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Tidy<'a> {
|
||||
type Id = Tidy<'static>;
|
||||
impl Step for Tidy {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -342,14 +354,19 @@ impl<'a> Step<'a> for Tidy<'a> {
|
||||
path.ends_with("src/tools/tidy")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Tidy {
|
||||
host: &builder.build.build,
|
||||
host: builder.build.build,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn testdir(build: &Build, host: &str) -> PathBuf {
|
||||
fn testdir(build: &Build, host: Interned<String>) -> PathBuf {
|
||||
build.out.join(host).join("test")
|
||||
}
|
||||
|
||||
@ -451,15 +468,15 @@ fn testdir(build: &Build, host: &str) -> PathBuf {
|
||||
// "pretty", "run-fail-fulldeps");
|
||||
// }
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Compiletest<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
target: &'a str,
|
||||
mode: &'a str,
|
||||
suite: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Compiletest {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: &'static str,
|
||||
suite: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct Test {
|
||||
path: &'static str,
|
||||
mode: &'static str,
|
||||
@ -512,8 +529,7 @@ static COMPILETESTS: &[Test] = &[
|
||||
Test { path: "src/test/debuginfo-gdb", mode: "debuginfo-gdb", suite: "debuginfo" },
|
||||
];
|
||||
|
||||
impl<'a> Step<'a> for Compiletest<'a> {
|
||||
type Id = Compiletest<'static>;
|
||||
impl Step for Compiletest {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -526,7 +542,12 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
let compiler = builder.compiler(builder.top_stage, host);
|
||||
|
||||
let test = path.map(|path| {
|
||||
@ -591,12 +612,12 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
builder.ensure(Compiletest {
|
||||
mode: "debuginfo-lldb",
|
||||
..self
|
||||
})
|
||||
});
|
||||
} else {
|
||||
builder.ensure(Compiletest {
|
||||
mode: "debuginfo-gdb",
|
||||
..self
|
||||
})
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@ -606,7 +627,7 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
}
|
||||
|
||||
builder.ensure(dist::DebuggerScripts {
|
||||
sysroot: &builder.sysroot(compiler),
|
||||
sysroot: builder.sysroot(compiler),
|
||||
target: target
|
||||
});
|
||||
|
||||
@ -630,7 +651,7 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
|
||||
let _folder = build.fold_output(|| format!("test_{}", suite));
|
||||
println!("Check compiletest suite={} mode={} ({} -> {})",
|
||||
suite, mode, compiler.host, target);
|
||||
suite, mode, &compiler.host, target);
|
||||
let mut cmd = builder.tool_cmd(Tool::Compiletest);
|
||||
|
||||
// compiletest currently has... a lot of arguments, so let's just pass all
|
||||
@ -645,8 +666,8 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
|
||||
cmd.arg("--mode").arg(mode);
|
||||
cmd.arg("--target").arg(target);
|
||||
cmd.arg("--host").arg(compiler.host);
|
||||
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.build));
|
||||
cmd.arg("--host").arg(&*compiler.host);
|
||||
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(build.build));
|
||||
|
||||
if let Some(ref nodejs) = build.config.nodejs {
|
||||
cmd.arg("--nodejs").arg(nodejs);
|
||||
@ -664,7 +685,7 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
hostflags.extend(flags.clone());
|
||||
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
|
||||
|
||||
let mut targetflags = build.rustc_flags(&target);
|
||||
let mut targetflags = build.rustc_flags(target);
|
||||
targetflags.extend(flags);
|
||||
targetflags.push(format!("-Lnative={}",
|
||||
build.test_helpers_out(target).display()));
|
||||
@ -735,7 +756,7 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
// Note that if we encounter `PATH` we make sure to append to our own `PATH`
|
||||
// rather than stomp over it.
|
||||
if target.contains("msvc") {
|
||||
for &(ref k, ref v) in build.cc[target].0.env() {
|
||||
for &(ref k, ref v) in build.cc[&target].0.env() {
|
||||
if k != "PATH" {
|
||||
cmd.env(k, v);
|
||||
}
|
||||
@ -769,9 +790,9 @@ impl<'a> Step<'a> for Compiletest<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Docs<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Docs {
|
||||
compiler: Compiler,
|
||||
}
|
||||
|
||||
// rules.test("check-docs", "src/doc")
|
||||
@ -779,8 +800,7 @@ pub struct Docs<'a> {
|
||||
// .default(true)
|
||||
// .host(true)
|
||||
// .run(move |s| check::docs(build, &s.compiler()));
|
||||
impl<'a> Step<'a> for Docs<'a> {
|
||||
type Id = Docs<'static>;
|
||||
impl Step for Docs {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -789,7 +809,12 @@ impl<'a> Step<'a> for Docs<'a> {
|
||||
path.ends_with("src/doc")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Docs {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
});
|
||||
@ -840,13 +865,12 @@ impl<'a> Step<'a> for Docs<'a> {
|
||||
// .host(true)
|
||||
// .run(move |s| check::error_index(build, &s.compiler()));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ErrorIndex<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ErrorIndex {
|
||||
compiler: Compiler,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
type Id = ErrorIndex<'static>;
|
||||
impl Step for ErrorIndex {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -855,7 +879,12 @@ impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
path.ends_with("src/tools/error_index_generator")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(ErrorIndex {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
});
|
||||
@ -933,16 +962,15 @@ fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) {
|
||||
// .host(true)
|
||||
// .run(move |s| check::krate(build, &s.compiler(), s.target,
|
||||
// Mode::Librustc, TestKind::Test, None));
|
||||
#[derive(Serialize)]
|
||||
pub struct KrateLibrustc<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct KrateLibrustc {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
test_kind: TestKind,
|
||||
krate: Option<&'a str>,
|
||||
krate: Option<Interned<String>>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for KrateLibrustc<'a> {
|
||||
type Id = KrateLibrustc<'static>;
|
||||
impl Step for KrateLibrustc {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -953,10 +981,15 @@ impl<'a> Step<'a> for KrateLibrustc<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
let compiler = builder.compiler(builder.top_stage, host);
|
||||
|
||||
let run = |name: Option<&str>| {
|
||||
let run = |name: Option<Interned<String>>| {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
@ -1043,17 +1076,16 @@ impl<'a> Step<'a> for KrateLibrustc<'a> {
|
||||
// .run(move |s| check::krate(build, &s.compiler(), s.target,
|
||||
// Mode::Libtest, TestKind::Test, None));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Krate<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Krate {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
mode: Mode,
|
||||
test_kind: TestKind,
|
||||
krate: Option<&'a str>,
|
||||
krate: Option<Interned<String>>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Krate<'a> {
|
||||
type Id = Krate<'static>;
|
||||
impl Step for Krate {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -1066,10 +1098,15 @@ impl<'a> Step<'a> for Krate<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
let compiler = builder.compiler(builder.top_stage, host);
|
||||
|
||||
let run = |mode: Mode, name: Option<&str>| {
|
||||
let run = |mode: Mode, name: Option<Interned<String>>| {
|
||||
let test_kind = if builder.kind == Kind::Test {
|
||||
TestKind::Test
|
||||
} else if builder.kind == Kind::Bench {
|
||||
@ -1134,11 +1171,12 @@ impl<'a> Step<'a> for Krate<'a> {
|
||||
}
|
||||
_ => panic!("can only test libraries"),
|
||||
};
|
||||
let root = INTERNER.intern_string(String::from(root));
|
||||
let _folder = build.fold_output(|| {
|
||||
format!("{}_stage{}-{}", test_kind.subcommand(), compiler.stage, name)
|
||||
});
|
||||
println!("{} {} stage{} ({} -> {})", test_kind, name, compiler.stage,
|
||||
compiler.host, target);
|
||||
&compiler.host, target);
|
||||
|
||||
// If we're not doing a full bootstrap but we're testing a stage2 version of
|
||||
// libstd, then what we're actually testing is the libstd produced in
|
||||
@ -1180,12 +1218,12 @@ impl<'a> Step<'a> for Krate<'a> {
|
||||
// target during the bootstrap and it's just meant to be a
|
||||
// helper crate, not tested. If it leaks through then it ends up
|
||||
// messing with various mtime calculations and such.
|
||||
if !name.contains("jemalloc") && name != "build_helper" {
|
||||
if !name.contains("jemalloc") && *name != *"build_helper" {
|
||||
cargo.arg("-p").arg(&format!("{}:0.0.0", name));
|
||||
}
|
||||
for dep in build.crates[name].deps.iter() {
|
||||
for dep in build.crates[&name].deps.iter() {
|
||||
if visited.insert(dep) {
|
||||
next.push(dep);
|
||||
next.push(*dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1198,7 +1236,7 @@ impl<'a> Step<'a> for Krate<'a> {
|
||||
// Note that to run the compiler we need to run with the *host* libraries,
|
||||
// but our wrapper scripts arrange for that to be the case anyway.
|
||||
let mut dylib_path = dylib_path();
|
||||
dylib_path.insert(0, builder.sysroot_libdir(compiler, target));
|
||||
dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
|
||||
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
|
||||
|
||||
if target.contains("emscripten") || build.remote_tested(target) {
|
||||
@ -1228,7 +1266,7 @@ impl<'a> Step<'a> for Krate<'a> {
|
||||
|
||||
fn krate_emscripten(build: &Build,
|
||||
compiler: Compiler,
|
||||
target: &str,
|
||||
target: Interned<String>,
|
||||
mode: Mode) {
|
||||
let out_dir = build.cargo_out(compiler, mode, target);
|
||||
let tests = find_tests(&out_dir.join("deps"), target);
|
||||
@ -1247,7 +1285,7 @@ fn krate_emscripten(build: &Build,
|
||||
|
||||
fn krate_remote(builder: &Builder,
|
||||
compiler: Compiler,
|
||||
target: &str,
|
||||
target: Interned<String>,
|
||||
mode: Mode) {
|
||||
let build = builder.build;
|
||||
let out_dir = build.cargo_out(compiler, mode, target);
|
||||
@ -1266,7 +1304,7 @@ fn krate_remote(builder: &Builder,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_tests(dir: &Path, target: &str) -> Vec<PathBuf> {
|
||||
fn find_tests(dir: &Path, target: Interned<String>) -> Vec<PathBuf> {
|
||||
let mut dst = Vec::new();
|
||||
for e in t!(dir.read_dir()).map(|e| t!(e)) {
|
||||
let file_type = t!(e.file_type());
|
||||
@ -1313,14 +1351,13 @@ fn find_tests(dir: &Path, target: &str) -> Vec<PathBuf> {
|
||||
/// QEMU we have to build our own tools so we've got conditional dependencies
|
||||
/// on those programs as well. Note that the remote test client is built for
|
||||
/// the build target (us) and the server is built for the target.
|
||||
#[derive(Serialize)]
|
||||
pub struct RemoteCopyLibs<'a> {
|
||||
compiler: Compiler<'a>,
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct RemoteCopyLibs {
|
||||
compiler: Compiler,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for RemoteCopyLibs<'a> {
|
||||
type Id = RemoteCopyLibs<'static>;
|
||||
impl Step for RemoteCopyLibs {
|
||||
type Output = ();
|
||||
|
||||
fn run(self, builder: &Builder) {
|
||||
@ -1368,18 +1405,17 @@ impl<'a> Step<'a> for RemoteCopyLibs<'a> {
|
||||
// .dep(|s| s.name("dist-src"))
|
||||
// .run(move |_| check::distcheck(build));
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Distcheck;
|
||||
|
||||
impl<'a> Step<'a> for Distcheck {
|
||||
type Id = Distcheck;
|
||||
impl Step for Distcheck {
|
||||
type Output = ();
|
||||
|
||||
/// Run "distcheck", a 'make check' from a tarball
|
||||
fn run(self, builder: &Builder) {
|
||||
let build = builder.build;
|
||||
|
||||
if build.build != "x86_64-unknown-linux-gnu" {
|
||||
if *build.build != *"x86_64-unknown-linux-gnu" {
|
||||
return
|
||||
}
|
||||
if !build.config.host.iter().any(|s| s == "x86_64-unknown-linux-gnu") {
|
||||
@ -1436,11 +1472,10 @@ impl<'a> Step<'a> for Distcheck {
|
||||
// .only_build(true)
|
||||
// .run(move |_| check::bootstrap(build));
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Bootstrap;
|
||||
|
||||
impl<'a> Step<'a> for Bootstrap {
|
||||
type Id = Bootstrap;
|
||||
impl Step for Bootstrap {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -1466,7 +1501,12 @@ impl<'a> Step<'a> for Bootstrap {
|
||||
path.ends_with("src/bootstrap")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
_target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Bootstrap);
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ use util::{exe, libdir, is_dylib, copy};
|
||||
use {Build, Compiler, Mode};
|
||||
use native;
|
||||
|
||||
use cache::{INTERNER, Interned};
|
||||
use builder::{Step, Builder};
|
||||
|
||||
//
|
||||
@ -140,14 +141,13 @@ use builder::{Step, Builder};
|
||||
// .dep(move |s| s.name("rustc").host(&build.build).target(s.host))
|
||||
// .run(move |s| compile::std(build, s.target, &s.compiler()));
|
||||
// }
|
||||
#[derive(Serialize)]
|
||||
pub struct Std<'a> {
|
||||
pub target: &'a str,
|
||||
pub compiler: Compiler<'a>,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Std {
|
||||
pub target: Interned<String>,
|
||||
pub compiler: Compiler,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Std<'a> {
|
||||
type Id = Std<'static>;
|
||||
impl Step for Std {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -158,11 +158,16 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Std {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
target,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/// Build the standard library.
|
||||
@ -178,7 +183,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
builder.ensure(StartupObjects { compiler, target });
|
||||
|
||||
if build.force_use_stage1(compiler, target) {
|
||||
let from = builder.compiler(1, &build.build);
|
||||
let from = builder.compiler(1, build.build);
|
||||
builder.ensure(Std {
|
||||
compiler: from,
|
||||
target: target,
|
||||
@ -194,7 +199,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-std", compiler.stage));
|
||||
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
|
||||
compiler.host, target);
|
||||
&compiler.host, target);
|
||||
|
||||
let out_dir = build.cargo_out(compiler, Mode::Libstd, target);
|
||||
build.clear_if_dirty(&out_dir, &builder.rustc(compiler));
|
||||
@ -229,7 +234,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
.arg("--manifest-path")
|
||||
.arg(build.src.join("src/libstd/Cargo.toml"));
|
||||
|
||||
if let Some(target) = build.config.target_config.get(target) {
|
||||
if let Some(target) = build.config.target_config.get(&target) {
|
||||
if let Some(ref jemalloc) = target.jemalloc {
|
||||
cargo.env("JEMALLOC_OVERRIDE", jemalloc);
|
||||
}
|
||||
@ -245,7 +250,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
&libstd_stamp(build, compiler, target));
|
||||
|
||||
builder.ensure(StdLink {
|
||||
compiler: builder.compiler(compiler.stage, &build.build),
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
target_compiler: compiler,
|
||||
target: target,
|
||||
});
|
||||
@ -261,15 +266,14 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
// .dep(|s| s.name("startup-objects"))
|
||||
// .dep(|s| s.name("create-sysroot").target(s.host));
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct StdLink<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target_compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct StdLink {
|
||||
pub compiler: Compiler,
|
||||
pub target_compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for StdLink<'a> {
|
||||
type Id = StdLink<'static>;
|
||||
impl Step for StdLink {
|
||||
type Output = ();
|
||||
|
||||
/// Link all libstd rlibs/dylibs into the sysroot location.
|
||||
@ -288,7 +292,7 @@ impl<'a> Step<'a> for StdLink<'a> {
|
||||
println!("Copying stage{} std from stage{} ({} -> {} / {})",
|
||||
target_compiler.stage,
|
||||
compiler.stage,
|
||||
compiler.host,
|
||||
&compiler.host,
|
||||
target_compiler.host,
|
||||
target);
|
||||
let libdir = builder.sysroot_libdir(target_compiler, target);
|
||||
@ -310,7 +314,7 @@ impl<'a> Step<'a> for StdLink<'a> {
|
||||
/// Copies the crt(1,i,n).o startup objects
|
||||
///
|
||||
/// Only required for musl targets that statically link to libc
|
||||
fn copy_musl_third_party_objects(build: &Build, target: &str, into: &Path) {
|
||||
fn copy_musl_third_party_objects(build: &Build, target: Interned<String>, into: &Path) {
|
||||
for &obj in &["crt1.o", "crti.o", "crtn.o"] {
|
||||
copy(&build.musl_root(target).unwrap().join("lib").join(obj), &into.join(obj));
|
||||
}
|
||||
@ -332,25 +336,29 @@ fn copy_apple_sanitizer_dylibs(native_dir: &Path, platform: &str, into: &Path) {
|
||||
// .dep(|s| s.name("create-sysroot").target(s.host))
|
||||
// .run(move |s| compile::build_startup_objects(build, &s.compiler(), s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct StartupObjects<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct StartupObjects {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for StartupObjects<'a> {
|
||||
type Id = StartupObjects<'static>;
|
||||
impl Step for StartupObjects {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with("src/rtstartup")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(StartupObjects {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
target,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/// Build and prepare startup objects like rsbegin.o and rsend.o
|
||||
@ -399,14 +407,13 @@ impl<'a> Step<'a> for StartupObjects<'a> {
|
||||
// .dep(|s| s.name("libstd-link"))
|
||||
// .run(move |s| compile::test(build, s.target, &s.compiler()));
|
||||
// }
|
||||
#[derive(Serialize)]
|
||||
pub struct Test<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Test {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Test<'a> {
|
||||
type Id = Test<'static>;
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -417,11 +424,16 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Test {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
target,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/// Build libtest.
|
||||
@ -438,12 +450,12 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
|
||||
if build.force_use_stage1(compiler, target) {
|
||||
builder.ensure(Test {
|
||||
compiler: builder.compiler(1, &build.build),
|
||||
compiler: builder.compiler(1, build.build),
|
||||
target: target,
|
||||
});
|
||||
println!("Uplifting stage1 test ({} -> {})", &build.build, target);
|
||||
builder.ensure(TestLink {
|
||||
compiler: builder.compiler(1, &build.build),
|
||||
compiler: builder.compiler(1, build.build),
|
||||
target_compiler: compiler,
|
||||
target: target,
|
||||
});
|
||||
@ -452,7 +464,7 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-test", compiler.stage));
|
||||
println!("Building stage{} test artifacts ({} -> {})", compiler.stage,
|
||||
compiler.host, target);
|
||||
&compiler.host, target);
|
||||
let out_dir = build.cargo_out(compiler, Mode::Libtest, target);
|
||||
build.clear_if_dirty(&out_dir, &libstd_stamp(build, compiler, target));
|
||||
let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
|
||||
@ -466,7 +478,7 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
&libtest_stamp(build, compiler, target));
|
||||
|
||||
builder.ensure(TestLink {
|
||||
compiler: builder.compiler(compiler.stage, &build.build),
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
target_compiler: compiler,
|
||||
target: target,
|
||||
});
|
||||
@ -481,15 +493,14 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
// compile::test_link)
|
||||
// .dep(|s| s.name("libstd-link"));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct TestLink<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target_compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TestLink {
|
||||
pub compiler: Compiler,
|
||||
pub target_compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for TestLink<'a> {
|
||||
type Id = TestLink<'static>;
|
||||
impl Step for TestLink {
|
||||
type Output = ();
|
||||
|
||||
/// Same as `std_link`, only for libtest
|
||||
@ -501,7 +512,7 @@ impl<'a> Step<'a> for TestLink<'a> {
|
||||
println!("Copying stage{} test from stage{} ({} -> {} / {})",
|
||||
target_compiler.stage,
|
||||
compiler.stage,
|
||||
compiler.host,
|
||||
&compiler.host,
|
||||
target_compiler.host,
|
||||
target);
|
||||
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
||||
@ -517,14 +528,13 @@ impl<'a> Step<'a> for TestLink<'a> {
|
||||
// .run(move |s| compile::rustc(build, s.target, &s.compiler()));
|
||||
// }
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Rustc<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Rustc {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rustc<'a> {
|
||||
type Id = Rustc<'static>;
|
||||
impl Step for Rustc {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
const DEFAULT: bool = true;
|
||||
@ -536,11 +546,16 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Rustc {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
target,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/// Build the compiler.
|
||||
@ -561,12 +576,12 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
|
||||
if build.force_use_stage1(compiler, target) {
|
||||
builder.ensure(Rustc {
|
||||
compiler: builder.compiler(1, &build.build),
|
||||
compiler: builder.compiler(1, build.build),
|
||||
target: target,
|
||||
});
|
||||
println!("Uplifting stage1 rustc ({} -> {})", &build.build, target);
|
||||
builder.ensure(RustcLink {
|
||||
compiler: builder.compiler(1, &build.build),
|
||||
compiler: builder.compiler(1, build.build),
|
||||
target_compiler: compiler,
|
||||
target,
|
||||
});
|
||||
@ -575,13 +590,13 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
|
||||
// Ensure that build scripts have a std to link against.
|
||||
builder.ensure(Std {
|
||||
compiler: builder.compiler(self.compiler.stage, &build.build),
|
||||
target: &build.build,
|
||||
compiler: builder.compiler(self.compiler.stage, build.build),
|
||||
target: build.build,
|
||||
});
|
||||
|
||||
let _folder = build.fold_output(|| format!("stage{}-rustc", compiler.stage));
|
||||
println!("Building stage{} compiler artifacts ({} -> {})",
|
||||
compiler.stage, compiler.host, target);
|
||||
compiler.stage, &compiler.host, target);
|
||||
|
||||
let out_dir = build.cargo_out(compiler, Mode::Librustc, target);
|
||||
build.clear_if_dirty(&out_dir, &libtest_stamp(build, compiler, target));
|
||||
@ -627,7 +642,7 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
cargo.env("LLVM_RUSTLLVM", "1");
|
||||
}
|
||||
cargo.env("LLVM_CONFIG", build.llvm_config(target));
|
||||
let target_config = build.config.target_config.get(target);
|
||||
let target_config = build.config.target_config.get(&target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
cargo.env("CFG_LLVM_ROOT", s);
|
||||
}
|
||||
@ -653,7 +668,7 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
&librustc_stamp(build, compiler, target));
|
||||
|
||||
builder.ensure(RustcLink {
|
||||
compiler: builder.compiler(compiler.stage, &build.build),
|
||||
compiler: builder.compiler(compiler.stage, build.build),
|
||||
target_compiler: compiler,
|
||||
target,
|
||||
});
|
||||
@ -666,15 +681,14 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
// "build-crate-rustc-main",
|
||||
// compile::rustc_link)
|
||||
// .dep(|s| s.name("libtest-link"));
|
||||
#[derive(Serialize)]
|
||||
struct RustcLink<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target_compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct RustcLink {
|
||||
pub compiler: Compiler,
|
||||
pub target_compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for RustcLink<'a> {
|
||||
type Id = RustcLink<'static>;
|
||||
impl Step for RustcLink {
|
||||
type Output = ();
|
||||
|
||||
/// Same as `std_link`, only for librustc
|
||||
@ -686,7 +700,7 @@ impl<'a> Step<'a> for RustcLink<'a> {
|
||||
println!("Copying stage{} rustc from stage{} ({} -> {} / {})",
|
||||
target_compiler.stage,
|
||||
compiler.stage,
|
||||
compiler.host,
|
||||
&compiler.host,
|
||||
target_compiler.host,
|
||||
target);
|
||||
add_to_sysroot(&builder.sysroot_libdir(target_compiler, target),
|
||||
@ -696,19 +710,19 @@ impl<'a> Step<'a> for RustcLink<'a> {
|
||||
|
||||
/// Cargo's output path for the standard library in a given stage, compiled
|
||||
/// by a particular compiler for the specified target.
|
||||
pub fn libstd_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
|
||||
pub fn libstd_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Libstd, target).join(".libstd.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for libtest in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn libtest_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
|
||||
pub fn libtest_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Libtest, target).join(".libtest.stamp")
|
||||
}
|
||||
|
||||
/// Cargo's output path for librustc in a given stage, compiled by a particular
|
||||
/// compiler for the specified target.
|
||||
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: &str) -> PathBuf {
|
||||
pub fn librustc_stamp(build: &Build, compiler: Compiler, target: Interned<String>) -> PathBuf {
|
||||
build.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
|
||||
}
|
||||
|
||||
@ -721,14 +735,13 @@ fn compiler_file(compiler: &Path, file: &str) -> PathBuf {
|
||||
// rules.build("create-sysroot", "path/to/nowhere")
|
||||
// .run(move |s| compile::create_sysroot(build, &s.compiler()));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Sysroot<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Sysroot {
|
||||
pub compiler: Compiler,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Sysroot<'a> {
|
||||
type Id = Sysroot<'static>;
|
||||
type Output = PathBuf;
|
||||
impl Step for Sysroot {
|
||||
type Output = Interned<PathBuf>;
|
||||
|
||||
/// Returns the sysroot for the `compiler` specified that *this build system
|
||||
/// generates*.
|
||||
@ -736,17 +749,17 @@ impl<'a> Step<'a> for Sysroot<'a> {
|
||||
/// That is, the sysroot for the stage0 compiler is not what the compiler
|
||||
/// thinks it is by default, but it's the same as the default for stages
|
||||
/// 1-3.
|
||||
fn run(self, builder: &Builder) -> PathBuf {
|
||||
fn run(self, builder: &Builder) -> Interned<PathBuf> {
|
||||
let build = builder.build;
|
||||
let compiler = self.compiler;
|
||||
let sysroot = if compiler.stage == 0 {
|
||||
build.out.join(compiler.host).join("stage0-sysroot")
|
||||
build.out.join(&compiler.host).join("stage0-sysroot")
|
||||
} else {
|
||||
build.out.join(compiler.host).join(format!("stage{}", compiler.stage))
|
||||
build.out.join(&compiler.host).join(format!("stage{}", compiler.stage))
|
||||
};
|
||||
let _ = fs::remove_dir_all(&sysroot);
|
||||
t!(fs::create_dir_all(&sysroot));
|
||||
sysroot
|
||||
INTERNER.intern_path(sysroot)
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,25 +777,24 @@ impl<'a> Step<'a> for Sysroot<'a> {
|
||||
// })
|
||||
// .run(move |s| compile::assemble_rustc(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Assemble<'a> {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Assemble {
|
||||
/// The compiler which we will produce in this step. Assemble itself will
|
||||
/// take care of ensuring that the necessary prerequisites to do so exist,
|
||||
/// that is, this target can be a stage2 compiler and Assemble will build
|
||||
/// previous stages for you.
|
||||
pub target_compiler: Compiler<'a>,
|
||||
pub target_compiler: Compiler,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Assemble<'a> {
|
||||
type Id = Assemble<'static>;
|
||||
type Output = Compiler<'a>;
|
||||
impl Step for Assemble {
|
||||
type Output = Compiler;
|
||||
|
||||
/// Prepare a new compiler from the artifacts in `stage`
|
||||
///
|
||||
/// This will assemble a compiler in `build/$host/stage$stage`. The compiler
|
||||
/// must have been previously produced by the `stage - 1` build.build
|
||||
/// compiler.
|
||||
fn run(self, builder: &Builder) -> Compiler<'a> {
|
||||
fn run(self, builder: &Builder) -> Compiler {
|
||||
let build = builder.build;
|
||||
let target_compiler = self.target_compiler;
|
||||
|
||||
@ -799,21 +811,14 @@ impl<'a> Step<'a> for Assemble<'a> {
|
||||
// compiler for the host platform for this because it doesn't have
|
||||
// the libraries we need. FIXME: Perhaps we should download those
|
||||
// libraries? It would make builds faster...
|
||||
builder.ensure(Assemble {
|
||||
target_compiler: Compiler {
|
||||
// FIXME: It may be faster if we build just a stage 1
|
||||
// compiler and then use that to bootstrap this compiler
|
||||
// forward.
|
||||
stage: target_compiler.stage - 1,
|
||||
host: &build.build
|
||||
},
|
||||
})
|
||||
// FIXME: It may be faster if we build just a stage 1
|
||||
// compiler and then use that to bootstrap this compiler
|
||||
// forward.
|
||||
builder.compiler(target_compiler.stage - 1, build.build)
|
||||
} else {
|
||||
// Build the compiler we'll use to build the stage requested. This
|
||||
// may build more than one compiler (going down to stage 0).
|
||||
builder.ensure(Assemble {
|
||||
target_compiler: target_compiler.with_stage(target_compiler.stage - 1),
|
||||
})
|
||||
builder.compiler(target_compiler.stage - 1, target_compiler.host)
|
||||
};
|
||||
|
||||
// Build the libraries for this compiler to link to (i.e., the libraries
|
||||
@ -829,7 +834,7 @@ impl<'a> Step<'a> for Assemble<'a> {
|
||||
|
||||
// Link in all dylibs to the libdir
|
||||
let sysroot = builder.sysroot(target_compiler);
|
||||
let sysroot_libdir = sysroot.join(libdir(host));
|
||||
let sysroot_libdir = sysroot.join(libdir(&*host));
|
||||
t!(fs::create_dir_all(&sysroot_libdir));
|
||||
let src_libdir = builder.sysroot_libdir(build_compiler, host);
|
||||
for f in t!(fs::read_dir(&src_libdir)).map(|f| t!(f)) {
|
||||
@ -842,7 +847,7 @@ impl<'a> Step<'a> for Assemble<'a> {
|
||||
let out_dir = build.cargo_out(build_compiler, Mode::Librustc, host);
|
||||
|
||||
// Link the compiler binary itself into place
|
||||
let rustc = out_dir.join(exe("rustc", host));
|
||||
let rustc = out_dir.join(exe("rustc", &*host));
|
||||
let bindir = sysroot.join("bin");
|
||||
t!(fs::create_dir_all(&bindir));
|
||||
let compiler = builder.rustc(target_compiler);
|
||||
@ -850,7 +855,7 @@ impl<'a> Step<'a> for Assemble<'a> {
|
||||
copy(&rustc, &compiler);
|
||||
|
||||
// See if rustdoc exists to link it into place
|
||||
let rustdoc = exe("rustdoc", host);
|
||||
let rustdoc = exe("rustdoc", &*host);
|
||||
let rustdoc_src = out_dir.join(&rustdoc);
|
||||
let rustdoc_dst = bindir.join(&rustdoc);
|
||||
if fs::metadata(&rustdoc_src).is_ok() {
|
||||
|
@ -23,6 +23,7 @@ use std::process;
|
||||
use num_cpus;
|
||||
use toml;
|
||||
use util::{exe, push_exe_path};
|
||||
use cache::{INTERNER, Interned};
|
||||
|
||||
/// Global configuration for the entire build and/or bootstrap.
|
||||
///
|
||||
@ -45,7 +46,7 @@ pub struct Config {
|
||||
pub docs: bool,
|
||||
pub locked_deps: bool,
|
||||
pub vendor: bool,
|
||||
pub target_config: HashMap<String, Target>,
|
||||
pub target_config: HashMap<Interned<String>, Target>,
|
||||
pub full_bootstrap: bool,
|
||||
pub extended: bool,
|
||||
pub sanitizers: bool,
|
||||
@ -77,9 +78,9 @@ pub struct Config {
|
||||
pub rust_debuginfo_tests: bool,
|
||||
pub rust_dist_src: bool,
|
||||
|
||||
pub build: String,
|
||||
pub host: Vec<String>,
|
||||
pub target: Vec<String>,
|
||||
pub build: Interned<String>,
|
||||
pub host: Vec<Interned<String>>,
|
||||
pub target: Vec<Interned<String>>,
|
||||
pub local_rebuild: bool,
|
||||
|
||||
// dist misc
|
||||
@ -282,7 +283,7 @@ impl Config {
|
||||
config.docs = true;
|
||||
config.rust_rpath = true;
|
||||
config.rust_codegen_units = 1;
|
||||
config.build = build.to_string();
|
||||
config.build = INTERNER.intern_str(build);
|
||||
config.channel = "dev".to_string();
|
||||
config.codegen_tests = true;
|
||||
config.rust_dist_src = true;
|
||||
@ -302,16 +303,19 @@ impl Config {
|
||||
}).unwrap_or_else(|| TomlConfig::default());
|
||||
|
||||
let build = toml.build.clone().unwrap_or(Build::default());
|
||||
set(&mut config.build, build.build.clone());
|
||||
set(&mut config.build, build.build.clone().map(|x| INTERNER.intern_string(x)));
|
||||
config.host.push(config.build.clone());
|
||||
for host in build.host.iter() {
|
||||
if !config.host.contains(host) {
|
||||
config.host.push(host.clone());
|
||||
let host = INTERNER.intern_str(host);
|
||||
if !config.host.contains(&host) {
|
||||
config.host.push(host);
|
||||
}
|
||||
}
|
||||
for target in config.host.iter().chain(&build.target) {
|
||||
if !config.target.contains(target) {
|
||||
config.target.push(target.clone());
|
||||
for target in config.host.iter().cloned()
|
||||
.chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
|
||||
{
|
||||
if !config.target.contains(&target) {
|
||||
config.target.push(target);
|
||||
}
|
||||
}
|
||||
config.nodejs = build.nodejs.map(PathBuf::from);
|
||||
@ -404,7 +408,7 @@ impl Config {
|
||||
target.musl_root = cfg.musl_root.clone().map(PathBuf::from);
|
||||
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);
|
||||
|
||||
config.target_config.insert(triple.clone(), target);
|
||||
config.target_config.insert(INTERNER.intern_string(triple.clone()), target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,13 +510,13 @@ impl Config {
|
||||
}
|
||||
|
||||
match key {
|
||||
"CFG_BUILD" if value.len() > 0 => self.build = value.to_string(),
|
||||
"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| s.to_string()));
|
||||
self.host.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
||||
|
||||
}
|
||||
"CFG_TARGET" if value.len() > 0 => {
|
||||
self.target.extend(value.split(" ").map(|s| s.to_string()));
|
||||
self.target.extend(value.split(" ").map(|s| INTERNER.intern_str(s)));
|
||||
}
|
||||
"CFG_EXPERIMENTAL_TARGETS" if value.len() > 0 => {
|
||||
self.llvm_experimental_targets = Some(value.to_string());
|
||||
@ -521,33 +525,28 @@ impl Config {
|
||||
self.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_MUSL_ROOT_X86_64" if value.len() > 0 => {
|
||||
let target = "x86_64-unknown-linux-musl".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("x86_64-unknown-linux-musl");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_MUSL_ROOT_I686" if value.len() > 0 => {
|
||||
let target = "i686-unknown-linux-musl".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("i686-unknown-linux-musl");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_MUSL_ROOT_ARM" if value.len() > 0 => {
|
||||
let target = "arm-unknown-linux-musleabi".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("arm-unknown-linux-musleabi");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_MUSL_ROOT_ARMHF" if value.len() > 0 => {
|
||||
let target = "arm-unknown-linux-musleabihf".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("arm-unknown-linux-musleabihf");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_MUSL_ROOT_ARMV7" if value.len() > 0 => {
|
||||
let target = "armv7-unknown-linux-musleabihf".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("armv7-unknown-linux-musleabihf");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.musl_root = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_DEFAULT_AR" if value.len() > 0 => {
|
||||
@ -595,33 +594,28 @@ impl Config {
|
||||
target.jemalloc = Some(parse_configure_path(value).join("libjemalloc_pic.a"));
|
||||
}
|
||||
"CFG_ARM_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => {
|
||||
let target = "arm-linux-androideabi".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("arm-linux-androideabi");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.ndk = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_ARMV7_LINUX_ANDROIDEABI_NDK" if value.len() > 0 => {
|
||||
let target = "armv7-linux-androideabi".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("armv7-linux-androideabi");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.ndk = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
||||
let target = "i686-linux-android".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("i686-linux-android");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.ndk = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
||||
let target = "aarch64-linux-android".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("aarch64-linux-android");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.ndk = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_X86_64_LINUX_ANDROID_NDK" if value.len() > 0 => {
|
||||
let target = "x86_64-linux-android".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("x86_64-linux-android");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.ndk = Some(parse_configure_path(value));
|
||||
}
|
||||
"CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
|
||||
@ -645,9 +639,8 @@ impl Config {
|
||||
.collect();
|
||||
}
|
||||
"CFG_QEMU_ARMHF_ROOTFS" if value.len() > 0 => {
|
||||
let target = "arm-unknown-linux-gnueabihf".to_string();
|
||||
let target = self.target_config.entry(target)
|
||||
.or_insert(Target::default());
|
||||
let target = INTERNER.intern_str("arm-unknown-linux-gnueabihf");
|
||||
let target = self.target_config.entry(target).or_insert(Target::default());
|
||||
target.qemu_rootfs = Some(parse_configure_path(value));
|
||||
}
|
||||
_ => {}
|
||||
|
@ -40,6 +40,7 @@ use util::{cp_r, libdir, is_dylib, cp_filtered, copy, exe};
|
||||
use builder::{Builder, Step};
|
||||
use compile;
|
||||
use tool::{self, Tool};
|
||||
use cache::{INTERNER, Interned};
|
||||
|
||||
pub fn pkgname(build: &Build, component: &str) -> String {
|
||||
if component == "cargo" {
|
||||
@ -71,14 +72,13 @@ fn rust_installer(builder: &Builder) -> Command {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::docs(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Docs<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Docs {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Docs<'a> {
|
||||
type Id = Docs<'static>;
|
||||
impl Step for Docs {
|
||||
type Output = Option<PathBuf>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -87,7 +87,9 @@ impl<'a> Step<'a> for Docs<'a> {
|
||||
path.ends_with("src/doc")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(Docs {
|
||||
stage: builder.top_stage,
|
||||
target: target,
|
||||
@ -165,7 +167,9 @@ fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
|
||||
found
|
||||
}
|
||||
|
||||
fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build: &Build) {
|
||||
fn make_win_dist(
|
||||
rust_root: &Path, plat_root: &Path, target_triple: Interned<String>, build: &Build
|
||||
) {
|
||||
//Ask gcc where it keeps its stuff
|
||||
let mut cmd = Command::new(build.cc(target_triple));
|
||||
cmd.arg("-print-search-dirs");
|
||||
@ -282,13 +286,12 @@ fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build:
|
||||
// }
|
||||
// });
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Mingw<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Mingw {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Mingw<'a> {
|
||||
type Id = Mingw<'static>;
|
||||
impl Step for Mingw {
|
||||
type Output = Option<PathBuf>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -297,7 +300,9 @@ impl<'a> Step<'a> for Mingw<'a> {
|
||||
false
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Mingw { target });
|
||||
}
|
||||
|
||||
@ -350,14 +355,13 @@ impl<'a> Step<'a> for Mingw<'a> {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::rustc(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Rustc<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rustc {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rustc<'a> {
|
||||
type Id = Rustc<'static>;
|
||||
impl Step for Rustc {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -367,7 +371,9 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
path.ends_with("src/librustc")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Rustc {
|
||||
stage: builder.top_stage,
|
||||
target: target,
|
||||
@ -381,7 +387,7 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
let target = self.target;
|
||||
|
||||
let compiler = builder.ensure(compile::Assemble {
|
||||
target_compiler: builder.compiler(stage, &build.build),
|
||||
target_compiler: builder.compiler(stage, build.build),
|
||||
});
|
||||
|
||||
println!("Dist rustc stage{} ({})", stage, target);
|
||||
@ -444,10 +450,12 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
|
||||
return distdir(build).join(format!("{}-{}.tar.gz", name, target));
|
||||
|
||||
fn prepare_image(builder: &Builder, compiler: Compiler, target: &str, image: &Path) {
|
||||
fn prepare_image(
|
||||
builder: &Builder, compiler: Compiler, target: Interned<String>, image: &Path
|
||||
) {
|
||||
let build = builder.build;
|
||||
let src = builder.sysroot(compiler);
|
||||
let libdir = libdir(target);
|
||||
let libdir = libdir(&target);
|
||||
|
||||
// Copy rustc/rustdoc binaries
|
||||
t!(fs::create_dir_all(image.join("bin")));
|
||||
@ -471,7 +479,7 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
|
||||
// Debugger scripts
|
||||
builder.ensure(DebuggerScripts {
|
||||
sysroot: &image,
|
||||
sysroot: INTERNER.intern_path(image.to_owned()),
|
||||
target: target,
|
||||
});
|
||||
|
||||
@ -491,23 +499,24 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
// .run(move |s| dist::debugger_scripts(build, &builder.sysroot(&s.compiler()),
|
||||
// s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct DebuggerScripts<'a> {
|
||||
pub sysroot: &'a Path,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct DebuggerScripts {
|
||||
pub sysroot: Interned<PathBuf>,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for DebuggerScripts<'a> {
|
||||
type Id = DebuggerScripts<'static>;
|
||||
impl Step for DebuggerScripts {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with("src/etc/lldb_batchmode.py")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(DebuggerScripts {
|
||||
sysroot: &builder.sysroot(builder.compiler(builder.top_stage, host)),
|
||||
sysroot: builder.sysroot(builder.compiler(builder.top_stage, host)),
|
||||
target: target,
|
||||
});
|
||||
}
|
||||
@ -564,14 +573,13 @@ impl<'a> Step<'a> for DebuggerScripts<'a> {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::std(build, &s.compiler(), s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Std<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Std {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Std<'a> {
|
||||
type Id = Std<'static>;
|
||||
impl Step for Std {
|
||||
type Output = Option<PathBuf>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -580,7 +588,9 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
path.ends_with("src/libstd")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Std {
|
||||
compiler: builder.compiler(builder.top_stage, host),
|
||||
target: target,
|
||||
@ -592,7 +602,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
println!("Dist std stage{} ({} -> {})", compiler.stage, compiler.host,
|
||||
println!("Dist std stage{} ({} -> {})", compiler.stage, &compiler.host,
|
||||
target);
|
||||
|
||||
// The only true set of target libraries came from the build triple, so
|
||||
@ -617,7 +627,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
|
||||
let dst = image.join("lib/rustlib").join(target);
|
||||
t!(fs::create_dir_all(&dst));
|
||||
let mut src = builder.sysroot_libdir(compiler, target);
|
||||
let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
|
||||
src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
|
||||
cp_r(&src, &dst);
|
||||
|
||||
@ -645,14 +655,13 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::analysis(build, &s.compiler(), s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Analysis<'a> {
|
||||
pub compiler: Compiler<'a>,
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Analysis {
|
||||
pub compiler: Compiler,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Analysis<'a> {
|
||||
type Id = Analysis<'static>;
|
||||
impl Step for Analysis {
|
||||
type Output = Option<PathBuf>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -661,7 +670,12 @@ impl<'a> Step<'a> for Analysis<'a> {
|
||||
path.ends_with("analysis")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.extended {
|
||||
return;
|
||||
}
|
||||
@ -679,7 +693,7 @@ impl<'a> Step<'a> for Analysis<'a> {
|
||||
assert!(build.config.extended);
|
||||
println!("Dist analysis");
|
||||
|
||||
if compiler.host != build.build {
|
||||
if &compiler.host != build.build {
|
||||
println!("\tskipping, not a build host");
|
||||
return None;
|
||||
}
|
||||
@ -769,11 +783,10 @@ fn copy_src_dirs(build: &Build, src_dirs: &[&str], exclude_dirs: &[&str], dst_di
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |_| dist::rust_src(build));
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Src;
|
||||
|
||||
impl<'a> Step<'a> for Src {
|
||||
type Id = Src;
|
||||
impl Step for Src {
|
||||
/// The output path of the src installer tarball
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
@ -785,7 +798,9 @@ impl<'a> Step<'a> for Src {
|
||||
path.ends_with("src")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, _target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Src);
|
||||
}
|
||||
|
||||
@ -867,11 +882,10 @@ const CARGO_VENDOR_VERSION: &str = "0.1.4";
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |_| dist::plain_source_tarball(build));
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct PlainSourceTarball;
|
||||
|
||||
impl<'a> Step<'a> for PlainSourceTarball {
|
||||
type Id = PlainSourceTarball;
|
||||
impl Step for PlainSourceTarball {
|
||||
/// Produces the location of the tarball generated
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
@ -883,7 +897,9 @@ impl<'a> Step<'a> for PlainSourceTarball {
|
||||
path.ends_with("src")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, _target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.rust_dist_src {
|
||||
return;
|
||||
}
|
||||
@ -1019,14 +1035,13 @@ fn write_file(path: &Path, data: &[u8]) {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::cargo(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Cargo<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Cargo {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Cargo<'a> {
|
||||
type Id = Cargo<'static>;
|
||||
impl Step for Cargo {
|
||||
type Output = PathBuf;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -1035,7 +1050,9 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
path.ends_with("cargo")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Cargo {
|
||||
stage: builder.top_stage,
|
||||
target: target,
|
||||
@ -1050,7 +1067,7 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
builder.ensure(tool::Cargo { stage, target });
|
||||
|
||||
println!("Dist cargo stage{} ({})", stage, target);
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
|
||||
let src = build.src.join("src/tools/cargo");
|
||||
let etc = src.join("src/etc");
|
||||
@ -1067,7 +1084,7 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
t!(fs::create_dir_all(image.join("share/zsh/site-functions")));
|
||||
t!(fs::create_dir_all(image.join("etc/bash_completion.d")));
|
||||
let cargo = build.cargo_out(compiler, Mode::Tool, target)
|
||||
.join(exe("cargo", target));
|
||||
.join(exe("cargo", &target));
|
||||
install(&cargo, &image.join("bin"), 0o755);
|
||||
for man in t!(etc.join("man").read_dir()) {
|
||||
let man = t!(man);
|
||||
@ -1116,14 +1133,13 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
// .dep(|s| s.name("tool-rls"))
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::rls(build, s.stage, s.target));
|
||||
#[derive(Serialize)]
|
||||
pub struct Rls<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rls {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rls<'a> {
|
||||
type Id = Rls<'static>;
|
||||
impl Step for Rls {
|
||||
type Output = PathBuf;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -1132,7 +1148,9 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
path.ends_with("rls")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
builder.ensure(Rls {
|
||||
stage: builder.top_stage,
|
||||
target: target,
|
||||
@ -1148,7 +1166,7 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
builder.ensure(tool::Rls { stage, target });
|
||||
|
||||
println!("Dist RLS stage{} ({})", stage, target);
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
|
||||
let src = build.src.join("src/tools/rls");
|
||||
let release_num = build.release_num("rls");
|
||||
@ -1162,7 +1180,7 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
|
||||
// Prepare the image directory
|
||||
let rls = build.cargo_out(compiler, Mode::Tool, target)
|
||||
.join(exe("rls", target));
|
||||
.join(exe("rls", &target));
|
||||
install(&rls, &image.join("bin"), 0o755);
|
||||
let doc = image.join("share/doc/rls");
|
||||
install(&src.join("README.md"), &doc, 0o644);
|
||||
@ -1210,14 +1228,13 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
// .dep(move |s| tool_rust_installer(build, s))
|
||||
// .run(move |s| dist::extended(build, s.stage, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Extended<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Extended {
|
||||
stage: u32,
|
||||
target: &'a str,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Extended<'a> {
|
||||
type Id = Extended<'static>;
|
||||
impl Step for Extended {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -1227,7 +1244,9 @@ impl<'a> Step<'a> for Extended<'a> {
|
||||
path.ends_with("cargo")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.extended {
|
||||
return;
|
||||
}
|
||||
@ -1242,7 +1261,7 @@ impl<'a> Step<'a> for Extended<'a> {
|
||||
let build = builder.build;
|
||||
let stage = self.stage;
|
||||
let target = self.target;
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
|
||||
println!("Dist extended stage{} ({})", stage, target);
|
||||
|
||||
@ -1583,7 +1602,7 @@ impl<'a> Step<'a> for Extended<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn add_env(build: &Build, cmd: &mut Command, target: &str) {
|
||||
fn add_env(build: &Build, cmd: &mut Command, target: Interned<String>) {
|
||||
let mut parts = channel::CFG_RELEASE_NUM.split('.');
|
||||
cmd.env("CFG_RELEASE_INFO", build.rust_version())
|
||||
.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM)
|
||||
@ -1620,11 +1639,10 @@ fn add_env(build: &Build, cmd: &mut Command, target: &str) {
|
||||
// .dep(move |s| s.name("tool-build-manifest").target(&build.build).stage(0))
|
||||
// .run(move |_| dist::hash_and_sign(build));
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct HashSign;
|
||||
|
||||
impl<'a> Step<'a> for HashSign {
|
||||
type Id = HashSign;
|
||||
impl Step for HashSign {
|
||||
type Output = ();
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -1634,7 +1652,9 @@ impl<'a> Step<'a> for HashSign {
|
||||
path.ends_with("hash-and-sign")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, _target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, _path: Option<&Path>, _host: Interned<String>, _target: Interned<String>
|
||||
) {
|
||||
builder.ensure(HashSign);
|
||||
}
|
||||
|
||||
|
@ -20,27 +20,27 @@
|
||||
use std::fs::{self, File};
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::{PathBuf, Path};
|
||||
use std::process::Command;
|
||||
|
||||
use Mode;
|
||||
use util::{cp_r, symlink_dir};
|
||||
use build_helper::up_to_date;
|
||||
|
||||
use util::{cp_r, symlink_dir};
|
||||
use builder::{Builder, Step};
|
||||
use tool::Tool;
|
||||
use compile;
|
||||
use cache::{INTERNER, Interned};
|
||||
|
||||
macro_rules! book {
|
||||
($($name:ident, $path:expr, $book_name:expr;)+) => {
|
||||
$(
|
||||
#[derive(Serialize)]
|
||||
pub struct $name<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct $name {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for $name<'a> {
|
||||
type Id = $name<'static>;
|
||||
impl Step for $name {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -48,7 +48,12 @@ macro_rules! book {
|
||||
path.ends_with($path)
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -62,7 +67,7 @@ macro_rules! book {
|
||||
fn run(self, builder: &Builder) {
|
||||
builder.ensure(Rustbook {
|
||||
target: self.target,
|
||||
name: $book_name,
|
||||
name: INTERNER.intern_str($book_name),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -93,14 +98,13 @@ book!(
|
||||
Reference, "src/doc/reference", "reference";
|
||||
);
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Rustbook<'a> {
|
||||
target: &'a str,
|
||||
name: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rustbook {
|
||||
target: Interned<String>,
|
||||
name: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rustbook<'a> {
|
||||
type Id = Rustbook<'static>;
|
||||
impl Step for Rustbook {
|
||||
type Output = ();
|
||||
|
||||
/// Invoke `rustbook` for `target` for the doc book `name`.
|
||||
@ -112,7 +116,7 @@ impl<'a> Step<'a> for Rustbook<'a> {
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
name: self.name,
|
||||
src: &src,
|
||||
src: INTERNER.intern_path(src),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -130,13 +134,12 @@ impl<'a> Step<'a> for Rustbook<'a> {
|
||||
// s.target,
|
||||
// "unstable-book",
|
||||
// &build.md_doc_out(s.target)));
|
||||
#[derive(Serialize)]
|
||||
pub struct UnstableBook<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct UnstableBook {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for UnstableBook<'a> {
|
||||
type Id = UnstableBook<'static>;
|
||||
impl Step for UnstableBook {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -144,7 +147,9 @@ impl<'a> Step<'a> for UnstableBook<'a> {
|
||||
path.ends_with("src/doc/unstable-book")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -161,21 +166,20 @@ impl<'a> Step<'a> for UnstableBook<'a> {
|
||||
});
|
||||
builder.ensure(RustbookSrc {
|
||||
target: self.target,
|
||||
name: "unstable-book",
|
||||
src: &builder.build.md_doc_out(self.target),
|
||||
name: INTERNER.intern_str("unstable-book"),
|
||||
src: builder.build.md_doc_out(self.target),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RustbookSrc<'a> {
|
||||
target: &'a str,
|
||||
name: &'a str,
|
||||
src: &'a Path,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RustbookSrc {
|
||||
target: Interned<String>,
|
||||
name: Interned<String>,
|
||||
src: Interned<PathBuf>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for RustbookSrc<'a> {
|
||||
type Id = UnstableBook<'static>;
|
||||
impl Step for RustbookSrc {
|
||||
type Output = ();
|
||||
|
||||
/// Invoke `rustbook` for `target` for the doc book `name` from the `src` path.
|
||||
@ -217,21 +221,22 @@ impl<'a> Step<'a> for RustbookSrc<'a> {
|
||||
// .default(build.config.docs)
|
||||
// .run(move |s| doc::book(build, s.target, "book"));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct TheBook<'a> {
|
||||
target: &'a str,
|
||||
name: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct TheBook {
|
||||
target: Interned<String>,
|
||||
name: &'static str,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for TheBook<'a> {
|
||||
type Id = TheBook<'static>;
|
||||
impl Step for TheBook {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with("src/doc/book")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -258,13 +263,13 @@ impl<'a> Step<'a> for TheBook<'a> {
|
||||
// build book first edition
|
||||
builder.ensure(Rustbook {
|
||||
target: target,
|
||||
name: &format!("{}/first-edition", name),
|
||||
name: INTERNER.intern_string(format!("{}/first-edition", name)),
|
||||
});
|
||||
|
||||
// build book second edition
|
||||
builder.ensure(Rustbook {
|
||||
target: target,
|
||||
name: &format!("{}/second-edition", name),
|
||||
name: INTERNER.intern_string(format!("{}/second-edition", name)),
|
||||
});
|
||||
|
||||
// build the index page
|
||||
@ -284,11 +289,11 @@ impl<'a> Step<'a> for TheBook<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn invoke_rustdoc(builder: &Builder, target: &str, markdown: &str) {
|
||||
fn invoke_rustdoc(builder: &Builder, target: Interned<String>, markdown: &str) {
|
||||
let build = builder.build;
|
||||
let out = build.doc_out(target);
|
||||
|
||||
let compiler = builder.compiler(0, &build.build);
|
||||
let compiler = builder.compiler(0, build.build);
|
||||
|
||||
let path = build.src.join("src/doc").join(markdown);
|
||||
|
||||
@ -340,13 +345,12 @@ fn invoke_rustdoc(builder: &Builder, target: &str, markdown: &str) {
|
||||
// .default(build.config.docs)
|
||||
// .run(move |s| doc::standalone(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Standalone<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Standalone {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Standalone<'a> {
|
||||
type Id = Standalone<'static>;
|
||||
impl Step for Standalone {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -354,7 +358,9 @@ impl<'a> Step<'a> for Standalone<'a> {
|
||||
path.ends_with("src/doc")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -380,7 +386,7 @@ impl<'a> Step<'a> for Standalone<'a> {
|
||||
let out = build.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
|
||||
let compiler = builder.compiler(0, &build.build);
|
||||
let compiler = builder.compiler(0, build.build);
|
||||
|
||||
let favicon = build.src.join("src/doc/favicon.inc");
|
||||
let footer = build.src.join("src/doc/footer.inc");
|
||||
@ -447,14 +453,13 @@ impl<'a> Step<'a> for Standalone<'a> {
|
||||
// .run(move |s| doc::std(build, s.stage, s.target));
|
||||
// }
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Std<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Std {
|
||||
stage: u32,
|
||||
target: &'a str,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Std<'a> {
|
||||
type Id = Std<'static>;
|
||||
impl Step for Std {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -464,7 +469,9 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
let run = || {
|
||||
builder.ensure(Std {
|
||||
stage: builder.top_stage,
|
||||
@ -496,7 +503,7 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
println!("Documenting stage{} std ({})", stage, target);
|
||||
let out = build.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
let compiler = if build.force_use_stage1(compiler, target) {
|
||||
builder.compiler(1, compiler.host)
|
||||
} else {
|
||||
@ -559,14 +566,13 @@ impl<'a> Step<'a> for Std<'a> {
|
||||
// .run(move |s| doc::test(build, s.stage, s.target));
|
||||
// }
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Test<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Test {
|
||||
stage: u32,
|
||||
target: &'a str,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Test<'a> {
|
||||
type Id = Test<'static>;
|
||||
impl Step for Test {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
@ -576,7 +582,9 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
let run = || {
|
||||
builder.ensure(Test {
|
||||
stage: builder.top_stage,
|
||||
@ -608,7 +616,7 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
println!("Documenting stage{} test ({})", stage, target);
|
||||
let out = build.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
let compiler = if build.force_use_stage1(compiler, target) {
|
||||
builder.compiler(1, compiler.host)
|
||||
} else {
|
||||
@ -647,14 +655,13 @@ impl<'a> Step<'a> for Test<'a> {
|
||||
// }
|
||||
//
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Rustc<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rustc {
|
||||
stage: u32,
|
||||
target: &'a str,
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rustc<'a> {
|
||||
type Id = Rustc<'static>;
|
||||
impl Step for Rustc {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -665,7 +672,9 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
let run = || {
|
||||
builder.ensure(Rustc {
|
||||
stage: builder.top_stage,
|
||||
@ -697,7 +706,7 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
println!("Documenting stage{} compiler ({})", stage, target);
|
||||
let out = build.doc_out(target);
|
||||
t!(fs::create_dir_all(&out));
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
let compiler = if build.force_use_stage1(compiler, target) {
|
||||
builder.compiler(1, compiler.host)
|
||||
} else {
|
||||
@ -749,13 +758,12 @@ impl<'a> Step<'a> for Rustc<'a> {
|
||||
// .host(true)
|
||||
// .run(move |s| doc::error_index(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ErrorIndex<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct ErrorIndex {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
type Id = ErrorIndex<'static>;
|
||||
impl Step for ErrorIndex {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -764,7 +772,9 @@ impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
path.ends_with("src/tools/error_index_generator")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -782,7 +792,7 @@ impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(compile::Rustc {
|
||||
compiler: builder.compiler(0, &build.build),
|
||||
compiler: builder.compiler(0, build.build),
|
||||
target,
|
||||
});
|
||||
|
||||
@ -812,13 +822,12 @@ impl<'a> Step<'a> for ErrorIndex<'a> {
|
||||
// .host(true)
|
||||
// .run(move |s| doc::unstable_book_gen(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct UnstableBookGen<'a> {
|
||||
target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct UnstableBookGen {
|
||||
target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for UnstableBookGen<'a> {
|
||||
type Id = UnstableBookGen<'static>;
|
||||
impl Step for UnstableBookGen {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -827,7 +836,9 @@ impl<'a> Step<'a> for UnstableBookGen<'a> {
|
||||
path.ends_with("src/doc/unstable-book")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>,
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.docs {
|
||||
// Not a default rule if docs are disabled.
|
||||
return;
|
||||
@ -843,7 +854,7 @@ impl<'a> Step<'a> for UnstableBookGen<'a> {
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(compile::Std {
|
||||
compiler: builder.compiler(builder.top_stage, &build.build),
|
||||
compiler: builder.compiler(builder.top_stage, build.build),
|
||||
target,
|
||||
});
|
||||
|
||||
|
@ -24,15 +24,17 @@ use Build;
|
||||
use config::Config;
|
||||
use metadata;
|
||||
|
||||
use cache::{Interned, INTERNER};
|
||||
|
||||
/// Deserialized version of all flags for this compile.
|
||||
pub struct Flags {
|
||||
pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
|
||||
pub on_fail: Option<String>,
|
||||
pub stage: Option<u32>,
|
||||
pub keep_stage: Option<u32>,
|
||||
pub build: String,
|
||||
pub host: Vec<String>,
|
||||
pub target: Vec<String>,
|
||||
pub build: Interned<String>,
|
||||
pub host: Vec<Interned<String>>,
|
||||
pub target: Vec<Interned<String>>,
|
||||
pub config: Option<PathBuf>,
|
||||
pub src: PathBuf,
|
||||
pub jobs: Option<u32>,
|
||||
@ -320,11 +322,13 @@ Arguments:
|
||||
stage: stage,
|
||||
on_fail: matches.opt_str("on-fail"),
|
||||
keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
|
||||
build: matches.opt_str("build").unwrap_or_else(|| {
|
||||
build: INTERNER.intern_string(matches.opt_str("build").unwrap_or_else(|| {
|
||||
env::var("BUILD").unwrap()
|
||||
}),
|
||||
host: split(matches.opt_strs("host")),
|
||||
target: split(matches.opt_strs("target")),
|
||||
})),
|
||||
host: split(matches.opt_strs("host"))
|
||||
.into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
|
||||
target: split(matches.opt_strs("target"))
|
||||
.into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
|
||||
config: cfg_file,
|
||||
src: src,
|
||||
jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
|
||||
|
@ -21,37 +21,44 @@ use std::process::Command;
|
||||
use dist::{self, pkgname, sanitize_sh, tmpdir};
|
||||
|
||||
use builder::{Builder, Step};
|
||||
use cache::Interned;
|
||||
|
||||
pub fn install_docs(builder: &Builder, stage: u32, host: &str) {
|
||||
pub fn install_docs(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||
install_sh(builder, "docs", "rust-docs", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_std(builder: &Builder, stage: u32) {
|
||||
for target in builder.build.config.target.iter() {
|
||||
install_sh(builder, "std", "rust-std", stage, Some(target));
|
||||
install_sh(builder, "std", "rust-std", stage, Some(*target));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_cargo(builder: &Builder, stage: u32, host: &str) {
|
||||
pub fn install_cargo(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||
install_sh(builder, "cargo", "cargo", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_rls(builder: &Builder, stage: u32, host: &str) {
|
||||
pub fn install_rls(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||
install_sh(builder, "rls", "rls", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_analysis(builder: &Builder, stage: u32, host: &str) {
|
||||
pub fn install_analysis(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||
install_sh(builder, "analysis", "rust-analysis", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_src(builder: &Builder, stage: u32) {
|
||||
install_sh(builder, "src", "rust-src", stage, None);
|
||||
}
|
||||
pub fn install_rustc(builder: &Builder, stage: u32, host: &str) {
|
||||
pub fn install_rustc(builder: &Builder, stage: u32, host: Interned<String>) {
|
||||
install_sh(builder, "rustc", "rustc", stage, Some(host));
|
||||
}
|
||||
|
||||
fn install_sh(builder: &Builder, package: &str, name: &str, stage: u32, host: Option<&str>) {
|
||||
fn install_sh(
|
||||
builder: &Builder,
|
||||
package: &str,
|
||||
name: &str,
|
||||
stage: u32,
|
||||
host: Option<Interned<String>>
|
||||
) {
|
||||
let build = builder.build;
|
||||
println!("Install {} stage{} ({:?})", package, stage, host);
|
||||
|
||||
@ -127,15 +134,15 @@ macro_rules! install {
|
||||
$default_cond:expr,
|
||||
only_hosts: $only_hosts:expr,
|
||||
$run_item:block $(, $c:ident)*;)+) => {
|
||||
$(#[derive(Serialize)]
|
||||
pub struct $name<'a> {
|
||||
$(
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct $name {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub host: &'a str,
|
||||
pub target: Interned<String>,
|
||||
pub host: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for $name<'a> {
|
||||
type Id = $name<'static>;
|
||||
impl Step for $name {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_BUILD_TARGETS: bool = true;
|
||||
@ -146,7 +153,12 @@ macro_rules! install {
|
||||
path.ends_with($path)
|
||||
}
|
||||
|
||||
fn make_run($builder: &Builder, path: Option<&Path>, host: &str, target: &str) {
|
||||
fn make_run(
|
||||
$builder: &Builder,
|
||||
path: Option<&Path>,
|
||||
host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
if path.is_none() && !($default_cond) {
|
||||
return;
|
||||
}
|
||||
|
@ -121,6 +121,8 @@
|
||||
extern crate build_helper;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate cmake;
|
||||
@ -186,16 +188,17 @@ mod job {
|
||||
|
||||
pub use config::Config;
|
||||
pub use flags::{Flags, Subcommand};
|
||||
use cache::{Interned, INTERNER};
|
||||
|
||||
/// A structure representing a Rust compiler.
|
||||
///
|
||||
/// Each compiler has a `stage` that it is associated with and a `host` that
|
||||
/// corresponds to the platform the compiler runs on. This structure is used as
|
||||
/// a parameter to many methods below.
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq, Clone, Copy, Hash, Debug)]
|
||||
pub struct Compiler<'a> {
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
|
||||
pub struct Compiler {
|
||||
stage: u32,
|
||||
host: &'a str,
|
||||
host: Interned<String>,
|
||||
}
|
||||
|
||||
/// Global configuration for the build system.
|
||||
@ -226,9 +229,9 @@ pub struct Build {
|
||||
verbosity: usize,
|
||||
|
||||
// Targets for which to build.
|
||||
build: String,
|
||||
hosts: Vec<String>,
|
||||
targets: Vec<String>,
|
||||
build: Interned<String>,
|
||||
hosts: Vec<Interned<String>>,
|
||||
targets: Vec<Interned<String>>,
|
||||
|
||||
// Stage 0 (downloaded) compiler and cargo or their local rust equivalents.
|
||||
initial_rustc: PathBuf,
|
||||
@ -240,10 +243,10 @@ pub struct Build {
|
||||
|
||||
// Runtime state filled in later on
|
||||
// target -> (cc, ar)
|
||||
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
||||
cc: HashMap<Interned<String>, (gcc::Tool, Option<PathBuf>)>,
|
||||
// host -> (cc, ar)
|
||||
cxx: HashMap<String, gcc::Tool>,
|
||||
crates: HashMap<String, Crate>,
|
||||
cxx: HashMap<Interned<String>, gcc::Tool>,
|
||||
crates: HashMap<Interned<String>, Crate>,
|
||||
is_sudo: bool,
|
||||
ci_env: CiEnv,
|
||||
delayed_failures: Cell<usize>,
|
||||
@ -251,9 +254,9 @@ pub struct Build {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Crate {
|
||||
name: String,
|
||||
name: Interned<String>,
|
||||
version: String,
|
||||
deps: Vec<String>,
|
||||
deps: Vec<Interned<String>>,
|
||||
path: PathBuf,
|
||||
doc_step: String,
|
||||
build_step: String,
|
||||
@ -265,7 +268,7 @@ struct Crate {
|
||||
///
|
||||
/// These entries currently correspond to the various output directories of the
|
||||
/// build system, with each mod generating output in a different directory.
|
||||
#[derive(Serialize, Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Mode {
|
||||
/// Build the standard library, placing output in the "stageN-std" directory.
|
||||
Libstd,
|
||||
@ -438,7 +441,7 @@ impl Build {
|
||||
/// Get the directory for incremental by-products when using the
|
||||
/// given compiler.
|
||||
fn incremental_dir(&self, compiler: Compiler) -> PathBuf {
|
||||
self.out.join(compiler.host).join(format!("stage{}-incremental", compiler.stage))
|
||||
self.out.join(&*compiler.host).join(format!("stage{}-incremental", compiler.stage))
|
||||
}
|
||||
|
||||
/// Returns the root directory for all output generated in a particular
|
||||
@ -452,7 +455,7 @@ impl Build {
|
||||
Mode::Tool => "-tools",
|
||||
Mode::Librustc => "-rustc",
|
||||
};
|
||||
self.out.join(compiler.host)
|
||||
self.out.join(&*compiler.host)
|
||||
.join(format!("stage{}{}", compiler.stage, suffix))
|
||||
}
|
||||
|
||||
@ -462,40 +465,40 @@ impl Build {
|
||||
fn cargo_out(&self,
|
||||
compiler: Compiler,
|
||||
mode: Mode,
|
||||
target: &str) -> PathBuf {
|
||||
self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
|
||||
target: Interned<String>) -> PathBuf {
|
||||
self.stage_out(compiler, mode).join(&*target).join(self.cargo_dir())
|
||||
}
|
||||
|
||||
/// Root output directory for LLVM compiled for `target`
|
||||
///
|
||||
/// Note that if LLVM is configured externally then the directory returned
|
||||
/// will likely be empty.
|
||||
fn llvm_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("llvm")
|
||||
fn llvm_out(&self, target: Interned<String>) -> PathBuf {
|
||||
self.out.join(&*target).join("llvm")
|
||||
}
|
||||
|
||||
/// Output directory for all documentation for a target
|
||||
fn doc_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("doc")
|
||||
fn doc_out(&self, target: Interned<String>) -> PathBuf {
|
||||
self.out.join(&*target).join("doc")
|
||||
}
|
||||
|
||||
/// Output directory for some generated md crate documentation for a target (temporary)
|
||||
fn md_doc_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("md-doc")
|
||||
fn md_doc_out(&self, target: Interned<String>) -> Interned<PathBuf> {
|
||||
INTERNER.intern_path(self.out.join(&*target).join("md-doc"))
|
||||
}
|
||||
|
||||
/// Output directory for all crate documentation for a target (temporary)
|
||||
///
|
||||
/// The artifacts here are then copied into `doc_out` above.
|
||||
fn crate_doc_out(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("crate-docs")
|
||||
fn crate_doc_out(&self, target: Interned<String>) -> PathBuf {
|
||||
self.out.join(&*target).join("crate-docs")
|
||||
}
|
||||
|
||||
/// Returns true if no custom `llvm-config` is set for the specified target.
|
||||
///
|
||||
/// If no custom `llvm-config` was specified then Rust's llvm will be used.
|
||||
fn is_rust_llvm(&self, target: &str) -> bool {
|
||||
match self.config.target_config.get(target) {
|
||||
fn is_rust_llvm(&self, target: Interned<String>) -> bool {
|
||||
match self.config.target_config.get(&target) {
|
||||
Some(ref c) => c.llvm_config.is_none(),
|
||||
None => true
|
||||
}
|
||||
@ -505,25 +508,25 @@ impl Build {
|
||||
///
|
||||
/// If a custom `llvm-config` was specified for target then that's returned
|
||||
/// instead.
|
||||
fn llvm_config(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
fn llvm_config(&self, target: Interned<String>) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(&target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
s.clone()
|
||||
} else {
|
||||
self.llvm_out(&self.config.build).join("bin")
|
||||
.join(exe("llvm-config", target))
|
||||
self.llvm_out(self.config.build).join("bin")
|
||||
.join(exe("llvm-config", &*target))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the path to `FileCheck` binary for the specified target
|
||||
fn llvm_filecheck(&self, target: &str) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(target);
|
||||
fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
|
||||
let target_config = self.config.target_config.get(&target);
|
||||
if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
|
||||
let llvm_bindir = output(Command::new(s).arg("--bindir"));
|
||||
Path::new(llvm_bindir.trim()).join(exe("FileCheck", target))
|
||||
Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target))
|
||||
} else {
|
||||
let base = self.llvm_out(&self.config.build).join("build");
|
||||
let exe = exe("FileCheck", target);
|
||||
let base = self.llvm_out(self.config.build).join("build");
|
||||
let exe = exe("FileCheck", &*target);
|
||||
if !self.config.ninja && self.config.build.contains("msvc") {
|
||||
base.join("Release/bin").join(exe)
|
||||
} else {
|
||||
@ -533,13 +536,13 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Directory for libraries built from C/C++ code and shared between stages.
|
||||
fn native_dir(&self, target: &str) -> PathBuf {
|
||||
self.out.join(target).join("native")
|
||||
fn native_dir(&self, target: Interned<String>) -> PathBuf {
|
||||
self.out.join(&*target).join("native")
|
||||
}
|
||||
|
||||
/// Root output directory for rust_test_helpers library compiled for
|
||||
/// `target`
|
||||
fn test_helpers_out(&self, target: &str) -> PathBuf {
|
||||
fn test_helpers_out(&self, target: Interned<String>) -> PathBuf {
|
||||
self.native_dir(target).join("rust-test-helpers")
|
||||
}
|
||||
|
||||
@ -606,16 +609,16 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Returns the path to the C compiler for the target specified.
|
||||
fn cc(&self, target: &str) -> &Path {
|
||||
self.cc[target].0.path()
|
||||
fn cc(&self, target: Interned<String>) -> &Path {
|
||||
self.cc[&target].0.path()
|
||||
}
|
||||
|
||||
/// Returns a list of flags to pass to the C compiler for the target
|
||||
/// specified.
|
||||
fn cflags(&self, target: &str) -> Vec<String> {
|
||||
fn cflags(&self, target: Interned<String>) -> Vec<String> {
|
||||
// Filter out -O and /O (the optimization flags) that we picked up from
|
||||
// gcc-rs because the build scripts will determine that for themselves.
|
||||
let mut base = self.cc[target].0.args().iter()
|
||||
let mut base = self.cc[&target].0.args().iter()
|
||||
.map(|s| s.to_string_lossy().into_owned())
|
||||
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
|
||||
.collect::<Vec<_>>();
|
||||
@ -631,20 +634,20 @@ impl Build {
|
||||
// Work around an apparently bad MinGW / GCC optimization,
|
||||
// See: http://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
|
||||
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78936
|
||||
if target == "i686-pc-windows-gnu" {
|
||||
if &*target == "i686-pc-windows-gnu" {
|
||||
base.push("-fno-omit-frame-pointer".into());
|
||||
}
|
||||
base
|
||||
}
|
||||
|
||||
/// Returns the path to the `ar` archive utility for the target specified.
|
||||
fn ar(&self, target: &str) -> Option<&Path> {
|
||||
self.cc[target].1.as_ref().map(|p| &**p)
|
||||
fn ar(&self, target: Interned<String>) -> Option<&Path> {
|
||||
self.cc[&target].1.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// Returns the path to the C++ compiler for the target specified.
|
||||
fn cxx(&self, target: &str) -> Result<&Path, String> {
|
||||
match self.cxx.get(target) {
|
||||
fn cxx(&self, target: Interned<String>) -> Result<&Path, String> {
|
||||
match self.cxx.get(&target) {
|
||||
Some(p) => Ok(p.path()),
|
||||
None => Err(format!(
|
||||
"target `{}` is not configured as a host, only as a target",
|
||||
@ -653,7 +656,7 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Returns flags to pass to the compiler to generate code for `target`.
|
||||
fn rustc_flags(&self, target: &str) -> Vec<String> {
|
||||
fn rustc_flags(&self, target: Interned<String>) -> Vec<String> {
|
||||
// New flags should be added here with great caution!
|
||||
//
|
||||
// It's quite unfortunate to **require** flags to generate code for a
|
||||
@ -670,8 +673,8 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Returns the "musl root" for this `target`, if defined
|
||||
fn musl_root(&self, target: &str) -> Option<&Path> {
|
||||
self.config.target_config.get(target)
|
||||
fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
|
||||
self.config.target_config.get(&target)
|
||||
.and_then(|t| t.musl_root.as_ref())
|
||||
.or(self.config.musl_root.as_ref())
|
||||
.map(|p| &**p)
|
||||
@ -679,7 +682,7 @@ impl Build {
|
||||
|
||||
/// Returns whether the target will be tested using the `remote-test-client`
|
||||
/// and `remote-test-server` binaries.
|
||||
fn remote_tested(&self, target: &str) -> bool {
|
||||
fn remote_tested(&self, target: Interned<String>) -> bool {
|
||||
self.qemu_rootfs(target).is_some() || target.contains("android") ||
|
||||
env::var_os("TEST_DEVICE_ADDR").is_some()
|
||||
}
|
||||
@ -689,8 +692,8 @@ impl Build {
|
||||
///
|
||||
/// If `Some` is returned then that means that tests for this target are
|
||||
/// emulated with QEMU and binaries will need to be shipped to the emulator.
|
||||
fn qemu_rootfs(&self, target: &str) -> Option<&Path> {
|
||||
self.config.target_config.get(target)
|
||||
fn qemu_rootfs(&self, target: Interned<String>) -> Option<&Path> {
|
||||
self.config.target_config.get(&target)
|
||||
.and_then(|t| t.qemu_rootfs.as_ref())
|
||||
.map(|p| &**p)
|
||||
}
|
||||
@ -718,20 +721,20 @@ impl Build {
|
||||
///
|
||||
/// When all of these conditions are met the build will lift artifacts from
|
||||
/// the previous stage forward.
|
||||
fn force_use_stage1(&self, compiler: Compiler, target: &str) -> bool {
|
||||
fn force_use_stage1(&self, compiler: Compiler, target: Interned<String>) -> bool {
|
||||
!self.config.full_bootstrap &&
|
||||
compiler.stage >= 2 &&
|
||||
self.config.host.iter().any(|h| h == target)
|
||||
self.config.host.iter().any(|h| *h == target)
|
||||
}
|
||||
|
||||
/// Returns the directory that OpenSSL artifacts are compiled into if
|
||||
/// configured to do so.
|
||||
fn openssl_dir(&self, target: &str) -> Option<PathBuf> {
|
||||
fn openssl_dir(&self, target: Interned<String>) -> Option<PathBuf> {
|
||||
// OpenSSL not used on Windows
|
||||
if target.contains("windows") {
|
||||
None
|
||||
} else if self.config.openssl_static {
|
||||
Some(self.out.join(target).join("openssl"))
|
||||
Some(self.out.join(&*target).join("openssl"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -739,7 +742,7 @@ impl Build {
|
||||
|
||||
/// Returns the directory that OpenSSL artifacts are installed into if
|
||||
/// configured as such.
|
||||
fn openssl_install_dir(&self, target: &str) -> Option<PathBuf> {
|
||||
fn openssl_install_dir(&self, target: Interned<String>) -> Option<PathBuf> {
|
||||
self.openssl_dir(target).map(|p| p.join("install"))
|
||||
}
|
||||
|
||||
@ -842,18 +845,19 @@ impl Build {
|
||||
/// Get a list of crates from a root crate.
|
||||
///
|
||||
/// Returns Vec<(crate, path to crate, is_root_crate)>
|
||||
fn crates(&self, root: &str) -> Vec<(&str, &Path)> {
|
||||
fn crates(&self, root: &str) -> Vec<(Interned<String>, &Path)> {
|
||||
let interned = INTERNER.intern_string(root.to_owned());
|
||||
let mut ret = Vec::new();
|
||||
let mut list = vec![root];
|
||||
let mut list = vec![interned];
|
||||
let mut visited = HashSet::new();
|
||||
while let Some(krate) = list.pop() {
|
||||
let krate = &self.crates[krate];
|
||||
let krate = &self.crates[&krate];
|
||||
// If we can't strip prefix, then out-of-tree path
|
||||
let path = krate.path.strip_prefix(&self.src).unwrap_or(&krate.path);
|
||||
ret.push((&*krate.name, path));
|
||||
ret.push((krate.name, path));
|
||||
for dep in &krate.deps {
|
||||
if visited.insert(dep) && dep != "build_helper" {
|
||||
list.push(dep);
|
||||
list.push(*dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -861,8 +865,8 @@ impl Build {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Compiler<'a> {
|
||||
pub fn with_stage(mut self, stage: u32) -> Compiler<'a> {
|
||||
impl<'a> Compiler {
|
||||
pub fn with_stage(mut self, stage: u32) -> Compiler {
|
||||
self.stage = stage;
|
||||
self
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use build_helper::output;
|
||||
use serde_json;
|
||||
|
||||
use {Build, Crate};
|
||||
use cache::Interned;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Output {
|
||||
@ -26,7 +27,7 @@ struct Output {
|
||||
#[derive(Deserialize)]
|
||||
struct Package {
|
||||
id: String,
|
||||
name: String,
|
||||
name: Interned<String>,
|
||||
version: String,
|
||||
source: Option<String>,
|
||||
manifest_path: String,
|
||||
@ -65,10 +66,10 @@ fn build_krate(build: &mut Build, krate: &str) {
|
||||
let mut id2name = HashMap::new();
|
||||
for package in output.packages {
|
||||
if package.source.is_none() {
|
||||
id2name.insert(package.id, package.name.clone());
|
||||
id2name.insert(package.id, package.name);
|
||||
let mut path = PathBuf::from(package.manifest_path);
|
||||
path.pop();
|
||||
build.crates.insert(package.name.clone(), Crate {
|
||||
build.crates.insert(package.name, Crate {
|
||||
build_step: format!("build-crate-{}", package.name),
|
||||
doc_step: format!("doc-crate-{}", package.name),
|
||||
test_step: format!("test-crate-{}", package.name),
|
||||
@ -93,7 +94,7 @@ fn build_krate(build: &mut Build, krate: &str) {
|
||||
Some(dep) => dep,
|
||||
None => continue,
|
||||
};
|
||||
krate.deps.push(dep.clone());
|
||||
krate.deps.push(*dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ use Build;
|
||||
use util;
|
||||
use build_helper::up_to_date;
|
||||
use builder::{Builder, Step};
|
||||
use cache::Interned;
|
||||
|
||||
// rules.build("llvm", "src/llvm")
|
||||
// .host(true)
|
||||
@ -45,13 +46,12 @@ use builder::{Builder, Step};
|
||||
// })
|
||||
// .run(move |s| native::llvm(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Llvm<'a> {
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Llvm {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Llvm<'a> {
|
||||
type Id = Llvm<'static>;
|
||||
impl Step for Llvm {
|
||||
type Output = ();
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -61,7 +61,7 @@ impl<'a> Step<'a> for Llvm<'a> {
|
||||
let target = self.target;
|
||||
// If we're using a custom LLVM bail out here, but we can only use a
|
||||
// custom LLVM for the build triple.
|
||||
if let Some(config) = build.config.target_config.get(target) {
|
||||
if let Some(config) = build.config.target_config.get(&target) {
|
||||
if let Some(ref s) = config.llvm_config {
|
||||
return check_llvm_version(build, s);
|
||||
}
|
||||
@ -117,7 +117,7 @@ impl<'a> Step<'a> for Llvm<'a> {
|
||||
|
||||
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
|
||||
|
||||
cfg.target(target)
|
||||
cfg.target(&target)
|
||||
.host(&build.build)
|
||||
.out_dir(&out_dir)
|
||||
.profile(profile)
|
||||
@ -154,11 +154,11 @@ impl<'a> Step<'a> for Llvm<'a> {
|
||||
|
||||
// http://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
if target != build.build {
|
||||
builder.ensure(Llvm { target: &build.build });
|
||||
builder.ensure(Llvm { target: build.build });
|
||||
// FIXME: if the llvm root for the build triple is overridden then we
|
||||
// should use llvm-tblgen from there, also should verify that it
|
||||
// actually exists most of the time in normal installs of LLVM.
|
||||
let host = build.llvm_out(&build.build).join("bin/llvm-tblgen");
|
||||
let host = build.llvm_out(build.build).join("bin/llvm-tblgen");
|
||||
cfg.define("CMAKE_CROSSCOMPILING", "True")
|
||||
.define("LLVM_TABLEGEN", &host);
|
||||
}
|
||||
@ -245,20 +245,24 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
|
||||
//rules.build("test-helpers", "src/rt/rust_test_helpers.c")
|
||||
// .run(move |s| native::test_helpers(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct TestHelpers<'a> {
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TestHelpers {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for TestHelpers<'a> {
|
||||
type Id = TestHelpers<'static>;
|
||||
impl Step for TestHelpers {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with("src/rt/rust_test_helpers.c")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
target: Interned<String>,
|
||||
) {
|
||||
builder.ensure(TestHelpers { target })
|
||||
}
|
||||
|
||||
@ -290,7 +294,7 @@ impl<'a> Step<'a> for TestHelpers<'a> {
|
||||
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&dst)
|
||||
.target(target)
|
||||
.target(&target)
|
||||
.host(&build.build)
|
||||
.opt_level(0)
|
||||
.debug(false)
|
||||
@ -306,13 +310,12 @@ const OPENSSL_SHA256: &'static str =
|
||||
//rules.build("openssl", "path/to/nowhere")
|
||||
// .run(move |s| native::openssl(build, s.target));
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Openssl<'a> {
|
||||
pub target: &'a str,
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Openssl {
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Openssl<'a> {
|
||||
type Id = Openssl<'static>;
|
||||
impl Step for Openssl {
|
||||
type Output = ();
|
||||
|
||||
fn should_run(_builder: &Builder, _path: &Path) -> bool {
|
||||
@ -385,7 +388,7 @@ impl<'a> Step<'a> for Openssl<'a> {
|
||||
configure.arg("no-ssl2");
|
||||
configure.arg("no-ssl3");
|
||||
|
||||
let os = match target {
|
||||
let os = match &*target {
|
||||
"aarch64-linux-android" => "linux-aarch64",
|
||||
"aarch64-unknown-linux-gnu" => "linux-aarch64",
|
||||
"arm-linux-androideabi" => "android",
|
||||
|
@ -122,14 +122,14 @@ pub fn check(build: &mut Build) {
|
||||
continue;
|
||||
}
|
||||
|
||||
cmd_finder.must_have(build.cc(target));
|
||||
if let Some(ar) = build.ar(target) {
|
||||
cmd_finder.must_have(build.cc(*target));
|
||||
if let Some(ar) = build.ar(*target) {
|
||||
cmd_finder.must_have(ar);
|
||||
}
|
||||
}
|
||||
|
||||
for host in build.config.host.iter() {
|
||||
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
|
||||
// avoid packaging the dummy liballoc_jemalloc on that platform.
|
||||
@ -139,7 +139,7 @@ pub fn check(build: &mut Build) {
|
||||
}
|
||||
|
||||
// Externally configured LLVM requires FileCheck to exist
|
||||
let filecheck = build.llvm_filecheck(&build.build);
|
||||
let filecheck = build.llvm_filecheck(build.build);
|
||||
if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
|
||||
panic!("FileCheck executable {:?} does not exist", filecheck);
|
||||
}
|
||||
@ -153,7 +153,7 @@ pub fn check(build: &mut Build) {
|
||||
|
||||
// Make sure musl-root is valid if specified
|
||||
if target.contains("musl") && !target.contains("mips") {
|
||||
match build.musl_root(target) {
|
||||
match build.musl_root(*target) {
|
||||
Some(root) => {
|
||||
if fs::metadata(root.join("lib/libc.a")).is_err() {
|
||||
panic!("couldn't find libc.a in musl dir: {}",
|
||||
|
@ -19,6 +19,7 @@ use util::{exe, add_lib_path};
|
||||
use compile::{self, libtest_stamp, libstd_stamp, librustc_stamp, Rustc};
|
||||
use native;
|
||||
use channel::GitInfo;
|
||||
use cache::Interned;
|
||||
|
||||
//// ========================================================================
|
||||
//// Build tools
|
||||
@ -44,15 +45,14 @@ use channel::GitInfo;
|
||||
// .run(move |s| compile::maybe_clean_tools(build, s.stage, s.target, Mode::Libstd));
|
||||
//
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct CleanTools<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct CleanTools {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
pub mode: Mode,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for CleanTools<'a> {
|
||||
type Id = CleanTools<'static>;
|
||||
impl Step for CleanTools {
|
||||
type Output = ();
|
||||
|
||||
/// Build a tool in `src/tools`
|
||||
@ -65,7 +65,7 @@ impl<'a> Step<'a> for CleanTools<'a> {
|
||||
let target = self.target;
|
||||
let mode = self.mode;
|
||||
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
|
||||
let stamp = match mode {
|
||||
Mode::Libstd => libstd_stamp(build, compiler, target),
|
||||
@ -78,16 +78,15 @@ impl<'a> Step<'a> for CleanTools<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ToolBuild<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct ToolBuild {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub tool: &'a str,
|
||||
pub target: Interned<String>,
|
||||
pub tool: &'static str,
|
||||
pub mode: Mode,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for ToolBuild<'a> {
|
||||
type Id = ToolBuild<'static>;
|
||||
impl Step for ToolBuild {
|
||||
type Output = PathBuf;
|
||||
|
||||
/// Build a tool in `src/tools`
|
||||
@ -100,7 +99,7 @@ impl<'a> Step<'a> for ToolBuild<'a> {
|
||||
let target = self.target;
|
||||
let tool = self.tool;
|
||||
|
||||
let compiler = builder.compiler(stage, &build.build);
|
||||
let compiler = builder.compiler(stage, build.build);
|
||||
builder.ensure(CleanTools { stage, target, mode: self.mode });
|
||||
match self.mode {
|
||||
Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
|
||||
@ -140,7 +139,7 @@ impl<'a> Step<'a> for ToolBuild<'a> {
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +158,7 @@ macro_rules! tool {
|
||||
$(Tool::$name =>
|
||||
self.ensure($name {
|
||||
stage: 0,
|
||||
target: &self.build.build,
|
||||
target: self.build.build,
|
||||
}),
|
||||
)+
|
||||
}
|
||||
@ -167,21 +166,25 @@ macro_rules! tool {
|
||||
}
|
||||
|
||||
$(
|
||||
#[derive(Serialize)]
|
||||
pub struct $name<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct $name {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for $name<'a> {
|
||||
type Id = $name<'static>;
|
||||
impl Step for $name {
|
||||
type Output = PathBuf;
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with($path)
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
target: Interned<String>
|
||||
) {
|
||||
builder.ensure($name {
|
||||
stage: builder.top_stage,
|
||||
target,
|
||||
@ -254,21 +257,25 @@ tool!(
|
||||
RustInstaller, "src/tools/rust-installer", "rust-installer", Mode::Libstd;
|
||||
);
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct RemoteTestServer<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct RemoteTestServer {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for RemoteTestServer<'a> {
|
||||
type Id = RemoteTestServer<'static>;
|
||||
impl Step for RemoteTestServer {
|
||||
type Output = PathBuf;
|
||||
|
||||
fn should_run(_builder: &Builder, path: &Path) -> bool {
|
||||
path.ends_with("src/tools/remote-test-server")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, _path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder,
|
||||
_path: Option<&Path>,
|
||||
_host: Interned<String>,
|
||||
target: Interned<String>
|
||||
) {
|
||||
builder.ensure(RemoteTestServer {
|
||||
stage: builder.top_stage,
|
||||
target,
|
||||
@ -299,14 +306,13 @@ impl<'a> Step<'a> for RemoteTestServer<'a> {
|
||||
// .host(&build.build)
|
||||
// })
|
||||
// .run(move |s| compile::tool(build, s.stage, s.target, "cargo"));
|
||||
#[derive(Serialize)]
|
||||
pub struct Cargo<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Cargo {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Cargo<'a> {
|
||||
type Id = Cargo<'static>;
|
||||
impl Step for Cargo {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -315,7 +321,9 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
path.ends_with("src/tools/cargo")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.extended {
|
||||
return;
|
||||
}
|
||||
@ -332,8 +340,8 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
// Cargo depends on procedural macros, which requires a full host
|
||||
// compiler to be available, so we need to depend on that.
|
||||
builder.ensure(Rustc {
|
||||
compiler: builder.compiler(builder.top_stage, &builder.build.build),
|
||||
target: &builder.build.build,
|
||||
compiler: builder.compiler(builder.top_stage, builder.build.build),
|
||||
target: builder.build.build,
|
||||
});
|
||||
builder.ensure(ToolBuild {
|
||||
stage: self.stage,
|
||||
@ -357,14 +365,13 @@ impl<'a> Step<'a> for Cargo<'a> {
|
||||
// })
|
||||
// .run(move |s| compile::tool(build, s.stage, s.target, "rls"));
|
||||
//
|
||||
#[derive(Serialize)]
|
||||
pub struct Rls<'a> {
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||
pub struct Rls {
|
||||
pub stage: u32,
|
||||
pub target: &'a str,
|
||||
pub target: Interned<String>,
|
||||
}
|
||||
|
||||
impl<'a> Step<'a> for Rls<'a> {
|
||||
type Id = Rls<'static>;
|
||||
impl Step for Rls {
|
||||
type Output = PathBuf;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
@ -373,7 +380,9 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
path.ends_with("src/tools/rls")
|
||||
}
|
||||
|
||||
fn make_run(builder: &Builder, path: Option<&Path>, _host: &str, target: &str) {
|
||||
fn make_run(
|
||||
builder: &Builder, path: Option<&Path>, _host: Interned<String>, target: Interned<String>
|
||||
) {
|
||||
if path.is_none() && !builder.build.config.extended {
|
||||
return;
|
||||
}
|
||||
@ -390,8 +399,8 @@ impl<'a> Step<'a> for Rls<'a> {
|
||||
// RLS depends on procedural macros, which requires a full host
|
||||
// compiler to be available, so we need to depend on that.
|
||||
builder.ensure(Rustc {
|
||||
compiler: builder.compiler(builder.top_stage, &builder.build.build),
|
||||
target: &builder.build.build,
|
||||
compiler: builder.compiler(builder.top_stage, builder.build.build),
|
||||
target: builder.build.build,
|
||||
});
|
||||
builder.ensure(ToolBuild {
|
||||
stage: self.stage,
|
||||
@ -407,7 +416,7 @@ impl<'a> Builder<'a> {
|
||||
/// `host`.
|
||||
pub fn tool_cmd(&self, tool: Tool) -> Command {
|
||||
let mut cmd = Command::new(self.tool_exe(tool));
|
||||
let compiler = self.compiler(0, &self.build.build);
|
||||
let compiler = self.compiler(0, self.build.build);
|
||||
self.prepare_tool_cmd(compiler, &mut cmd);
|
||||
cmd
|
||||
}
|
||||
@ -417,10 +426,10 @@ impl<'a> Builder<'a> {
|
||||
/// Notably this munges the dynamic library lookup path to point to the
|
||||
/// right location to run `compiler`.
|
||||
fn prepare_tool_cmd(&self, compiler: Compiler, cmd: &mut Command) {
|
||||
let host = compiler.host;
|
||||
let mut paths = vec![
|
||||
self.sysroot_libdir(compiler, compiler.host),
|
||||
self.cargo_out(compiler, Mode::Tool, host).join("deps"),
|
||||
let host = &compiler.host;
|
||||
let mut paths: Vec<PathBuf> = vec![
|
||||
PathBuf::from(&self.sysroot_libdir(compiler, compiler.host)),
|
||||
self.cargo_out(compiler, Mode::Tool, *host).join("deps"),
|
||||
];
|
||||
|
||||
// On MSVC a tool may invoke a C compiler (e.g. compiletest in run-make
|
||||
@ -429,7 +438,7 @@ impl<'a> Builder<'a> {
|
||||
if compiler.host.contains("msvc") {
|
||||
let curpaths = env::var_os("PATH").unwrap_or_default();
|
||||
let curpaths = env::split_paths(&curpaths).collect::<Vec<_>>();
|
||||
for &(ref k, ref v) in self.cc[compiler.host].0.env() {
|
||||
for &(ref k, ref v) in self.cc[&compiler.host].0.env() {
|
||||
if k != "PATH" {
|
||||
continue
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user