1use std::fs;
4use std::path::{Path, PathBuf};
5
6use crate::core::build_steps::compile::{
7 ArtifactKeepMode, add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo,
8 std_crates_for_make_run,
9};
10use crate::core::build_steps::tool;
11use crate::core::build_steps::tool::{
12 SourceType, TEST_FLOAT_PARSE_ALLOW_FEATURES, ToolTargetBuildMode, get_tool_target_compiler,
13 prepare_tool_cargo,
14};
15use crate::core::builder::{
16 self, Alias, Builder, Cargo, CommandLineStep, Kind, RunConfig, ShouldRun, Step, StepMetadata,
17 crate_description,
18};
19use crate::core::config::{Subcommand, TargetSelection};
20use crate::utils::build_stamp::{self, BuildStamp};
21use crate::utils::helpers::t;
22use crate::{CodegenBackendKind, Compiler, Mode};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
27enum CheckKind {
28 Check,
29 Fix,
30}
31
32impl CheckKind {
33 fn to_kind(self) -> Kind {
34 match self {
35 CheckKind::Check => Kind::Check,
36 CheckKind::Fix => Kind::Fix,
37 }
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42pub struct Std {
43 pub build_compiler: Compiler,
45 pub target: TargetSelection,
46 crates: Vec<String>,
52}
53
54impl Std {
55 const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"];
56}
57
58impl CommandLineStep for Std {
59 type Output = BuildStamp;
60
61 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
62 let mut run = run;
63 for c in Std::CRATE_OR_DEPS {
64 run = run.crate_or_deps(c);
65 }
66
67 run.path("library")
68 }
69
70 fn is_default_step(_builder: &Builder<'_>) -> bool {
71 true
72 }
73
74 fn make_run(run: RunConfig<'_>) {
75 if !run.builder.download_rustc() && run.builder.config.skip_std_check_if_no_download_rustc {
76 eprintln!(
77 "WARNING: `--skip-std-check-if-no-download-rustc` flag was passed and `rust.download-rustc` is not available. Skipping."
78 );
79 return;
80 }
81
82 if run.builder.config.compile_time_deps {
83 return;
85 }
86
87 let crates = std_crates_for_make_run(&run);
91 run.builder.ensure(Std {
92 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Std)
93 .build_compiler(),
94 target: run.target,
95 crates,
96 });
97 }
98
99 fn run(self, builder: &Builder<'_>) -> Self::Output {
100 let build_compiler = self.build_compiler;
101 let target = self.target;
102
103 let mut cargo = builder::Cargo::new(
104 builder,
105 build_compiler,
106 Mode::Std,
107 SourceType::InTree,
108 target,
109 builder.kind,
110 );
111
112 std_cargo(builder, target, &mut cargo, &self.crates);
113 if matches!(builder.config.cmd, Subcommand::Fix) {
114 cargo.arg("--lib");
116 }
117
118 let _guard = builder.msg(
119 builder.kind,
120 format_args!("library artifacts{}", crate_description(&self.crates)),
121 Mode::Std,
122 build_compiler,
123 target,
124 );
125
126 let check_stamp =
127 build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check");
128 run_cargo(
129 builder,
130 cargo,
131 builder.config.free_args.clone(),
132 &check_stamp,
133 vec![],
134 ArtifactKeepMode::OnlyRmeta,
135 );
136
137 drop(_guard);
138
139 if !self.crates.iter().any(|krate| krate == "test") {
141 return check_stamp;
142 }
143
144 let mut cargo = builder::Cargo::new(
151 builder,
152 build_compiler,
153 Mode::Std,
154 SourceType::InTree,
155 target,
156 Kind::Check,
157 );
158
159 std_cargo(builder, target, &mut cargo, &self.crates);
160
161 let stamp =
162 build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check-test");
163 let _guard = builder.msg(
164 Kind::Check,
165 "library test/bench/example targets",
166 Mode::Std,
167 build_compiler,
168 target,
169 );
170 run_cargo(
171 builder,
172 cargo,
173 builder.config.free_args.clone(),
174 &stamp,
175 vec![],
176 ArtifactKeepMode::OnlyRmeta,
177 );
178 check_stamp
179 }
180
181 fn metadata(&self) -> Option<StepMetadata> {
182 Some(StepMetadata::check("std", self.target).built_by(self.build_compiler))
183 }
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Hash)]
190struct RmetaSysroot {
191 host_dir: PathBuf,
192 target_dir: PathBuf,
193}
194
195impl RmetaSysroot {
196 fn from_stamp(
198 builder: &Builder<'_>,
199 stamp: BuildStamp,
200 target: TargetSelection,
201 directory: &Path,
202 ) -> Self {
203 let host_dir = directory.join("host");
204 let target_dir = directory.join(target);
205 let _ = fs::remove_dir_all(directory);
206 t!(fs::create_dir_all(directory));
207 add_to_sysroot(builder, &target_dir, &host_dir, &stamp);
208
209 Self { host_dir, target_dir }
210 }
211
212 fn configure_cargo(&self, cargo: &mut Cargo) {
215 cargo.append_to_env(
216 "RUSTC_ADDITIONAL_SYSROOT_PATHS",
217 format!("{},{}", self.host_dir.to_str().unwrap(), self.target_dir.to_str().unwrap()),
218 ",",
219 );
220 }
221}
222
223#[derive(Debug, Clone, PartialEq, Eq, Hash)]
230struct PrepareRustcRmetaSysroot {
231 build_compiler: CompilerForCheck,
232 target: TargetSelection,
233}
234
235impl PrepareRustcRmetaSysroot {
236 fn new(build_compiler: CompilerForCheck, target: TargetSelection) -> Self {
237 Self { build_compiler, target }
238 }
239}
240
241impl Step for PrepareRustcRmetaSysroot {
242 type Output = RmetaSysroot;
243
244 fn run(self, builder: &Builder<'_>) -> Self::Output {
245 let stamp = Rustc::check_rustc_for_preparing_sysroot(builder, &self);
247
248 let build_compiler = self.build_compiler.build_compiler();
249
250 let dir = builder
252 .out
253 .join(build_compiler.host)
254 .join(format!("stage{}-rustc-rmeta-artifacts", build_compiler.stage + 1));
255 RmetaSysroot::from_stamp(builder, stamp, self.target, &dir)
256 }
257}
258
259#[derive(Debug, Clone, PartialEq, Eq, Hash)]
266struct PrepareStdRmetaSysroot {
267 build_compiler: Compiler,
268 target: TargetSelection,
269}
270
271impl PrepareStdRmetaSysroot {
272 fn new(build_compiler: Compiler, target: TargetSelection) -> Self {
273 Self { build_compiler, target }
274 }
275}
276
277impl Step for PrepareStdRmetaSysroot {
278 type Output = RmetaSysroot;
279
280 fn run(self, builder: &Builder<'_>) -> Self::Output {
281 let stamp = builder.ensure(Std {
283 build_compiler: self.build_compiler,
284 target: self.target,
285 crates: vec![],
286 });
287
288 let dir = builder
290 .out
291 .join(self.build_compiler.host)
292 .join(format!("stage{}-std-rmeta-artifacts", self.build_compiler.stage));
293
294 RmetaSysroot::from_stamp(builder, stamp, self.target, &dir)
295 }
296}
297
298#[derive(Debug, Clone, PartialEq, Eq, Hash)]
300pub struct Rustc {
301 check_kind: CheckKind,
302
303 build_compiler: CompilerForCheck,
305 target: TargetSelection,
306
307 crates: Vec<String>,
313}
314
315impl Rustc {
316 fn check_rustc_for_preparing_sysroot(
317 builder: &Builder<'_>,
318 prepare: &PrepareRustcRmetaSysroot,
319 ) -> BuildStamp {
320 builder.ensure(Rustc {
321 check_kind: CheckKind::Check,
323 build_compiler: prepare.build_compiler.clone(),
324 target: prepare.target,
325 crates: vec![],
326 })
327 }
328}
329
330impl CommandLineStep for Rustc {
331 type Output = BuildStamp;
332 const IS_HOST: bool = true;
333
334 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
335 run.crate_or_deps("rustc-main").path("compiler")
336 }
337
338 fn is_default_step(_builder: &Builder<'_>) -> bool {
339 true
340 }
341
342 fn make_run(run: RunConfig<'_>) {
343 let check_kind = match run.builder.kind {
344 Kind::Check => CheckKind::Check,
345 Kind::Fix => CheckKind::Fix,
346 kind => panic!("unexpected kind for `check::Rustc`: {kind:?}"),
347 };
348
349 let target = run.target;
350 let build_compiler = prepare_compiler_for_check(run.builder, target, Mode::Rustc);
351 let crates = run.make_run_crates(Alias::Compiler);
352
353 run.builder.ensure(Rustc { check_kind, build_compiler, target, crates });
354 }
355
356 fn run(self, builder: &Builder<'_>) -> Self::Output {
364 let build_compiler = self.build_compiler.build_compiler;
365 let target = self.target;
366
367 let mut cargo = builder::Cargo::new(
368 builder,
369 build_compiler,
370 Mode::Rustc,
371 SourceType::InTree,
372 target,
373 self.check_kind.to_kind(),
374 );
375
376 rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates);
377 self.build_compiler.configure_cargo(&mut cargo);
378
379 for krate in &*self.crates {
383 cargo.arg("-p").arg(krate);
384 }
385
386 let _guard = builder.msg(
387 self.check_kind.to_kind(),
388 format_args!("compiler artifacts{}", crate_description(&self.crates)),
389 Mode::Rustc,
390 self.build_compiler.build_compiler(),
391 target,
392 );
393
394 let stamp =
395 build_stamp::librustc_stamp(builder, build_compiler, target).with_prefix("check");
396
397 run_cargo(
398 builder,
399 cargo,
400 builder.config.free_args.clone(),
401 &stamp,
402 vec![],
403 ArtifactKeepMode::OnlyRmeta,
404 );
405
406 stamp
407 }
408
409 fn metadata(&self) -> Option<StepMetadata> {
410 let mut metadata = StepMetadata::new("rustc", self.target, self.check_kind.to_kind())
411 .built_by(self.build_compiler.build_compiler());
412 if !self.crates.is_empty() {
413 metadata = metadata.with_metadata(format!("({} crates)", self.crates.len()));
414 }
415 Some(metadata)
416 }
417}
418
419#[derive(Debug, Clone, PartialEq, Eq, Hash)]
428pub struct CompilerForCheck {
429 build_compiler: Compiler,
430 rustc_rmeta_sysroot: Option<RmetaSysroot>,
431 std_rmeta_sysroot: Option<RmetaSysroot>,
432}
433
434impl CompilerForCheck {
435 pub fn build_compiler(&self) -> Compiler {
436 self.build_compiler
437 }
438
439 pub fn configure_cargo(&self, cargo: &mut Cargo) {
442 if let Some(sysroot) = &self.rustc_rmeta_sysroot {
443 sysroot.configure_cargo(cargo);
444 }
445 if let Some(sysroot) = &self.std_rmeta_sysroot {
446 sysroot.configure_cargo(cargo);
447 }
448 }
449}
450
451fn prepare_std(
454 builder: &Builder<'_>,
455 build_compiler: Compiler,
456 target: TargetSelection,
457) -> Option<RmetaSysroot> {
458 builder.std(build_compiler, builder.host_target);
461
462 if builder.host_target != target {
466 Some(builder.ensure(PrepareStdRmetaSysroot::new(build_compiler, target)))
467 } else {
468 None
469 }
470}
471
472pub fn prepare_compiler_for_check(
474 builder: &Builder<'_>,
475 target: TargetSelection,
476 mode: Mode,
477) -> CompilerForCheck {
478 let host = builder.host_target;
479
480 let mut rustc_rmeta_sysroot = None;
481 let mut std_rmeta_sysroot = None;
482 let build_compiler = match mode {
483 Mode::ToolBootstrap => builder.compiler(0, host),
484 Mode::ToolTarget => get_tool_target_compiler(builder, ToolTargetBuildMode::Build(target)),
488 Mode::ToolStd => {
489 if builder.config.compile_time_deps {
490 builder.compiler(0, host)
494 } else {
495 let build_compiler = builder.compiler(builder.top_stage, host);
497 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
498 build_compiler
499 }
500 }
501 Mode::ToolRustcPrivate | Mode::Codegen => {
502 let compiler_for_rustc = prepare_compiler_for_check(builder, target, Mode::Rustc);
507 rustc_rmeta_sysroot = Some(
508 builder.ensure(PrepareRustcRmetaSysroot::new(compiler_for_rustc.clone(), target)),
509 );
510 let build_compiler = compiler_for_rustc.build_compiler();
511
512 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
514 build_compiler
515 }
516 Mode::Rustc => {
517 let stage = if host == target { builder.top_stage - 1 } else { builder.top_stage };
525 let build_compiler = builder.compiler(stage, host);
526
527 std_rmeta_sysroot = prepare_std(builder, build_compiler, target);
529 build_compiler
530 }
531 Mode::Std => {
532 builder.compiler(builder.top_stage, host)
536 }
537 };
538 CompilerForCheck { build_compiler, rustc_rmeta_sysroot, std_rmeta_sysroot }
539}
540
541#[derive(Debug, Clone, PartialEq, Eq, Hash)]
543pub struct CraneliftCodegenBackend {
544 build_compiler: CompilerForCheck,
545 target: TargetSelection,
546}
547
548impl CommandLineStep for CraneliftCodegenBackend {
549 type Output = ();
550 const IS_HOST: bool = true;
551
552 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
553 run.alias("rustc_codegen_cranelift").alias("cg_clif")
554 }
555
556 fn is_default_step(_builder: &Builder<'_>) -> bool {
557 true
558 }
559
560 fn make_run(run: RunConfig<'_>) {
561 run.builder.ensure(CraneliftCodegenBackend {
562 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Codegen),
563 target: run.target,
564 });
565 }
566
567 fn run(self, builder: &Builder<'_>) {
568 let build_compiler = self.build_compiler.build_compiler();
569 let target = self.target;
570
571 let mut cargo = builder::Cargo::new(
572 builder,
573 build_compiler,
574 Mode::Codegen,
575 SourceType::InTree,
576 target,
577 builder.kind,
578 );
579
580 cargo
581 .arg("--manifest-path")
582 .arg(builder.src.join("compiler/rustc_codegen_cranelift/Cargo.toml"));
583 rustc_cargo_env(builder, &mut cargo, target);
584 self.build_compiler.configure_cargo(&mut cargo);
585
586 let _guard = builder.msg(
587 Kind::Check,
588 "rustc_codegen_cranelift",
589 Mode::Codegen,
590 build_compiler,
591 target,
592 );
593
594 let stamp = build_stamp::codegen_backend_stamp(
595 builder,
596 build_compiler,
597 target,
598 &CodegenBackendKind::Cranelift,
599 )
600 .with_prefix("check");
601
602 run_cargo(
603 builder,
604 cargo,
605 builder.config.free_args.clone(),
606 &stamp,
607 vec![],
608 ArtifactKeepMode::OnlyRmeta,
609 );
610 }
611
612 fn metadata(&self) -> Option<StepMetadata> {
613 Some(
614 StepMetadata::check("rustc_codegen_cranelift", self.target)
615 .built_by(self.build_compiler.build_compiler()),
616 )
617 }
618}
619
620#[derive(Debug, Clone, PartialEq, Eq, Hash)]
622pub struct GccCodegenBackend {
623 build_compiler: CompilerForCheck,
624 target: TargetSelection,
625}
626
627impl CommandLineStep for GccCodegenBackend {
628 type Output = ();
629 const IS_HOST: bool = true;
630
631 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
632 run.alias("rustc_codegen_gcc").alias("cg_gcc")
633 }
634
635 fn is_default_step(_builder: &Builder<'_>) -> bool {
636 true
637 }
638
639 fn make_run(run: RunConfig<'_>) {
640 run.builder.ensure(GccCodegenBackend {
641 build_compiler: prepare_compiler_for_check(run.builder, run.target, Mode::Codegen),
642 target: run.target,
643 });
644 }
645
646 fn run(self, builder: &Builder<'_>) {
647 if builder.build.config.vendor {
649 println!("Skipping checking of `rustc_codegen_gcc` with vendoring enabled.");
650 return;
651 }
652
653 let build_compiler = self.build_compiler.build_compiler();
654 let target = self.target;
655
656 let mut cargo = builder::Cargo::new(
657 builder,
658 build_compiler,
659 Mode::Codegen,
660 SourceType::InTree,
661 target,
662 builder.kind,
663 );
664
665 cargo.arg("--manifest-path").arg(builder.src.join("compiler/rustc_codegen_gcc/Cargo.toml"));
666 rustc_cargo_env(builder, &mut cargo, target);
667 self.build_compiler.configure_cargo(&mut cargo);
668
669 let _guard =
670 builder.msg(Kind::Check, "rustc_codegen_gcc", Mode::Codegen, build_compiler, target);
671
672 let stamp = build_stamp::codegen_backend_stamp(
673 builder,
674 build_compiler,
675 target,
676 &CodegenBackendKind::Gcc,
677 )
678 .with_prefix("check");
679
680 run_cargo(
681 builder,
682 cargo,
683 builder.config.free_args.clone(),
684 &stamp,
685 vec![],
686 ArtifactKeepMode::OnlyRmeta,
687 );
688 }
689
690 fn metadata(&self) -> Option<StepMetadata> {
691 Some(
692 StepMetadata::check("rustc_codegen_gcc", self.target)
693 .built_by(self.build_compiler.build_compiler()),
694 )
695 }
696}
697
698macro_rules! tool_check_step {
699 (
700 $name:ident {
701 path: $path:literal
703 $(, alt_path: $alt_path:literal )*
704 , mode: $mode:expr
706 $(, allow_features: $allow_features:expr )?
708 $(, enable_features: [$($enable_features:expr),*] )?
710 $(, default_features: $default_features:expr )?
711 $(, default: $default:literal )?
712 $( , )?
713 }
714 ) => {
715 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
716 pub struct $name {
717 compiler: CompilerForCheck,
718 target: TargetSelection,
719 }
720
721 impl CommandLineStep for $name {
722 type Output = ();
723 const IS_HOST: bool = true;
724
725 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
726 run.multi_path(&[$path $(, $alt_path )*])
727 }
728
729 fn is_default_step(_builder: &Builder<'_>) -> bool {
730 true $( && const { $default } )?
732 }
733
734 fn make_run(run: RunConfig<'_>) {
735 let target = run.target;
736 let mode: Mode = $mode;
737
738 let compiler = prepare_compiler_for_check(run.builder, target, mode);
739
740 if mode == Mode::ToolBootstrap && target != run.builder.host_target {
742 println!("WARNING: not checking bootstrap tool {} for target {target} as it is a bootstrap (host-only) tool", stringify!($path));
743 return;
744 };
745
746 run.builder.ensure($name { target, compiler });
747 }
748
749 fn run(self, builder: &Builder<'_>) {
750 let Self { target, compiler } = self;
751 let allow_features = {
752 let mut _value = "";
753 $( _value = $allow_features; )?
754 _value
755 };
756 let extra_features: &[&str] = &[$($($enable_features),*)?];
757 let default_features = {
758 let mut _value = true;
759 $( _value = $default_features; )?
760 _value
761 };
762 let mode: Mode = $mode;
763 run_tool_check_step(builder, compiler, target, $path, mode, allow_features, extra_features, default_features);
764 }
765
766 fn metadata(&self) -> Option<StepMetadata> {
767 Some(StepMetadata::check(stringify!($name), self.target).built_by(self.compiler.build_compiler))
768 }
769 }
770 }
771}
772
773#[allow(clippy::too_many_arguments)]
775fn run_tool_check_step(
776 builder: &Builder<'_>,
777 compiler: CompilerForCheck,
778 target: TargetSelection,
779 path: &str,
780 mode: Mode,
781 allow_features: &str,
782 extra_features: &[&str],
783 default_features: bool,
784) {
785 let display_name = path.rsplit('/').next().unwrap();
786
787 let build_compiler = compiler.build_compiler();
788
789 let extra_features = extra_features.iter().map(|f| f.to_string()).collect::<Vec<String>>();
790 let mut cargo = prepare_tool_cargo(
791 builder,
792 build_compiler,
793 mode,
794 target,
795 builder.kind,
796 path,
797 SourceType::InTree,
802 &extra_features,
803 );
804 cargo.allow_features(allow_features);
805 compiler.configure_cargo(&mut cargo);
806
807 if display_name == "rust-analyzer" {
810 cargo.arg("--bins");
811 cargo.arg("--tests");
812 cargo.arg("--benches");
813 } else {
814 cargo.arg("--all-targets");
815 }
816
817 if !default_features {
818 cargo.arg("--no-default-features");
819 }
820
821 let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target))
822 .with_prefix(&format!("{display_name}-check"));
823
824 let _guard = builder.msg(builder.kind, display_name, mode, build_compiler, target);
825 run_cargo(
826 builder,
827 cargo,
828 builder.config.free_args.clone(),
829 &stamp,
830 vec![],
831 ArtifactKeepMode::OnlyRmeta,
832 );
833}
834
835tool_check_step!(Rustdoc {
836 path: "src/tools/rustdoc",
837 alt_path: "src/librustdoc",
838 mode: Mode::ToolRustcPrivate
839});
840tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustcPrivate });
845tool_check_step!(Miri {
846 path: "src/tools/miri",
847 mode: Mode::ToolRustcPrivate,
848 enable_features: ["check_only"],
849});
850tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustcPrivate });
851tool_check_step!(Priroda { path: "src/tools/miri/priroda", mode: Mode::ToolRustcPrivate });
852tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustcPrivate });
853tool_check_step!(RustAnalyzer {
854 path: "src/tools/rust-analyzer",
855 mode: Mode::ToolRustcPrivate,
856 allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
857 enable_features: ["in-rust-tree"],
858});
859tool_check_step!(MiroptTestTools {
860 path: "src/tools/miropt-test-tools",
861 mode: Mode::ToolBootstrap
862});
863tool_check_step!(TestFloatParse {
865 path: "src/tools/test-float-parse",
866 mode: Mode::ToolStd,
867 allow_features: TEST_FLOAT_PARSE_ALLOW_FEATURES
868});
869tool_check_step!(FeaturesStatusDump {
870 path: "src/tools/features-status-dump",
871 mode: Mode::ToolBootstrap
872});
873
874tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
875
876tool_check_step!(RunMakeSupport {
879 path: "src/tools/run-make-support",
880 mode: Mode::ToolBootstrap,
881 default: false
882});
883
884tool_check_step!(CoverageDump {
885 path: "src/tools/coverage-dump",
886 mode: Mode::ToolBootstrap,
887 default: false
888});
889
890tool_check_step!(Compiletest {
893 path: "src/tools/compiletest",
894 mode: Mode::ToolBootstrap,
895 default: false,
896});
897
898tool_check_step!(RustdocGuiTest {
902 path: "src/tools/rustdoc-gui-test",
903 mode: Mode::ToolBootstrap,
904 default: false,
905});
906
907tool_check_step!(Linkchecker {
908 path: "src/tools/linkchecker",
909 mode: Mode::ToolBootstrap,
910 default: false
911});
912
913tool_check_step!(BumpStage0 {
914 path: "src/tools/bump-stage0",
915 mode: Mode::ToolBootstrap,
916 default: false
917});
918
919tool_check_step!(Tidy { path: "src/tools/tidy", mode: Mode::ToolBootstrap, default: false });