]> git.proxmox.com Git - rustc.git/blob - src/bootstrap/step.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / bootstrap / step.rs
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
11 //! Major workhorse of rustbuild, definition and dependencies between stages of
12 //! the copmile.
13 //!
14 //! The primary purpose of this module is to define the various `Step`s of
15 //! execution of the build. Each `Step` has a corresponding `Source` indicating
16 //! what it's actually doing along with a number of dependencies which must be
17 //! executed first.
18 //!
19 //! This module will take the CLI as input and calculate the steps required for
20 //! the build requested, ensuring that all intermediate pieces are in place.
21 //! Essentially this module is a `make`-replacement, but not as good.
22
23 use std::collections::HashSet;
24
25 use {Build, Compiler};
26
27 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
28 pub struct Step<'a> {
29 pub src: Source<'a>,
30 pub target: &'a str,
31 }
32
33 /// Macro used to iterate over all targets that are recognized by the build
34 /// system.
35 ///
36 /// Whenever a new step is added it will involve adding an entry here, updating
37 /// the dependencies section below, and then adding an implementation of the
38 /// step in `build/mod.rs`.
39 ///
40 /// This macro takes another macro as an argument and then calls that macro with
41 /// all steps that the build system knows about.
42 macro_rules! targets {
43 ($m:ident) => {
44 $m! {
45 // Step representing building the stageN compiler. This is just the
46 // compiler executable itself, not any of the support libraries
47 (rustc, Rustc { stage: u32 }),
48
49 // Steps for the two main cargo builds. These are parameterized over
50 // the compiler which is producing the artifact.
51 (libstd, Libstd { compiler: Compiler<'a> }),
52 (libtest, Libtest { compiler: Compiler<'a> }),
53 (librustc, Librustc { compiler: Compiler<'a> }),
54
55 // Links the target produced by the compiler provided into the
56 // host's directory also provided.
57 (libstd_link, LibstdLink {
58 compiler: Compiler<'a>,
59 host: &'a str
60 }),
61 (libtest_link, LibtestLink {
62 compiler: Compiler<'a>,
63 host: &'a str
64 }),
65 (librustc_link, LibrustcLink {
66 compiler: Compiler<'a>,
67 host: &'a str
68 }),
69
70 // Various tools that we can build as part of the build.
71 (tool_linkchecker, ToolLinkchecker { stage: u32 }),
72 (tool_rustbook, ToolRustbook { stage: u32 }),
73 (tool_error_index, ToolErrorIndex { stage: u32 }),
74 (tool_cargotest, ToolCargoTest { stage: u32 }),
75 (tool_tidy, ToolTidy { stage: u32 }),
76 (tool_compiletest, ToolCompiletest { stage: u32 }),
77
78 // Steps for long-running native builds. Ideally these wouldn't
79 // actually exist and would be part of build scripts, but for now
80 // these are here.
81 //
82 // There aren't really any parameters to this, but empty structs
83 // with braces are unstable so we just pick something that works.
84 (llvm, Llvm { _dummy: () }),
85 (test_helpers, TestHelpers { _dummy: () }),
86 (debugger_scripts, DebuggerScripts { stage: u32 }),
87
88 // Steps for various pieces of documentation that we can generate,
89 // the 'doc' step is just a pseudo target to depend on a bunch of
90 // others.
91 (doc, Doc { stage: u32 }),
92 (doc_book, DocBook { stage: u32 }),
93 (doc_nomicon, DocNomicon { stage: u32 }),
94 (doc_standalone, DocStandalone { stage: u32 }),
95 (doc_std, DocStd { stage: u32 }),
96 (doc_test, DocTest { stage: u32 }),
97 (doc_rustc, DocRustc { stage: u32 }),
98 (doc_error_index, DocErrorIndex { stage: u32 }),
99
100 // Steps for running tests. The 'check' target is just a pseudo
101 // target to depend on a bunch of others.
102 (check, Check { stage: u32, compiler: Compiler<'a> }),
103 (check_target, CheckTarget { stage: u32, compiler: Compiler<'a> }),
104 (check_linkcheck, CheckLinkcheck { stage: u32 }),
105 (check_cargotest, CheckCargoTest { stage: u32 }),
106 (check_tidy, CheckTidy { stage: u32 }),
107 (check_rpass, CheckRPass { compiler: Compiler<'a> }),
108 (check_rpass_full, CheckRPassFull { compiler: Compiler<'a> }),
109 (check_rpass_valgrind, CheckRPassValgrind { compiler: Compiler<'a> }),
110 (check_rfail, CheckRFail { compiler: Compiler<'a> }),
111 (check_rfail_full, CheckRFailFull { compiler: Compiler<'a> }),
112 (check_cfail, CheckCFail { compiler: Compiler<'a> }),
113 (check_cfail_full, CheckCFailFull { compiler: Compiler<'a> }),
114 (check_pfail, CheckPFail { compiler: Compiler<'a> }),
115 (check_pretty, CheckPretty { compiler: Compiler<'a> }),
116 (check_pretty_rpass, CheckPrettyRPass { compiler: Compiler<'a> }),
117 (check_pretty_rpass_full, CheckPrettyRPassFull { compiler: Compiler<'a> }),
118 (check_pretty_rfail, CheckPrettyRFail { compiler: Compiler<'a> }),
119 (check_pretty_rfail_full, CheckPrettyRFailFull { compiler: Compiler<'a> }),
120 (check_pretty_rpass_valgrind, CheckPrettyRPassValgrind { compiler: Compiler<'a> }),
121 (check_codegen, CheckCodegen { compiler: Compiler<'a> }),
122 (check_codegen_units, CheckCodegenUnits { compiler: Compiler<'a> }),
123 (check_incremental, CheckIncremental { compiler: Compiler<'a> }),
124 (check_ui, CheckUi { compiler: Compiler<'a> }),
125 (check_mir_opt, CheckMirOpt { compiler: Compiler<'a> }),
126 (check_debuginfo, CheckDebuginfo { compiler: Compiler<'a> }),
127 (check_rustdoc, CheckRustdoc { compiler: Compiler<'a> }),
128 (check_docs, CheckDocs { compiler: Compiler<'a> }),
129 (check_error_index, CheckErrorIndex { compiler: Compiler<'a> }),
130 (check_rmake, CheckRMake { compiler: Compiler<'a> }),
131 (check_crate_std, CheckCrateStd { compiler: Compiler<'a> }),
132 (check_crate_test, CheckCrateTest { compiler: Compiler<'a> }),
133 (check_crate_rustc, CheckCrateRustc { compiler: Compiler<'a> }),
134
135 // Distribution targets, creating tarballs
136 (dist, Dist { stage: u32 }),
137 (dist_docs, DistDocs { stage: u32 }),
138 (dist_mingw, DistMingw { _dummy: () }),
139 (dist_rustc, DistRustc { stage: u32 }),
140 (dist_std, DistStd { compiler: Compiler<'a> }),
141 (dist_src, DistSrc { _dummy: () }),
142
143 // Misc targets
144 (android_copy_libs, AndroidCopyLibs { compiler: Compiler<'a> }),
145 }
146 }
147 }
148
149 // Define the `Source` enum by iterating over all the steps and peeling out just
150 // the types that we want to define.
151
152 macro_rules! item { ($a:item) => ($a) }
153
154 macro_rules! define_source {
155 ($(($short:ident, $name:ident { $($args:tt)* }),)*) => {
156 item! {
157 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
158 pub enum Source<'a> {
159 $($name { $($args)* }),*
160 }
161 }
162 }
163 }
164
165 targets!(define_source);
166
167 /// Calculate a list of all steps described by `build`.
168 ///
169 /// This will inspect the flags passed in on the command line and use that to
170 /// build up a list of steps to execute. These steps will then be transformed
171 /// into a topologically sorted list which when executed left-to-right will
172 /// correctly sequence the entire build.
173 pub fn all(build: &Build) -> Vec<Step> {
174 build.verbose("inferred build steps:");
175
176 let mut ret = Vec::new();
177 let mut all = HashSet::new();
178 for target in top_level(build) {
179 fill(build, &target, &mut ret, &mut all);
180 }
181 return ret;
182
183 fn fill<'a>(build: &'a Build,
184 target: &Step<'a>,
185 ret: &mut Vec<Step<'a>>,
186 set: &mut HashSet<Step<'a>>) {
187 if set.insert(target.clone()) {
188 for dep in target.deps(build) {
189 build.verbose(&format!("{:?}\n -> {:?}", target, dep));
190 fill(build, &dep, ret, set);
191 }
192 ret.push(target.clone());
193 }
194 }
195 }
196
197 /// Determines what top-level targets are requested as part of this build,
198 /// returning them as a list.
199 fn top_level(build: &Build) -> Vec<Step> {
200 let mut targets = Vec::new();
201 let stage = build.flags.stage.unwrap_or(2);
202
203 let host = Step {
204 src: Source::Llvm { _dummy: () },
205 target: build.flags.host.iter().next()
206 .unwrap_or(&build.config.build),
207 };
208 let target = Step {
209 src: Source::Llvm { _dummy: () },
210 target: build.flags.target.iter().next().map(|x| &x[..])
211 .unwrap_or(host.target)
212 };
213
214 // First, try to find steps on the command line.
215 add_steps(build, stage, &host, &target, &mut targets);
216
217 // If none are specified, then build everything.
218 if targets.len() == 0 {
219 let t = Step {
220 src: Source::Llvm { _dummy: () },
221 target: &build.config.build,
222 };
223 if build.config.docs {
224 targets.push(t.doc(stage));
225 }
226 for host in build.config.host.iter() {
227 if !build.flags.host.contains(host) {
228 continue
229 }
230 let host = t.target(host);
231 if host.target == build.config.build {
232 targets.push(host.librustc(host.compiler(stage)));
233 } else {
234 targets.push(host.librustc_link(t.compiler(stage), host.target));
235 }
236 for target in build.config.target.iter() {
237 if !build.flags.target.contains(target) {
238 continue
239 }
240
241 if host.target == build.config.build {
242 targets.push(host.target(target)
243 .libtest(host.compiler(stage)));
244 } else {
245 targets.push(host.target(target)
246 .libtest_link(t.compiler(stage), host.target));
247 }
248 }
249 }
250 }
251
252 return targets
253
254 }
255
256 fn add_steps<'a>(build: &'a Build,
257 stage: u32,
258 host: &Step<'a>,
259 target: &Step<'a>,
260 targets: &mut Vec<Step<'a>>) {
261 struct Context<'a> {
262 stage: u32,
263 compiler: Compiler<'a>,
264 _dummy: (),
265 host: &'a str,
266 }
267 for step in build.flags.step.iter() {
268
269 // The macro below insists on hygienic access to all local variables, so
270 // we shove them all in a struct and subvert hygiene by accessing struct
271 // fields instead,
272 let cx = Context {
273 stage: stage,
274 compiler: host.target(&build.config.build).compiler(stage),
275 _dummy: (),
276 host: host.target,
277 };
278 macro_rules! add_step {
279 ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => ({$(
280 let name = stringify!($short).replace("_", "-");
281 if &step[..] == &name[..] {
282 targets.push(target.$short($(cx.$arg),*));
283 continue
284 }
285 drop(name);
286 )*})
287 }
288
289 targets!(add_step);
290
291 panic!("unknown step: {}", step);
292 }
293 }
294
295 macro_rules! constructors {
296 ($(($short:ident, $name:ident { $($arg:ident: $t:ty),* }),)*) => {$(
297 fn $short(&self, $($arg: $t),*) -> Step<'a> {
298 Step {
299 src: Source::$name { $($arg: $arg),* },
300 target: self.target,
301 }
302 }
303 )*}
304 }
305
306 impl<'a> Step<'a> {
307 fn compiler(&self, stage: u32) -> Compiler<'a> {
308 Compiler::new(stage, self.target)
309 }
310
311 fn target(&self, target: &'a str) -> Step<'a> {
312 Step { target: target, src: self.src.clone() }
313 }
314
315 // Define ergonomic constructors for each step defined above so they can be
316 // easily constructed.
317 targets!(constructors);
318
319 /// Mapping of all dependencies for rustbuild.
320 ///
321 /// This function receives a step, the build that we're building for, and
322 /// then returns a list of all the dependencies of that step.
323 pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
324 match self.src {
325 Source::Rustc { stage: 0 } => {
326 Vec::new()
327 }
328 Source::Rustc { stage } => {
329 let compiler = Compiler::new(stage - 1, &build.config.build);
330 vec![self.librustc(compiler)]
331 }
332 Source::Librustc { compiler } => {
333 vec![self.libtest(compiler), self.llvm(())]
334 }
335 Source::Libtest { compiler } => {
336 vec![self.libstd(compiler)]
337 }
338 Source::Libstd { compiler } => {
339 vec![self.rustc(compiler.stage).target(compiler.host)]
340 }
341 Source::LibrustcLink { compiler, host } => {
342 vec![self.librustc(compiler),
343 self.libtest_link(compiler, host)]
344 }
345 Source::LibtestLink { compiler, host } => {
346 vec![self.libtest(compiler), self.libstd_link(compiler, host)]
347 }
348 Source::LibstdLink { compiler, host } => {
349 vec![self.libstd(compiler),
350 self.target(host).rustc(compiler.stage)]
351 }
352 Source::Llvm { _dummy } => Vec::new(),
353 Source::TestHelpers { _dummy } => Vec::new(),
354 Source::DebuggerScripts { stage: _ } => Vec::new(),
355
356 // Note that all doc targets depend on artifacts from the build
357 // architecture, not the target (which is where we're generating
358 // docs into).
359 Source::DocStd { stage } => {
360 let compiler = self.target(&build.config.build).compiler(stage);
361 vec![self.libstd(compiler)]
362 }
363 Source::DocTest { stage } => {
364 let compiler = self.target(&build.config.build).compiler(stage);
365 vec![self.libtest(compiler)]
366 }
367 Source::DocBook { stage } |
368 Source::DocNomicon { stage } => {
369 vec![self.target(&build.config.build).tool_rustbook(stage)]
370 }
371 Source::DocErrorIndex { stage } => {
372 vec![self.target(&build.config.build).tool_error_index(stage)]
373 }
374 Source::DocStandalone { stage } => {
375 vec![self.target(&build.config.build).rustc(stage)]
376 }
377 Source::DocRustc { stage } => {
378 vec![self.doc_test(stage)]
379 }
380 Source::Doc { stage } => {
381 let mut deps = vec![
382 self.doc_book(stage), self.doc_nomicon(stage),
383 self.doc_standalone(stage), self.doc_std(stage),
384 self.doc_error_index(stage),
385 ];
386
387 if build.config.compiler_docs {
388 deps.push(self.doc_rustc(stage));
389 }
390
391 deps
392 }
393 Source::Check { stage, compiler } => {
394 // Check is just a pseudo step which means check all targets,
395 // so just depend on checking all targets.
396 build.config.target.iter().map(|t| {
397 self.target(t).check_target(stage, compiler)
398 }).collect()
399 }
400 Source::CheckTarget { stage, compiler } => {
401 // CheckTarget here means run all possible test suites for this
402 // target. Most of the time, however, we can't actually run
403 // anything if we're not the build triple as we could be cross
404 // compiling.
405 //
406 // As a result, the base set of targets here is quite stripped
407 // down from the standard set of targets. These suites have
408 // their own internal logic to run in cross-compiled situations
409 // if they'll run at all. For example compiletest knows that
410 // when testing Android targets we ship artifacts to the
411 // emulator.
412 //
413 // When in doubt the rule of thumb for adding to this list is
414 // "should this test suite run on the android bot?"
415 let mut base = vec![
416 self.check_rpass(compiler),
417 self.check_rfail(compiler),
418 self.check_crate_std(compiler),
419 self.check_crate_test(compiler),
420 self.check_debuginfo(compiler),
421 self.dist(stage),
422 ];
423
424 // If we're testing the build triple, then we know we can
425 // actually run binaries and such, so we run all possible tests
426 // that we know about.
427 if self.target == build.config.build {
428 base.extend(vec![
429 // docs-related
430 self.check_docs(compiler),
431 self.check_error_index(compiler),
432 self.check_rustdoc(compiler),
433
434 // UI-related
435 self.check_cfail(compiler),
436 self.check_pfail(compiler),
437 self.check_ui(compiler),
438
439 // codegen-related
440 self.check_incremental(compiler),
441 self.check_codegen(compiler),
442 self.check_codegen_units(compiler),
443
444 // misc compiletest-test suites
445 self.check_rpass_full(compiler),
446 self.check_rfail_full(compiler),
447 self.check_cfail_full(compiler),
448 self.check_pretty_rpass_full(compiler),
449 self.check_pretty_rfail_full(compiler),
450 self.check_rpass_valgrind(compiler),
451 self.check_rmake(compiler),
452 self.check_mir_opt(compiler),
453
454 // crates
455 self.check_crate_rustc(compiler),
456
457 // pretty
458 self.check_pretty(compiler),
459 self.check_pretty_rpass(compiler),
460 self.check_pretty_rfail(compiler),
461 self.check_pretty_rpass_valgrind(compiler),
462
463 // misc
464 self.check_linkcheck(stage),
465 self.check_tidy(stage),
466 ]);
467 }
468 return base
469 }
470 Source::CheckLinkcheck { stage } => {
471 vec![self.tool_linkchecker(stage), self.doc(stage)]
472 }
473 Source::CheckCargoTest { stage } => {
474 vec![self.tool_cargotest(stage),
475 self.librustc(self.compiler(stage))]
476 }
477 Source::CheckTidy { stage } => {
478 vec![self.tool_tidy(stage)]
479 }
480 Source::CheckMirOpt { compiler} |
481 Source::CheckPrettyRPass { compiler } |
482 Source::CheckPrettyRFail { compiler } |
483 Source::CheckRFail { compiler } |
484 Source::CheckPFail { compiler } |
485 Source::CheckCodegen { compiler } |
486 Source::CheckCodegenUnits { compiler } |
487 Source::CheckIncremental { compiler } |
488 Source::CheckUi { compiler } |
489 Source::CheckRustdoc { compiler } |
490 Source::CheckPretty { compiler } |
491 Source::CheckCFail { compiler } |
492 Source::CheckRPassValgrind { compiler } |
493 Source::CheckRPass { compiler } => {
494 let mut base = vec![
495 self.libtest(compiler),
496 self.target(compiler.host).tool_compiletest(compiler.stage),
497 self.test_helpers(()),
498 ];
499 if self.target.contains("android") {
500 base.push(self.android_copy_libs(compiler));
501 }
502 base
503 }
504 Source::CheckDebuginfo { compiler } => {
505 vec![
506 self.libtest(compiler),
507 self.target(compiler.host).tool_compiletest(compiler.stage),
508 self.test_helpers(()),
509 self.debugger_scripts(compiler.stage),
510 ]
511 }
512 Source::CheckRPassFull { compiler } |
513 Source::CheckRFailFull { compiler } |
514 Source::CheckCFailFull { compiler } |
515 Source::CheckPrettyRPassFull { compiler } |
516 Source::CheckPrettyRFailFull { compiler } |
517 Source::CheckPrettyRPassValgrind { compiler } |
518 Source::CheckRMake { compiler } => {
519 vec![self.librustc(compiler),
520 self.target(compiler.host).tool_compiletest(compiler.stage)]
521 }
522 Source::CheckDocs { compiler } => {
523 vec![self.libstd(compiler)]
524 }
525 Source::CheckErrorIndex { compiler } => {
526 vec![self.libstd(compiler),
527 self.target(compiler.host).tool_error_index(compiler.stage)]
528 }
529 Source::CheckCrateStd { compiler } => {
530 vec![self.libtest(compiler)]
531 }
532 Source::CheckCrateTest { compiler } => {
533 vec![self.libtest(compiler)]
534 }
535 Source::CheckCrateRustc { compiler } => {
536 vec![self.libtest(compiler)]
537 }
538
539 Source::ToolLinkchecker { stage } |
540 Source::ToolTidy { stage } => {
541 vec![self.libstd(self.compiler(stage))]
542 }
543 Source::ToolErrorIndex { stage } |
544 Source::ToolRustbook { stage } => {
545 vec![self.librustc(self.compiler(stage))]
546 }
547 Source::ToolCargoTest { stage } => {
548 vec![self.libstd(self.compiler(stage))]
549 }
550 Source::ToolCompiletest { stage } => {
551 vec![self.libtest(self.compiler(stage))]
552 }
553
554 Source::DistDocs { stage } => vec![self.doc(stage)],
555 Source::DistMingw { _dummy: _ } => Vec::new(),
556 Source::DistRustc { stage } => {
557 vec![self.rustc(stage)]
558 }
559 Source::DistStd { compiler } => {
560 // We want to package up as many target libraries as possible
561 // for the `rust-std` package, so if this is a host target we
562 // depend on librustc and otherwise we just depend on libtest.
563 if build.config.host.iter().any(|t| t == self.target) {
564 vec![self.librustc(compiler)]
565 } else {
566 vec![self.libtest(compiler)]
567 }
568 }
569 Source::DistSrc { _dummy: _ } => Vec::new(),
570
571 Source::Dist { stage } => {
572 let mut base = Vec::new();
573
574 for host in build.config.host.iter() {
575 let host = self.target(host);
576 base.push(host.dist_src(()));
577 base.push(host.dist_rustc(stage));
578 if host.target.contains("windows-gnu") {
579 base.push(host.dist_mingw(()));
580 }
581
582 let compiler = self.compiler(stage);
583 for target in build.config.target.iter() {
584 let target = self.target(target);
585 if build.config.docs {
586 base.push(target.dist_docs(stage));
587 }
588 base.push(target.dist_std(compiler));
589 }
590 }
591 return base
592 }
593
594 Source::AndroidCopyLibs { compiler } => {
595 vec![self.libtest(compiler)]
596 }
597 }
598 }
599 }