]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/check.rs
cadb9a7e441f24b1adcdd38f6f0407bb2767449c
[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, 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("test")
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                   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(Std { 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                   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                   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 Rustdoc {
164     pub target: Interned<String>,
165 }
166
167 impl Step for Rustdoc {
168     type Output = ();
169     const ONLY_HOSTS: bool = true;
170     const DEFAULT: bool = true;
171
172     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
173         run.path("src/tools/rustdoc")
174     }
175
176     fn make_run(run: RunConfig<'_>) {
177         run.builder.ensure(Rustdoc {
178             target: run.target,
179         });
180     }
181
182     fn run(self, builder: &Builder<'_>) {
183         let compiler = builder.compiler(0, builder.config.build);
184         let target = self.target;
185
186         builder.ensure(Rustc { target });
187
188         let cargo = prepare_tool_cargo(builder,
189                                        compiler,
190                                        Mode::ToolRustc,
191                                        target,
192                                        cargo_subcommand(builder.kind),
193                                        "src/tools/rustdoc",
194                                        SourceType::InTree,
195                                        &[]);
196
197         println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
198         run_cargo(builder,
199                   cargo,
200                   args(builder.kind),
201                   &rustdoc_stamp(builder, compiler, target),
202                   true);
203
204         let libdir = builder.sysroot_libdir(compiler, target);
205         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
206         add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
207     }
208 }
209
210 /// Cargo's output path for the standard library in a given stage, compiled
211 /// by a particular compiler for the specified target.
212 pub fn libstd_stamp(
213     builder: &Builder<'_>,
214     compiler: Compiler,
215     target: Interned<String>,
216 ) -> PathBuf {
217     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
218 }
219
220 /// Cargo's output path for librustc in a given stage, compiled by a particular
221 /// compiler for the specified target.
222 pub fn librustc_stamp(
223     builder: &Builder<'_>,
224     compiler: Compiler,
225     target: Interned<String>,
226 ) -> PathBuf {
227     builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
228 }
229
230 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
231 /// compiler for the specified target and backend.
232 fn codegen_backend_stamp(builder: &Builder<'_>,
233                          compiler: Compiler,
234                          target: Interned<String>,
235                          backend: Interned<String>) -> PathBuf {
236     builder.cargo_out(compiler, Mode::Codegen, target)
237          .join(format!(".librustc_codegen_llvm-{}-check.stamp", backend))
238 }
239
240 /// Cargo's output path for rustdoc in a given stage, compiled by a particular
241 /// compiler for the specified target.
242 pub fn rustdoc_stamp(
243     builder: &Builder<'_>,
244     compiler: Compiler,
245     target: Interned<String>,
246 ) -> PathBuf {
247     builder.cargo_out(compiler, Mode::ToolRustc, target)
248         .join(".rustdoc-check.stamp")
249 }