1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std::collections::HashSet;
13 use build::{Build, Compiler};
15 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
21 macro_rules! targets {
24 (rustc, Rustc { stage: u32 }),
25 (libstd, Libstd { stage: u32, compiler: Compiler<'a> }),
26 (librustc, Librustc { stage: u32, compiler: Compiler<'a> }),
27 (llvm, Llvm { _dummy: () }),
28 (compiler_rt, CompilerRt { _dummy: () }),
33 macro_rules! item { ($a:item) => ($a) }
35 macro_rules! define_source {
36 ($(($short:ident, $name:ident { $($args:tt)* }),)*) => {
38 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
40 $($name { $($args)* }),*
46 targets!(define_source);
48 pub fn all(build: &Build) -> Vec<Step> {
49 let mut ret = Vec::new();
50 let mut all = HashSet::new();
51 for target in top_level(build) {
52 fill(build, &target, &mut ret, &mut all);
56 fn fill<'a>(build: &'a Build,
58 ret: &mut Vec<Step<'a>>,
59 set: &mut HashSet<Step<'a>>) {
60 if set.insert(target.clone()) {
61 for dep in target.deps(build) {
62 fill(build, &dep, ret, set);
64 ret.push(target.clone());
69 fn top_level(build: &Build) -> Vec<Step> {
70 let mut targets = Vec::new();
71 let stage = build.flags.stage.unwrap_or(2);
74 src: Source::Llvm { _dummy: () },
75 target: build.flags.host.iter().next()
76 .unwrap_or(&build.config.build),
79 src: Source::Llvm { _dummy: () },
80 target: build.flags.target.iter().next().map(|x| &x[..])
81 .unwrap_or(host.target)
84 add_steps(build, stage, &host, &target, &mut targets);
86 if targets.len() == 0 {
88 src: Source::Llvm { _dummy: () },
89 target: &build.config.build,
91 for host in build.config.host.iter() {
92 if !build.flags.host.contains(host) {
95 let host = t.target(host);
96 targets.push(host.librustc(stage, host.compiler(stage)));
97 for target in build.config.target.iter() {
98 if !build.flags.target.contains(target) {
101 targets.push(host.target(target)
102 .libstd(stage, host.compiler(stage)));
111 fn add_steps<'a>(build: &'a Build,
115 targets: &mut Vec<Step<'a>>) {
116 for step in build.flags.step.iter() {
117 let compiler = host.compiler(stage);
119 "libstd" => targets.push(target.libstd(stage, compiler)),
120 "librustc" => targets.push(target.librustc(stage, compiler)),
121 "rustc" => targets.push(host.rustc(stage)),
122 "llvm" => targets.push(target.llvm(())),
123 "compiler-rt" => targets.push(target.compiler_rt(())),
124 _ => panic!("unknown build target: `{}`", step),
129 macro_rules! constructors {
130 ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => {$(
131 fn $short(&self, $($arg: $t),*) -> Step<'a> {
133 src: Source::$name { $($arg: $arg),* },
141 fn compiler(&self, stage: u32) -> Compiler<'a> {
142 Compiler::new(stage, self.target)
145 fn target(&self, target: &'a str) -> Step<'a> {
146 Step { target: target, src: self.src.clone() }
149 targets!(constructors);
151 pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
153 Source::Rustc { stage: 0 } => {
154 assert!(self.target == build.config.build);
157 Source::Rustc { stage } => {
158 let compiler = Compiler::new(stage - 1, &build.config.build);
159 vec![self.librustc(stage - 1, compiler)]
161 Source::Librustc { stage, compiler } => {
162 vec![self.libstd(stage, compiler), self.llvm(())]
164 Source::Libstd { stage: _, compiler } => {
165 vec![self.compiler_rt(()),
166 self.rustc(compiler.stage).target(compiler.host)]
168 Source::CompilerRt { _dummy } => {
169 vec![self.llvm(()).target(&build.config.build)]
171 Source::Llvm { _dummy } => Vec::new(),