]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/check.rs
Deal with spaces in the rust version.
[rust.git] / src / bootstrap / check.rs
1 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
2
3 use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
4 use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, std_cargo};
5 use crate::config::TargetSelection;
6 use crate::tool::{prepare_tool_cargo, SourceType};
7 use crate::{Compiler, Mode};
8 use std::path::PathBuf;
9
10 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11 pub struct Std {
12     pub target: TargetSelection,
13 }
14
15 fn args(kind: Kind) -> Vec<String> {
16     match kind {
17         Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
18         _ => Vec::new(),
19     }
20 }
21
22 fn cargo_subcommand(kind: Kind) -> &'static str {
23     match kind {
24         Kind::Check => "check",
25         Kind::Clippy => "clippy",
26         Kind::Fix => "fix",
27         _ => unreachable!(),
28     }
29 }
30
31 impl Step for Std {
32     type Output = ();
33     const DEFAULT: bool = true;
34
35     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
36         run.all_krates("test")
37     }
38
39     fn make_run(run: RunConfig<'_>) {
40         run.builder.ensure(Std { target: run.target });
41     }
42
43     fn run(self, builder: &Builder<'_>) {
44         let target = self.target;
45         let compiler = builder.compiler(0, builder.config.build);
46
47         let mut cargo = builder.cargo(
48             compiler,
49             Mode::Std,
50             SourceType::InTree,
51             target,
52             cargo_subcommand(builder.kind),
53         );
54         std_cargo(builder, target, compiler.stage, &mut cargo);
55
56         builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
57         run_cargo(
58             builder,
59             cargo,
60             args(builder.kind),
61             &libstd_stamp(builder, compiler, target),
62             vec![],
63             true,
64         );
65
66         let libdir = builder.sysroot_libdir(compiler, target);
67         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
68         add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
69     }
70 }
71
72 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
73 pub struct Rustc {
74     pub target: TargetSelection,
75 }
76
77 impl Step for Rustc {
78     type Output = ();
79     const ONLY_HOSTS: bool = true;
80     const DEFAULT: bool = true;
81
82     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
83         run.all_krates("rustc-main")
84     }
85
86     fn make_run(run: RunConfig<'_>) {
87         run.builder.ensure(Rustc { target: run.target });
88     }
89
90     /// Builds the compiler.
91     ///
92     /// This will build the compiler for a particular stage of the build using
93     /// the `compiler` targeting the `target` architecture. The artifacts
94     /// created will also be linked into the sysroot directory.
95     fn run(self, builder: &Builder<'_>) {
96         let compiler = builder.compiler(0, builder.config.build);
97         let target = self.target;
98
99         builder.ensure(Std { target });
100
101         let mut cargo = builder.cargo(
102             compiler,
103             Mode::Rustc,
104             SourceType::InTree,
105             target,
106             cargo_subcommand(builder.kind),
107         );
108         rustc_cargo(builder, &mut cargo, target);
109
110         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
111         run_cargo(
112             builder,
113             cargo,
114             args(builder.kind),
115             &librustc_stamp(builder, compiler, target),
116             vec![],
117             true,
118         );
119
120         let libdir = builder.sysroot_libdir(compiler, target);
121         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
122         add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
123     }
124 }
125
126 macro_rules! tool_check_step {
127     ($name:ident, $path:expr, $source_type:expr) => {
128         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
129         pub struct $name {
130             pub target: TargetSelection,
131         }
132
133         impl Step for $name {
134             type Output = ();
135             const ONLY_HOSTS: bool = true;
136             const DEFAULT: bool = true;
137
138             fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
139                 run.path($path)
140             }
141
142             fn make_run(run: RunConfig<'_>) {
143                 run.builder.ensure($name { target: run.target });
144             }
145
146             fn run(self, builder: &Builder<'_>) {
147                 let compiler = builder.compiler(0, builder.config.build);
148                 let target = self.target;
149
150                 builder.ensure(Rustc { target });
151
152                 let cargo = prepare_tool_cargo(
153                     builder,
154                     compiler,
155                     Mode::ToolRustc,
156                     target,
157                     cargo_subcommand(builder.kind),
158                     $path,
159                     $source_type,
160                     &[],
161                 );
162
163                 println!(
164                     "Checking {} artifacts ({} -> {})",
165                     stringify!($name).to_lowercase(),
166                     &compiler.host.triple,
167                     target.triple
168                 );
169                 run_cargo(
170                     builder,
171                     cargo,
172                     args(builder.kind),
173                     &stamp(builder, compiler, target),
174                     vec![],
175                     true,
176                 );
177
178                 let libdir = builder.sysroot_libdir(compiler, target);
179                 let hostdir = builder.sysroot_libdir(compiler, compiler.host);
180                 add_to_sysroot(&builder, &libdir, &hostdir, &stamp(builder, compiler, target));
181
182                 /// Cargo's output path in a given stage, compiled by a particular
183                 /// compiler for the specified target.
184                 fn stamp(
185                     builder: &Builder<'_>,
186                     compiler: Compiler,
187                     target: TargetSelection,
188                 ) -> PathBuf {
189                     builder
190                         .cargo_out(compiler, Mode::ToolRustc, target)
191                         .join(format!(".{}-check.stamp", stringify!($name).to_lowercase()))
192                 }
193             }
194         }
195     };
196 }
197
198 tool_check_step!(Rustdoc, "src/tools/rustdoc", SourceType::InTree);
199 // Clippy is a hybrid. It is an external tool, but uses a git subtree instead
200 // of a submodule. Since the SourceType only drives the deny-warnings
201 // behavior, treat it as in-tree so that any new warnings in clippy will be
202 // rejected.
203 tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
204
205 /// Cargo's output path for the standard library in a given stage, compiled
206 /// by a particular compiler for the specified target.
207 fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
208     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
209 }
210
211 /// Cargo's output path for librustc in a given stage, compiled by a particular
212 /// compiler for the specified target.
213 fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
214     builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
215 }