]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/check.rs
Auto merge of #76331 - Aaron1011:fix/group-compat-hack-test, r=petrochenkov
[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         // Then run cargo again, once we've put the rmeta files for the library
71         // crates into the sysroot. This is needed because e.g., core's tests
72         // depend on `libtest` -- Cargo presumes it will exist, but it doesn't
73         // since we initialize with an empty sysroot.
74         //
75         // Currently only the "libtest" tree of crates does this.
76
77         let mut cargo = builder.cargo(
78             compiler,
79             Mode::Std,
80             SourceType::InTree,
81             target,
82             cargo_subcommand(builder.kind),
83         );
84         std_cargo(builder, target, compiler.stage, &mut cargo);
85         cargo.arg("--all-targets");
86
87         // Explicitly pass -p for all dependencies krates -- this will force cargo
88         // to also check the tests/benches/examples for these crates, rather
89         // than just the leaf crate.
90         for krate in builder.in_tree_crates("test") {
91             cargo.arg("-p").arg(krate.name);
92         }
93
94         builder.info(&format!(
95             "Checking std test/bench/example targets ({} -> {})",
96             &compiler.host, target
97         ));
98         run_cargo(
99             builder,
100             cargo,
101             args(builder.kind),
102             &libstd_test_stamp(builder, compiler, target),
103             vec![],
104             true,
105         );
106     }
107 }
108
109 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
110 pub struct Rustc {
111     pub target: TargetSelection,
112 }
113
114 impl Step for Rustc {
115     type Output = ();
116     const ONLY_HOSTS: bool = true;
117     const DEFAULT: bool = true;
118
119     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
120         run.all_krates("rustc-main")
121     }
122
123     fn make_run(run: RunConfig<'_>) {
124         run.builder.ensure(Rustc { target: run.target });
125     }
126
127     /// Builds the compiler.
128     ///
129     /// This will build the compiler for a particular stage of the build using
130     /// the `compiler` targeting the `target` architecture. The artifacts
131     /// created will also be linked into the sysroot directory.
132     fn run(self, builder: &Builder<'_>) {
133         let compiler = builder.compiler(0, builder.config.build);
134         let target = self.target;
135
136         builder.ensure(Std { target });
137
138         let mut cargo = builder.cargo(
139             compiler,
140             Mode::Rustc,
141             SourceType::InTree,
142             target,
143             cargo_subcommand(builder.kind),
144         );
145         rustc_cargo(builder, &mut cargo, target);
146         cargo.arg("--all-targets");
147
148         // Explicitly pass -p for all compiler krates -- this will force cargo
149         // to also check the tests/benches/examples for these crates, rather
150         // than just the leaf crate.
151         for krate in builder.in_tree_crates("rustc-main") {
152             cargo.arg("-p").arg(krate.name);
153         }
154
155         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
156         run_cargo(
157             builder,
158             cargo,
159             args(builder.kind),
160             &librustc_stamp(builder, compiler, target),
161             vec![],
162             true,
163         );
164
165         let libdir = builder.sysroot_libdir(compiler, target);
166         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
167         add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target));
168     }
169 }
170
171 macro_rules! tool_check_step {
172     ($name:ident, $path:expr, $source_type:expr) => {
173         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
174         pub struct $name {
175             pub target: TargetSelection,
176         }
177
178         impl Step for $name {
179             type Output = ();
180             const ONLY_HOSTS: bool = true;
181             const DEFAULT: bool = true;
182
183             fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
184                 run.path($path)
185             }
186
187             fn make_run(run: RunConfig<'_>) {
188                 run.builder.ensure($name { target: run.target });
189             }
190
191             fn run(self, builder: &Builder<'_>) {
192                 let compiler = builder.compiler(0, builder.config.build);
193                 let target = self.target;
194
195                 builder.ensure(Rustc { target });
196
197                 let mut cargo = prepare_tool_cargo(
198                     builder,
199                     compiler,
200                     Mode::ToolRustc,
201                     target,
202                     cargo_subcommand(builder.kind),
203                     $path,
204                     $source_type,
205                     &[],
206                 );
207
208                 cargo.arg("--all-targets");
209
210                 builder.info(&format!(
211                     "Checking {} artifacts ({} -> {})",
212                     stringify!($name).to_lowercase(),
213                     &compiler.host.triple,
214                     target.triple
215                 ));
216                 run_cargo(
217                     builder,
218                     cargo,
219                     args(builder.kind),
220                     &stamp(builder, compiler, target),
221                     vec![],
222                     true,
223                 );
224
225                 let libdir = builder.sysroot_libdir(compiler, target);
226                 let hostdir = builder.sysroot_libdir(compiler, compiler.host);
227                 add_to_sysroot(&builder, &libdir, &hostdir, &stamp(builder, compiler, target));
228
229                 /// Cargo's output path in a given stage, compiled by a particular
230                 /// compiler for the specified target.
231                 fn stamp(
232                     builder: &Builder<'_>,
233                     compiler: Compiler,
234                     target: TargetSelection,
235                 ) -> PathBuf {
236                     builder
237                         .cargo_out(compiler, Mode::ToolRustc, target)
238                         .join(format!(".{}-check.stamp", stringify!($name).to_lowercase()))
239                 }
240             }
241         }
242     };
243 }
244
245 tool_check_step!(Rustdoc, "src/tools/rustdoc", SourceType::InTree);
246 // Clippy is a hybrid. It is an external tool, but uses a git subtree instead
247 // of a submodule. Since the SourceType only drives the deny-warnings
248 // behavior, treat it as in-tree so that any new warnings in clippy will be
249 // rejected.
250 tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);
251
252 tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree);
253
254 /// Cargo's output path for the standard library in a given stage, compiled
255 /// by a particular compiler for the specified target.
256 fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
257     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
258 }
259
260 /// Cargo's output path for the standard library in a given stage, compiled
261 /// by a particular compiler for the specified target.
262 fn libstd_test_stamp(
263     builder: &Builder<'_>,
264     compiler: Compiler,
265     target: TargetSelection,
266 ) -> PathBuf {
267     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check-test.stamp")
268 }
269
270 /// Cargo's output path for librustc in a given stage, compiled by a particular
271 /// compiler for the specified target.
272 fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
273     builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
274 }