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