]> git.proxmox.com Git - rustc.git/blame - src/bootstrap/build/step.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / bootstrap / build / step.rs
CommitLineData
7453a54e
SL
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.
4//
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.
10
11use std::collections::HashSet;
12
13use build::{Build, Compiler};
14
15#[derive(Hash, Eq, PartialEq, Clone, Debug)]
16pub struct Step<'a> {
17 pub src: Source<'a>,
18 pub target: &'a str,
19}
20
21macro_rules! targets {
22 ($m:ident) => {
23 $m! {
24 // Step representing building the stageN compiler. This is just the
25 // compiler executable itself, not any of the support libraries
26 (rustc, Rustc { stage: u32 }),
27
54a0048b
SL
28 // Steps for the two main cargo builds. These are parameterized over
29 // the compiler which is producing the artifact.
30 (libstd, Libstd { compiler: Compiler<'a> }),
31 (libtest, Libtest { compiler: Compiler<'a> }),
32 (librustc, Librustc { compiler: Compiler<'a> }),
33
34 // Links the target produced by the compiler provided into the
35 // host's directory also provided.
7453a54e 36 (libstd_link, LibstdLink {
54a0048b
SL
37 compiler: Compiler<'a>,
38 host: &'a str
39 }),
40 (libtest_link, LibtestLink {
7453a54e
SL
41 compiler: Compiler<'a>,
42 host: &'a str
43 }),
44 (librustc_link, LibrustcLink {
7453a54e
SL
45 compiler: Compiler<'a>,
46 host: &'a str
47 }),
48
54a0048b
SL
49 // Various tools that we can build as part of the build.
50 (tool_linkchecker, ToolLinkchecker { stage: u32 }),
51 (tool_rustbook, ToolRustbook { stage: u32 }),
52 (tool_error_index, ToolErrorIndex { stage: u32 }),
53 (tool_cargotest, ToolCargoTest { stage: u32 }),
54
7453a54e
SL
55 // Steps for long-running native builds. Ideally these wouldn't
56 // actually exist and would be part of build scripts, but for now
57 // these are here.
58 //
59 // There aren't really any parameters to this, but empty structs
60 // with braces are unstable so we just pick something that works.
61 (llvm, Llvm { _dummy: () }),
62 (compiler_rt, CompilerRt { _dummy: () }),
54a0048b
SL
63
64 // Steps for various pieces of documentation that we can generate,
65 // the 'doc' step is just a pseudo target to depend on a bunch of
66 // others.
7453a54e
SL
67 (doc, Doc { stage: u32 }),
68 (doc_book, DocBook { stage: u32 }),
69 (doc_nomicon, DocNomicon { stage: u32 }),
70 (doc_style, DocStyle { stage: u32 }),
71 (doc_standalone, DocStandalone { stage: u32 }),
54a0048b
SL
72 (doc_std, DocStd { stage: u32 }),
73 (doc_test, DocTest { stage: u32 }),
74 (doc_rustc, DocRustc { stage: u32 }),
75 (doc_error_index, DocErrorIndex { stage: u32 }),
76
77 // Steps for running tests. The 'check' target is just a pseudo
78 // target to depend on a bunch of others.
79 (check, Check { stage: u32, compiler: Compiler<'a> }),
80 (check_linkcheck, CheckLinkcheck { stage: u32 }),
81 (check_cargotest, CheckCargoTest { stage: u32 }),
82
83 // Distribution targets, creating tarballs
84 (dist, Dist { stage: u32 }),
85 (dist_docs, DistDocs { stage: u32 }),
86 (dist_mingw, DistMingw { _dummy: () }),
87 (dist_rustc, DistRustc { stage: u32 }),
88 (dist_std, DistStd { compiler: Compiler<'a> }),
7453a54e
SL
89 }
90 }
91}
92
93macro_rules! item { ($a:item) => ($a) }
94
95macro_rules! define_source {
96 ($(($short:ident, $name:ident { $($args:tt)* }),)*) => {
97 item! {
98 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
99 pub enum Source<'a> {
100 $($name { $($args)* }),*
101 }
102 }
103 }
104}
105
106targets!(define_source);
107
108pub fn all(build: &Build) -> Vec<Step> {
109 let mut ret = Vec::new();
110 let mut all = HashSet::new();
111 for target in top_level(build) {
112 fill(build, &target, &mut ret, &mut all);
113 }
114 return ret;
115
116 fn fill<'a>(build: &'a Build,
117 target: &Step<'a>,
118 ret: &mut Vec<Step<'a>>,
119 set: &mut HashSet<Step<'a>>) {
120 if set.insert(target.clone()) {
121 for dep in target.deps(build) {
122 fill(build, &dep, ret, set);
123 }
124 ret.push(target.clone());
125 }
126 }
127}
128
129fn top_level(build: &Build) -> Vec<Step> {
130 let mut targets = Vec::new();
131 let stage = build.flags.stage.unwrap_or(2);
132
133 let host = Step {
134 src: Source::Llvm { _dummy: () },
135 target: build.flags.host.iter().next()
136 .unwrap_or(&build.config.build),
137 };
138 let target = Step {
139 src: Source::Llvm { _dummy: () },
140 target: build.flags.target.iter().next().map(|x| &x[..])
141 .unwrap_or(host.target)
142 };
143
144 add_steps(build, stage, &host, &target, &mut targets);
145
146 if targets.len() == 0 {
147 let t = Step {
148 src: Source::Llvm { _dummy: () },
149 target: &build.config.build,
150 };
151 targets.push(t.doc(stage));
152 for host in build.config.host.iter() {
153 if !build.flags.host.contains(host) {
154 continue
155 }
156 let host = t.target(host);
157 if host.target == build.config.build {
54a0048b 158 targets.push(host.librustc(host.compiler(stage)));
7453a54e 159 } else {
54a0048b 160 targets.push(host.librustc_link(t.compiler(stage), host.target));
7453a54e
SL
161 }
162 for target in build.config.target.iter() {
163 if !build.flags.target.contains(target) {
164 continue
165 }
166
167 if host.target == build.config.build {
168 targets.push(host.target(target)
54a0048b 169 .libtest(host.compiler(stage)));
7453a54e
SL
170 } else {
171 targets.push(host.target(target)
54a0048b 172 .libtest_link(t.compiler(stage), host.target));
7453a54e
SL
173 }
174 }
175 }
176 }
177
178 return targets
179
180}
181
182fn add_steps<'a>(build: &'a Build,
183 stage: u32,
184 host: &Step<'a>,
185 target: &Step<'a>,
186 targets: &mut Vec<Step<'a>>) {
54a0048b
SL
187 struct Context<'a> {
188 stage: u32,
189 compiler: Compiler<'a>,
190 _dummy: (),
191 host: &'a str,
192 }
7453a54e 193 for step in build.flags.step.iter() {
54a0048b
SL
194
195 // The macro below insists on hygienic access to all local variables, so
196 // we shove them all in a struct and subvert hygiene by accessing struct
197 // fields instead,
198 let cx = Context {
199 stage: stage,
200 compiler: host.target(&build.config.build).compiler(stage),
201 _dummy: (),
202 host: host.target,
203 };
204 macro_rules! add_step {
205 ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => ({$(
206 let name = stringify!($short).replace("_", "-");
207 if &step[..] == &name[..] {
208 targets.push(target.$short($(cx.$arg),*));
209 continue
210 }
211 drop(name);
212 )*})
7453a54e 213 }
54a0048b
SL
214
215 targets!(add_step);
216
217 panic!("unknown step: {}", step);
7453a54e
SL
218 }
219}
220
221macro_rules! constructors {
222 ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => {$(
223 fn $short(&self, $($arg: $t),*) -> Step<'a> {
224 Step {
225 src: Source::$name { $($arg: $arg),* },
226 target: self.target,
227 }
228 }
229 )*}
230}
231
232impl<'a> Step<'a> {
233 fn compiler(&self, stage: u32) -> Compiler<'a> {
234 Compiler::new(stage, self.target)
235 }
236
237 fn target(&self, target: &'a str) -> Step<'a> {
238 Step { target: target, src: self.src.clone() }
239 }
240
241 targets!(constructors);
242
243 pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
244 match self.src {
245 Source::Rustc { stage: 0 } => {
246 Vec::new()
247 }
248 Source::Rustc { stage } => {
249 let compiler = Compiler::new(stage - 1, &build.config.build);
54a0048b 250 vec![self.librustc(compiler)]
7453a54e 251 }
54a0048b
SL
252 Source::Librustc { compiler } => {
253 vec![self.libtest(compiler), self.llvm(())]
7453a54e 254 }
54a0048b
SL
255 Source::Libtest { compiler } => {
256 vec![self.libstd(compiler)]
257 }
258 Source::Libstd { compiler } => {
7453a54e
SL
259 vec![self.compiler_rt(()),
260 self.rustc(compiler.stage).target(compiler.host)]
261 }
54a0048b
SL
262 Source::LibrustcLink { compiler, host } => {
263 vec![self.librustc(compiler),
264 self.libtest_link(compiler, host)]
265 }
266 Source::LibtestLink { compiler, host } => {
267 vec![self.libtest(compiler), self.libstd_link(compiler, host)]
7453a54e 268 }
54a0048b
SL
269 Source::LibstdLink { compiler, host } => {
270 vec![self.libstd(compiler),
271 self.target(host).rustc(compiler.stage)]
7453a54e
SL
272 }
273 Source::CompilerRt { _dummy } => {
274 vec![self.llvm(()).target(&build.config.build)]
275 }
276 Source::Llvm { _dummy } => Vec::new(),
54a0048b
SL
277
278 // Note that all doc targets depend on artifacts from the build
279 // architecture, not the target (which is where we're generating
280 // docs into).
281 Source::DocStd { stage } => {
282 let compiler = self.target(&build.config.build).compiler(stage);
283 vec![self.libstd(compiler)]
284 }
285 Source::DocTest { stage } => {
286 let compiler = self.target(&build.config.build).compiler(stage);
287 vec![self.libtest(compiler)]
288 }
7453a54e
SL
289 Source::DocBook { stage } |
290 Source::DocNomicon { stage } |
54a0048b
SL
291 Source::DocStyle { stage } => {
292 vec![self.target(&build.config.build).tool_rustbook(stage)]
293 }
294 Source::DocErrorIndex { stage } => {
295 vec![self.target(&build.config.build).tool_error_index(stage)]
296 }
7453a54e 297 Source::DocStandalone { stage } => {
54a0048b
SL
298 vec![self.target(&build.config.build).rustc(stage)]
299 }
300 Source::DocRustc { stage } => {
301 vec![self.doc_test(stage)]
7453a54e
SL
302 }
303 Source::Doc { stage } => {
304 vec![self.doc_book(stage), self.doc_nomicon(stage),
54a0048b
SL
305 self.doc_style(stage), self.doc_standalone(stage),
306 self.doc_std(stage),
307 self.doc_error_index(stage)]
308 }
309 Source::Check { stage, compiler: _ } => {
310 vec![self.check_linkcheck(stage),
311 self.dist(stage)]
312 }
313 Source::CheckLinkcheck { stage } => {
314 vec![self.tool_linkchecker(stage), self.doc(stage)]
315 }
316 Source::CheckCargoTest { stage } => {
317 vec![self.tool_cargotest(stage)]
318 }
319
320 Source::ToolLinkchecker { stage } => {
321 vec![self.libstd(self.compiler(stage))]
322 }
323 Source::ToolErrorIndex { stage } |
324 Source::ToolRustbook { stage } => {
325 vec![self.librustc(self.compiler(stage))]
326 }
327 Source::ToolCargoTest { stage } => {
328 vec![self.librustc(self.compiler(stage))]
329 }
330
331 Source::DistDocs { stage } => vec![self.doc(stage)],
332 Source::DistMingw { _dummy: _ } => Vec::new(),
333 Source::DistRustc { stage } => {
334 vec![self.rustc(stage)]
335 }
336 Source::DistStd { compiler } => {
337 vec![self.libtest(compiler)]
338 }
339
340 Source::Dist { stage } => {
341 let mut base = Vec::new();
342
343 for host in build.config.host.iter() {
344 let host = self.target(host);
345 base.push(host.dist_rustc(stage));
346 if host.target.contains("windows-gnu") {
347 base.push(host.dist_mingw(()));
348 }
349
350 let compiler = self.compiler(stage);
351 for target in build.config.target.iter() {
352 let target = self.target(target);
353 base.push(target.dist_docs(stage));
354 base.push(target.dist_std(compiler));
355 }
356 }
357 return base
7453a54e
SL
358 }
359 }
360 }
361}