1use crate::core::build_steps::compile::{
4 add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
5};
6use crate::core::build_steps::tool::{COMPILETEST_ALLOW_FEATURES, SourceType, prepare_tool_cargo};
7use crate::core::builder::{
8 self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, crate_description,
9};
10use crate::core::config::TargetSelection;
11use crate::utils::build_stamp::{self, BuildStamp};
12use crate::{Mode, Subcommand};
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct Std {
16 pub target: TargetSelection,
17 crates: Vec<String>,
23 override_build_kind: Option<Kind>,
30}
31
32impl Std {
33 pub fn new(target: TargetSelection) -> Self {
34 Self { target, crates: vec![], override_build_kind: None }
35 }
36
37 pub fn build_kind(mut self, kind: Option<Kind>) -> Self {
38 self.override_build_kind = kind;
39 self
40 }
41}
42
43impl Step for Std {
44 type Output = ();
45 const DEFAULT: bool = true;
46
47 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
48 run.crate_or_deps("sysroot")
49 .crate_or_deps("coretests")
50 .crate_or_deps("alloctests")
51 .path("library")
52 }
53
54 fn make_run(run: RunConfig<'_>) {
55 let crates = std_crates_for_run_make(&run);
56 run.builder.ensure(Std { target: run.target, crates, override_build_kind: None });
57 }
58
59 fn run(self, builder: &Builder<'_>) {
60 builder.require_submodule("library/stdarch", None);
61
62 let target = self.target;
63 let compiler = builder.compiler(builder.top_stage, builder.config.build);
64
65 let mut cargo = builder::Cargo::new(
66 builder,
67 compiler,
68 Mode::Std,
69 SourceType::InTree,
70 target,
71 self.override_build_kind.unwrap_or(builder.kind),
72 );
73
74 std_cargo(builder, target, compiler.stage, &mut cargo);
75 if matches!(builder.config.cmd, Subcommand::Fix) {
76 cargo.arg("--lib");
78 }
79
80 for krate in &*self.crates {
81 cargo.arg("-p").arg(krate);
82 }
83
84 let _guard = builder.msg_check(
85 format_args!("library artifacts{}", crate_description(&self.crates)),
86 target,
87 );
88
89 let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check");
90 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
91
92 if compiler.stage == 0 {
95 let libdir = builder.sysroot_target_libdir(compiler, target);
96 let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
97 add_to_sysroot(builder, &libdir, &hostdir, &stamp);
98 }
99 drop(_guard);
100
101 if builder.kind == Kind::Clippy || !self.crates.iter().any(|krate| krate == "test") {
104 return;
105 }
106
107 let mut cargo = builder::Cargo::new(
114 builder,
115 compiler,
116 Mode::Std,
117 SourceType::InTree,
118 target,
119 self.override_build_kind.unwrap_or(builder.kind),
120 );
121
122 if compiler.stage == 0 {
126 cargo.arg("--all-targets");
127 }
128
129 std_cargo(builder, target, compiler.stage, &mut cargo);
130
131 for krate in &*self.crates {
135 cargo.arg("-p").arg(krate);
136 }
137
138 let stamp = build_stamp::libstd_stamp(builder, compiler, target).with_prefix("check-test");
139 let _guard = builder.msg_check("library test/bench/example targets", target);
140 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
141 }
142}
143
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct Rustc {
146 pub target: TargetSelection,
147 crates: Vec<String>,
153 override_build_kind: Option<Kind>,
160}
161
162impl Rustc {
163 pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
164 let crates = builder
165 .in_tree_crates("rustc-main", Some(target))
166 .into_iter()
167 .map(|krate| krate.name.to_string())
168 .collect();
169 Self { target, crates, override_build_kind: None }
170 }
171
172 pub fn build_kind(mut self, build_kind: Option<Kind>) -> Self {
173 self.override_build_kind = build_kind;
174 self
175 }
176}
177
178impl Step for Rustc {
179 type Output = ();
180 const ONLY_HOSTS: bool = true;
181 const DEFAULT: bool = true;
182
183 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
184 run.crate_or_deps("rustc-main").path("compiler")
185 }
186
187 fn make_run(run: RunConfig<'_>) {
188 let crates = run.make_run_crates(Alias::Compiler);
189 run.builder.ensure(Rustc { target: run.target, crates, override_build_kind: None });
190 }
191
192 fn run(self, builder: &Builder<'_>) {
198 let compiler = builder.compiler(builder.top_stage, builder.config.build);
199 let target = self.target;
200
201 if compiler.stage != 0 {
202 builder.ensure(crate::core::build_steps::compile::Std::new(compiler, compiler.host));
208 builder.ensure(crate::core::build_steps::compile::Std::new(compiler, target));
209 } else {
210 builder.ensure(Std::new(target).build_kind(self.override_build_kind));
211 }
212
213 let mut cargo = builder::Cargo::new(
214 builder,
215 compiler,
216 Mode::Rustc,
217 SourceType::InTree,
218 target,
219 self.override_build_kind.unwrap_or(builder.kind),
220 );
221
222 rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
223
224 if builder.kind != Kind::Clippy {
227 cargo.arg("--all-targets");
228 }
229
230 for krate in &*self.crates {
234 cargo.arg("-p").arg(krate);
235 }
236
237 let _guard = builder.msg_check(
238 format_args!("compiler artifacts{}", crate_description(&self.crates)),
239 target,
240 );
241
242 let stamp = build_stamp::librustc_stamp(builder, compiler, target).with_prefix("check");
243
244 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
245
246 let libdir = builder.sysroot_target_libdir(compiler, target);
247 let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
248 add_to_sysroot(builder, &libdir, &hostdir, &stamp);
249 }
250}
251
252#[derive(Debug, Clone, PartialEq, Eq, Hash)]
253pub struct CodegenBackend {
254 pub target: TargetSelection,
255 pub backend: &'static str,
256}
257
258impl Step for CodegenBackend {
259 type Output = ();
260 const ONLY_HOSTS: bool = true;
261 const DEFAULT: bool = true;
262
263 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
264 run.paths(&["compiler/rustc_codegen_cranelift", "compiler/rustc_codegen_gcc"])
265 }
266
267 fn make_run(run: RunConfig<'_>) {
268 for &backend in &["cranelift", "gcc"] {
269 run.builder.ensure(CodegenBackend { target: run.target, backend });
270 }
271 }
272
273 fn run(self, builder: &Builder<'_>) {
274 if builder.build.config.vendor && self.backend == "gcc" {
276 println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
277 return;
278 }
279
280 let compiler = builder.compiler(builder.top_stage, builder.config.build);
281 let target = self.target;
282 let backend = self.backend;
283
284 builder.ensure(Rustc::new(target, builder));
285
286 let mut cargo = builder::Cargo::new(
287 builder,
288 compiler,
289 Mode::Codegen,
290 SourceType::InTree,
291 target,
292 builder.kind,
293 );
294
295 cargo
296 .arg("--manifest-path")
297 .arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
298 rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
299
300 let _guard = builder.msg_check(backend, target);
301
302 let stamp = build_stamp::codegen_backend_stamp(builder, compiler, target, backend)
303 .with_prefix("check");
304
305 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
306 }
307}
308
309#[derive(Debug, Clone, PartialEq, Eq, Hash)]
310pub struct RustAnalyzer {
311 pub target: TargetSelection,
312}
313
314impl Step for RustAnalyzer {
315 type Output = ();
316 const ONLY_HOSTS: bool = true;
317 const DEFAULT: bool = true;
318
319 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
320 let builder = run.builder;
321 run.path("src/tools/rust-analyzer").default_condition(
322 builder
323 .config
324 .tools
325 .as_ref()
326 .is_none_or(|tools| tools.iter().any(|tool| tool == "rust-analyzer")),
327 )
328 }
329
330 fn make_run(run: RunConfig<'_>) {
331 run.builder.ensure(RustAnalyzer { target: run.target });
332 }
333
334 fn run(self, builder: &Builder<'_>) {
335 let compiler = builder.compiler(builder.top_stage, builder.config.build);
336 let target = self.target;
337
338 builder.ensure(Rustc::new(target, builder));
339
340 let mut cargo = prepare_tool_cargo(
341 builder,
342 compiler,
343 Mode::ToolRustc,
344 target,
345 builder.kind,
346 "src/tools/rust-analyzer",
347 SourceType::InTree,
348 &["in-rust-tree".to_owned()],
349 );
350
351 cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES);
352
353 if builder.kind != Kind::Clippy {
356 cargo.arg("--bins");
358 cargo.arg("--tests");
359 cargo.arg("--benches");
360 }
361
362 let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
365 .with_prefix("rust-analyzer-check");
366
367 let _guard = builder.msg_check("rust-analyzer artifacts", target);
368 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
369 }
370}
371
372#[derive(Debug, Clone, PartialEq, Eq, Hash)]
375pub struct Compiletest {
376 pub target: TargetSelection,
377}
378
379impl Step for Compiletest {
380 type Output = ();
381 const ONLY_HOSTS: bool = true;
382 const DEFAULT: bool = false;
383
384 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
385 run.path("src/tools/compiletest")
386 }
387
388 fn make_run(run: RunConfig<'_>) {
389 run.builder.ensure(Compiletest { target: run.target });
390 }
391
392 fn run(self, builder: &Builder<'_>) {
393 let mode = if builder.config.compiletest_use_stage0_libtest {
394 Mode::ToolBootstrap
395 } else {
396 Mode::ToolStd
397 };
398
399 let compiler = builder.compiler(
400 if mode == Mode::ToolBootstrap { 0 } else { builder.top_stage },
401 builder.config.build,
402 );
403
404 if mode != Mode::ToolBootstrap {
405 builder.ensure(Rustc::new(self.target, builder));
406 }
407
408 let mut cargo = prepare_tool_cargo(
409 builder,
410 compiler,
411 mode,
412 self.target,
413 builder.kind,
414 "src/tools/compiletest",
415 SourceType::InTree,
416 &[],
417 );
418
419 cargo.allow_features(COMPILETEST_ALLOW_FEATURES);
420
421 if builder.kind != Kind::Clippy {
424 cargo.arg("--all-targets");
425 }
426
427 let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, self.target))
428 .with_prefix("compiletest-check");
429
430 let _guard = builder.msg_check("compiletest artifacts", self.target);
431 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
432 }
433}
434
435macro_rules! tool_check_step {
436 (
437 $name:ident {
438 path: $path:literal
440 $(, alt_path: $alt_path:literal )*
441 $(, default: $default:literal )?
442 $( , )?
443 }
444 ) => {
445 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
446 pub struct $name {
447 pub target: TargetSelection,
448 }
449
450 impl Step for $name {
451 type Output = ();
452 const ONLY_HOSTS: bool = true;
453 const DEFAULT: bool = true $( && $default )?;
455
456 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
457 run.paths(&[ $path, $( $alt_path ),* ])
458 }
459
460 fn make_run(run: RunConfig<'_>) {
461 run.builder.ensure($name { target: run.target });
462 }
463
464 fn run(self, builder: &Builder<'_>) {
465 let Self { target } = self;
466 run_tool_check_step(builder, target, stringify!($name), $path);
467 }
468 }
469 }
470}
471
472fn run_tool_check_step(
474 builder: &Builder<'_>,
475 target: TargetSelection,
476 step_type_name: &str,
477 path: &str,
478) {
479 let display_name = path.rsplit('/').next().unwrap();
480 let compiler = builder.compiler(builder.top_stage, builder.config.build);
481
482 builder.ensure(Rustc::new(target, builder));
483
484 let mut cargo = prepare_tool_cargo(
485 builder,
486 compiler,
487 Mode::ToolRustc,
488 target,
489 builder.kind,
490 path,
491 SourceType::InTree,
496 &[],
497 );
498
499 if builder.kind != Kind::Clippy {
502 cargo.arg("--all-targets");
503 }
504
505 let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
506 .with_prefix(&format!("{}-check", step_type_name.to_lowercase()));
507
508 let _guard = builder.msg_check(format!("{display_name} artifacts"), target);
509 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
510}
511
512tool_check_step!(Rustdoc { path: "src/tools/rustdoc", alt_path: "src/librustdoc" });
513tool_check_step!(Clippy { path: "src/tools/clippy" });
518tool_check_step!(Miri { path: "src/tools/miri" });
519tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri" });
520tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
521tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
522tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
523tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump" });
524
525tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });
526
527tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", default: false });
530
531#[derive(Debug, Clone, PartialEq, Eq, Hash)]
541pub(crate) struct CoverageDump;
542
543impl CoverageDump {
544 const PATH: &str = "src/tools/coverage-dump";
545}
546
547impl Step for CoverageDump {
548 type Output = ();
549
550 const DEFAULT: bool = false;
553 const ONLY_HOSTS: bool = true;
554
555 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
556 run.path(Self::PATH)
557 }
558
559 fn make_run(run: RunConfig<'_>) {
560 run.builder.ensure(Self {});
561 }
562
563 fn run(self, builder: &Builder<'_>) -> Self::Output {
564 let Self {} = self;
566 let display_name = "coverage-dump";
567 let host = builder.config.build;
568 let target = host;
569 let mode = Mode::ToolBootstrap;
570
571 let compiler = builder.compiler(0, host);
572 let cargo = prepare_tool_cargo(
573 builder,
574 compiler,
575 mode,
576 target,
577 builder.kind,
578 Self::PATH,
579 SourceType::InTree,
580 &[],
581 );
582
583 let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target))
584 .with_prefix(&format!("{display_name}-check"));
585
586 let _guard = builder.msg_tool(
587 builder.kind,
588 mode,
589 display_name,
590 compiler.stage,
591 &compiler.host,
592 &target,
593 );
594 run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
595 }
596}