]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/check.rs
Rollup merge of #60187 - tmandry:generator-optimization, r=eddyb
[rust.git] / src / bootstrap / check.rs
1 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
2
3 use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
4                      add_to_sysroot};
5 use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
6 use crate::tool::{prepare_tool_cargo, SourceType};
7 use crate::{Compiler, Mode};
8 use crate::cache::{INTERNER, Interned};
9 use std::path::PathBuf;
10
11 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
12 pub struct Std {
13     pub target: Interned<String>,
14 }
15
16 fn args(kind: Kind) -> Vec<String> {
17     match kind {
18         Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
19         _ => Vec::new()
20     }
21 }
22
23 fn cargo_subcommand(kind: Kind) -> &'static str {
24     match kind {
25         Kind::Check => "check",
26         Kind::Clippy => "clippy",
27         Kind::Fix => "fix",
28         _ => unreachable!()
29     }
30 }
31
32 impl Step for Std {
33     type Output = ();
34     const DEFAULT: bool = true;
35
36     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
37         run.all_krates("std")
38     }
39
40     fn make_run(run: RunConfig<'_>) {
41         run.builder.ensure(Std {
42             target: run.target,
43         });
44     }
45
46     fn run(self, builder: &Builder<'_>) {
47         let target = self.target;
48         let compiler = builder.compiler(0, builder.config.build);
49
50         let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
51         std_cargo(builder, &compiler, target, &mut cargo);
52
53         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
54         builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
55         run_cargo(builder,
56                   &mut cargo,
57                   args(builder.kind),
58                   &libstd_stamp(builder, compiler, target),
59                   true);
60
61         let libdir = builder.sysroot_libdir(compiler, target);
62         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
63         add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
64     }
65 }
66
67 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
68 pub struct Rustc {
69     pub target: Interned<String>,
70 }
71
72 impl Step for Rustc {
73     type Output = ();
74     const ONLY_HOSTS: bool = true;
75     const DEFAULT: bool = true;
76
77     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
78         run.all_krates("rustc-main")
79     }
80
81     fn make_run(run: RunConfig<'_>) {
82         run.builder.ensure(Rustc {
83             target: run.target,
84         });
85     }
86
87     /// Builds the compiler.
88     ///
89     /// This will build the compiler for a particular stage of the build using
90     /// the `compiler` targeting the `target` architecture. The artifacts
91     /// created will also be linked into the sysroot directory.
92     fn run(self, builder: &Builder<'_>) {
93         let compiler = builder.compiler(0, builder.config.build);
94         let target = self.target;
95
96         builder.ensure(Test { target });
97
98         let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
99             cargo_subcommand(builder.kind));
100         rustc_cargo(builder, &mut cargo);
101
102         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
103         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
104         run_cargo(builder,
105                   &mut cargo,
106                   args(builder.kind),
107                   &librustc_stamp(builder, compiler, target),
108                   true);
109
110         let libdir = builder.sysroot_libdir(compiler, target);
111         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
112         add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
113     }
114 }
115
116 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
117 pub struct CodegenBackend {
118     pub target: Interned<String>,
119     pub backend: Interned<String>,
120 }
121
122 impl Step for CodegenBackend {
123     type Output = ();
124     const ONLY_HOSTS: bool = true;
125     const DEFAULT: bool = true;
126
127     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
128         run.all_krates("rustc_codegen_llvm")
129     }
130
131     fn make_run(run: RunConfig<'_>) {
132         let backend = run.builder.config.rust_codegen_backends.get(0);
133         let backend = backend.cloned().unwrap_or_else(|| {
134             INTERNER.intern_str("llvm")
135         });
136         run.builder.ensure(CodegenBackend {
137             target: run.target,
138             backend,
139         });
140     }
141
142     fn run(self, builder: &Builder<'_>) {
143         let compiler = builder.compiler(0, builder.config.build);
144         let target = self.target;
145         let backend = self.backend;
146
147         builder.ensure(Rustc { target });
148
149         let mut cargo = builder.cargo(compiler, Mode::Codegen, target,
150             cargo_subcommand(builder.kind));
151         cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
152         rustc_cargo_env(builder, &mut cargo);
153
154         // We won't build LLVM if it's not available, as it shouldn't affect `check`.
155
156         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
157         run_cargo(builder,
158                   &mut cargo,
159                   args(builder.kind),
160                   &codegen_backend_stamp(builder, compiler, target, backend),
161                   true);
162     }
163 }
164
165 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
166 pub struct Test {
167     pub target: Interned<String>,
168 }
169
170 impl Step for Test {
171     type Output = ();
172     const DEFAULT: bool = true;
173
174     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
175         run.all_krates("test")
176     }
177
178     fn make_run(run: RunConfig<'_>) {
179         run.builder.ensure(Test {
180             target: run.target,
181         });
182     }
183
184     fn run(self, builder: &Builder<'_>) {
185         let compiler = builder.compiler(0, builder.config.build);
186         let target = self.target;
187
188         builder.ensure(Std { target });
189
190         let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
191         test_cargo(builder, &compiler, target, &mut cargo);
192
193         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
194         builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
195         run_cargo(builder,
196                   &mut cargo,
197                   args(builder.kind),
198                   &libtest_stamp(builder, compiler, target),
199                   true);
200
201         let libdir = builder.sysroot_libdir(compiler, target);
202         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
203         add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
204     }
205 }
206
207 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
208 pub struct Rustdoc {
209     pub target: Interned<String>,
210 }
211
212 impl Step for Rustdoc {
213     type Output = ();
214     const ONLY_HOSTS: bool = true;
215     const DEFAULT: bool = true;
216
217     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
218         run.path("src/tools/rustdoc")
219     }
220
221     fn make_run(run: RunConfig<'_>) {
222         run.builder.ensure(Rustdoc {
223             target: run.target,
224         });
225     }
226
227     fn run(self, builder: &Builder<'_>) {
228         let compiler = builder.compiler(0, builder.config.build);
229         let target = self.target;
230
231         builder.ensure(Rustc { target });
232
233         let mut cargo = prepare_tool_cargo(builder,
234                                            compiler,
235                                            Mode::ToolRustc,
236                                            target,
237                                            cargo_subcommand(builder.kind),
238                                            "src/tools/rustdoc",
239                                            SourceType::InTree,
240                                            &[]);
241
242         let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage));
243         println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
244         run_cargo(builder,
245                   &mut cargo,
246                   args(builder.kind),
247                   &rustdoc_stamp(builder, compiler, target),
248                   true);
249
250         let libdir = builder.sysroot_libdir(compiler, target);
251         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
252         add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
253         builder.cargo(compiler, Mode::ToolRustc, target, "clean");
254     }
255 }
256
257 /// Cargo's output path for the standard library in a given stage, compiled
258 /// by a particular compiler for the specified target.
259 pub fn libstd_stamp(
260     builder: &Builder<'_>,
261     compiler: Compiler,
262     target: Interned<String>,
263 ) -> PathBuf {
264     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
265 }
266
267 /// Cargo's output path for libtest in a given stage, compiled by a particular
268 /// compiler for the specified target.
269 pub fn libtest_stamp(
270     builder: &Builder<'_>,
271     compiler: Compiler,
272     target: Interned<String>,
273 ) -> PathBuf {
274     builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
275 }
276
277 /// Cargo's output path for librustc in a given stage, compiled by a particular
278 /// compiler for the specified target.
279 pub fn librustc_stamp(
280     builder: &Builder<'_>,
281     compiler: Compiler,
282     target: Interned<String>,
283 ) -> PathBuf {
284     builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
285 }
286
287 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
288 /// compiler for the specified target and backend.
289 fn codegen_backend_stamp(builder: &Builder<'_>,
290                          compiler: Compiler,
291                          target: Interned<String>,
292                          backend: Interned<String>) -> PathBuf {
293     builder.cargo_out(compiler, Mode::Codegen, target)
294          .join(format!(".librustc_codegen_llvm-{}-check.stamp", backend))
295 }
296
297 /// Cargo's output path for rustdoc in a given stage, compiled by a particular
298 /// compiler for the specified target.
299 pub fn rustdoc_stamp(
300     builder: &Builder<'_>,
301     compiler: Compiler,
302     target: Interned<String>,
303 ) -> PathBuf {
304     builder.cargo_out(compiler, Mode::ToolRustc, target)
305         .join(".rustdoc-check.stamp")
306 }