1
1
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
2
2
3
+ use crate :: core:: build_steps:: check;
3
4
use crate :: core:: build_steps:: compile:: {
4
5
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
5
6
} ;
@@ -9,7 +10,7 @@ use crate::core::builder::{
9
10
} ;
10
11
use crate :: core:: config:: TargetSelection ;
11
12
use crate :: utils:: build_stamp:: { self , BuildStamp } ;
12
- use crate :: { Mode , Subcommand } ;
13
+ use crate :: { Compiler , Mode , Subcommand } ;
13
14
14
15
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
15
16
pub struct Std {
@@ -27,17 +28,25 @@ pub struct Std {
27
28
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
28
29
/// which is not useful if we only want to lint a few crates with specific rules.
29
30
override_build_kind : Option < Kind > ,
31
+
32
+ override_compiler : Option < Compiler > ,
30
33
}
31
34
32
35
impl Std {
33
36
pub fn new ( target : TargetSelection ) -> Self {
34
- Self { target, crates : vec ! [ ] , override_build_kind : None }
37
+ Self { target, crates : vec ! [ ] , override_build_kind : None , override_compiler : None }
35
38
}
36
39
37
40
pub fn build_kind ( mut self , kind : Option < Kind > ) -> Self {
38
41
self . override_build_kind = kind;
39
42
self
40
43
}
44
+
45
+ /// Override the compiler used. Needed when checking tools that use [`Mode::ToolStd`].
46
+ pub fn with_compiler ( mut self , compiler : Compiler ) -> Self {
47
+ self . override_compiler = Some ( compiler) ;
48
+ self
49
+ }
41
50
}
42
51
43
52
impl Step for Std {
@@ -53,14 +62,21 @@ impl Step for Std {
53
62
54
63
fn make_run ( run : RunConfig < ' _ > ) {
55
64
let crates = std_crates_for_run_make ( & run) ;
56
- run. builder . ensure ( Std { target : run. target , crates, override_build_kind : None } ) ;
65
+ run. builder . ensure ( Std {
66
+ target : run. target ,
67
+ crates,
68
+ override_build_kind : None ,
69
+ override_compiler : None ,
70
+ } ) ;
57
71
}
58
72
59
73
fn run ( self , builder : & Builder < ' _ > ) {
60
74
builder. require_submodule ( "library/stdarch" , None ) ;
61
75
62
76
let target = self . target ;
63
- let compiler = builder. compiler ( builder. top_stage , builder. config . build ) ;
77
+ let compiler = self
78
+ . override_compiler
79
+ . unwrap_or_else ( || builder. compiler ( builder. top_stage , builder. config . build ) ) ;
64
80
65
81
let mut cargo = builder:: Cargo :: new (
66
82
builder,
@@ -375,6 +391,8 @@ macro_rules! tool_check_step {
375
391
// The part of this path after the final '/' is also used as a display name.
376
392
path: $path: literal
377
393
$( , alt_path: $alt_path: literal ) *
394
+ , mode: $mode: path
395
+ $( , allow_features: $allow_features: expr ) ?
378
396
$( , default : $default: literal ) ?
379
397
$( , ) ?
380
398
}
@@ -400,7 +418,14 @@ macro_rules! tool_check_step {
400
418
401
419
fn run( self , builder: & Builder <' _>) {
402
420
let Self { target } = self ;
403
- run_tool_check_step( builder, target, stringify!( $name) , $path) ;
421
+
422
+ let allow_features = {
423
+ let mut _value = "" ;
424
+ $( _value = $allow_features; ) ?
425
+ _value
426
+ } ;
427
+
428
+ run_tool_check_step( builder, target, $path, $mode, allow_features) ;
404
429
}
405
430
}
406
431
}
@@ -410,18 +435,38 @@ macro_rules! tool_check_step {
410
435
fn run_tool_check_step (
411
436
builder : & Builder < ' _ > ,
412
437
target : TargetSelection ,
413
- step_type_name : & str ,
414
438
path : & str ,
439
+ mode : Mode ,
440
+ allow_features : & str ,
415
441
) {
416
442
let display_name = path. rsplit ( '/' ) . next ( ) . unwrap ( ) ;
417
- let compiler = builder. compiler ( builder. top_stage , builder. config . build ) ;
418
443
419
- builder. ensure ( Rustc :: new ( target, builder) ) ;
444
+ let host = builder. config . build ;
445
+ let compiler;
446
+
447
+ match mode {
448
+ Mode :: ToolBootstrap => {
449
+ // Most "bootstrap tools" just need the bootstrap compiler.
450
+ compiler = builder. compiler ( 0 , host) ;
451
+ }
452
+ Mode :: ToolStd => {
453
+ // A small number of bootstrap tools also rely on in-tree standard
454
+ // library crates (e.g. compiletest needs libtest), so we use the
455
+ // bootstrap compiler to do a check build of the standard library.
456
+ compiler = builder. compiler ( 0 , host) ;
457
+ builder. ensure ( check:: Std :: new ( target) . with_compiler ( compiler) ) ;
458
+ }
459
+ Mode :: ToolRustc => {
460
+ compiler = builder. compiler ( builder. top_stage , host) ;
461
+ builder. ensure ( check:: Rustc :: new ( target, builder) ) ;
462
+ }
463
+ _ => panic ! ( "unexpected mode for tool check step: {mode:?}" ) ,
464
+ }
420
465
421
466
let mut cargo = prepare_tool_cargo (
422
467
builder,
423
468
compiler,
424
- Mode :: ToolRustc ,
469
+ mode ,
425
470
target,
426
471
builder. kind ,
427
472
path,
@@ -432,39 +477,62 @@ fn run_tool_check_step(
432
477
SourceType :: InTree ,
433
478
& [ ] ,
434
479
) ;
480
+ cargo. allow_features ( allow_features) ;
435
481
436
482
// For ./x.py clippy, don't run with --all-targets because
437
483
// linting tests and benchmarks can produce very noisy results
438
484
if builder. kind != Kind :: Clippy {
439
485
cargo. arg ( "--all-targets" ) ;
440
486
}
441
487
442
- let stamp = BuildStamp :: new ( & builder. cargo_out ( compiler, Mode :: ToolRustc , target) )
443
- . with_prefix ( & format ! ( "{}-check" , step_type_name . to_lowercase ( ) ) ) ;
488
+ let stamp = BuildStamp :: new ( & builder. cargo_out ( compiler, mode , target) )
489
+ . with_prefix ( & format ! ( "{display_name }-check" ) ) ;
444
490
445
- let _guard = builder. msg_check ( format ! ( "{display_name} artifacts" ) , target) ;
491
+ let _guard =
492
+ builder. msg_tool ( builder. kind , mode, display_name, compiler. stage , & compiler. host , & target) ;
446
493
run_cargo ( builder, cargo, builder. config . free_args . clone ( ) , & stamp, vec ! [ ] , true , false ) ;
447
494
}
448
495
449
- tool_check_step ! ( Rustdoc { path: "src/tools/rustdoc" , alt_path: "src/librustdoc" } ) ;
496
+ // FIXME: Some of these `Mode::ToolRustc` values might be wrong.
497
+ // (Historically, all tools were hardcoded to use `Mode::ToolRustc`.)
498
+
499
+ tool_check_step ! ( Rustdoc {
500
+ path: "src/tools/rustdoc" ,
501
+ alt_path: "src/librustdoc" ,
502
+ mode: Mode :: ToolRustc ,
503
+ } ) ;
450
504
// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
451
505
// of a submodule. Since the SourceType only drives the deny-warnings
452
506
// behavior, treat it as in-tree so that any new warnings in clippy will be
453
507
// rejected.
454
- tool_check_step ! ( Clippy { path: "src/tools/clippy" } ) ;
455
- tool_check_step ! ( Miri { path: "src/tools/miri" } ) ;
456
- tool_check_step ! ( CargoMiri { path: "src/tools/miri/cargo-miri" } ) ;
457
- tool_check_step ! ( Rustfmt { path: "src/tools/rustfmt" } ) ;
458
- tool_check_step ! ( MiroptTestTools { path: "src/tools/miropt-test-tools" } ) ;
459
- tool_check_step ! ( TestFloatParse { path: "src/etc/test-float-parse" } ) ;
460
- tool_check_step ! ( FeaturesStatusDump { path: "src/tools/features-status-dump" } ) ;
461
-
462
- tool_check_step ! ( Bootstrap { path: "src/bootstrap" , default : false } ) ;
508
+ tool_check_step ! ( Clippy { path: "src/tools/clippy" , mode: Mode :: ToolRustc } ) ;
509
+ tool_check_step ! ( Miri { path: "src/tools/miri" , mode: Mode :: ToolRustc } ) ;
510
+ tool_check_step ! ( CargoMiri { path: "src/tools/miri/cargo-miri" , mode: Mode :: ToolRustc } ) ;
511
+ tool_check_step ! ( Rustfmt { path: "src/tools/rustfmt" , mode: Mode :: ToolRustc } ) ;
512
+ tool_check_step ! ( MiroptTestTools { path: "src/tools/miropt-test-tools" , mode: Mode :: ToolRustc } ) ;
513
+ tool_check_step ! ( TestFloatParse { path: "src/etc/test-float-parse" , mode: Mode :: ToolRustc } ) ;
514
+ tool_check_step ! ( FeaturesStatusDump {
515
+ path: "src/tools/features-status-dump" ,
516
+ mode: Mode :: ToolRustc ,
517
+ } ) ;
518
+
519
+ tool_check_step ! ( Bootstrap { path: "src/bootstrap" , mode: Mode :: ToolBootstrap , default : false } ) ;
463
520
464
521
// `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
465
522
// check to make it easier to work on.
466
- tool_check_step ! ( RunMakeSupport { path: "src/tools/run-make-support" , default : false } ) ;
523
+ tool_check_step ! ( RunMakeSupport {
524
+ path: "src/tools/run-make-support" ,
525
+ mode: Mode :: ToolBootstrap ,
526
+ default : false ,
527
+ } ) ;
467
528
468
529
// Compiletest is implicitly "checked" when it gets built in order to run tests,
469
530
// so this is mainly for people working on compiletest to run locally.
470
- tool_check_step ! ( Compiletest { path: "src/tools/compiletest" , default : false } ) ;
531
+ //
532
+ // Compiletest uses libtest internally, so it needs `Mode::ToolStd` and `#![feature(test)]`.
533
+ tool_check_step ! ( Compiletest {
534
+ path: "src/tools/compiletest" ,
535
+ mode: Mode :: ToolStd ,
536
+ allow_features: "test" ,
537
+ default : false ,
538
+ } ) ;
0 commit comments