@@ -12,7 +12,7 @@ use std::process::Command;
1212use std:: time:: { Duration , Instant } ;
1313
1414use crate :: cache:: { Cache , Interned , INTERNER } ;
15- use crate :: config:: { SplitDebuginfo , TargetSelection , DryRun } ;
15+ use crate :: config:: { DryRun , SplitDebuginfo , TargetSelection } ;
1616use crate :: doc;
1717use crate :: flags:: { Color , Subcommand } ;
1818use crate :: install;
@@ -21,7 +21,9 @@ use crate::run;
2121use crate :: setup;
2222use crate :: test;
2323use crate :: tool:: { self , SourceType } ;
24- use crate :: util:: { self , add_dylib_path, add_link_lib_path, exe, libdir, output, t} ;
24+ use crate :: util:: {
25+ self , add_dylib_path, add_link_lib_path, dylib_path, dylib_path_var, exe, libdir, output, t,
26+ } ;
2527use crate :: EXTRA_CHECK_CFGS ;
2628use crate :: { check, compile, Crate } ;
2729use crate :: { clean, dist} ;
@@ -1061,6 +1063,44 @@ impl<'a> Builder<'a> {
10611063 self . ensure ( tool:: Rustdoc { compiler } )
10621064 }
10631065
1066+ pub fn cargo_clippy_cmd ( & self , run_compiler : Compiler ) -> Command {
1067+ let initial_sysroot_bin = self . initial_rustc . parent ( ) . unwrap ( ) ;
1068+ // Set PATH to include the sysroot bin dir so clippy can find cargo.
1069+ let path = t ! ( env:: join_paths(
1070+ // The sysroot comes first in PATH to avoid using rustup's cargo.
1071+ std:: iter:: once( PathBuf :: from( initial_sysroot_bin) )
1072+ . chain( env:: split_paths( & t!( env:: var( "PATH" ) ) ) )
1073+ ) ) ;
1074+
1075+ if run_compiler. stage == 0 {
1076+ // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
1077+ let cargo_clippy = self . initial_rustc . parent ( ) . unwrap ( ) . join ( "cargo-clippy" ) ;
1078+ let mut cmd = Command :: new ( cargo_clippy) ;
1079+ cmd. env ( "PATH" , & path) ;
1080+ return cmd;
1081+ }
1082+
1083+ let build_compiler = self . compiler ( run_compiler. stage - 1 , self . build . build ) ;
1084+ self . ensure ( tool:: Clippy {
1085+ compiler : build_compiler,
1086+ target : self . build . build ,
1087+ extra_features : vec ! [ ] ,
1088+ } ) ;
1089+ let cargo_clippy = self . ensure ( tool:: CargoClippy {
1090+ compiler : build_compiler,
1091+ target : self . build . build ,
1092+ extra_features : vec ! [ ] ,
1093+ } ) ;
1094+ let mut dylib_path = dylib_path ( ) ;
1095+ let run_compiler = self . compiler ( build_compiler. stage + 1 , self . build . build ) ;
1096+ dylib_path. insert ( 0 , self . sysroot ( run_compiler) . join ( "lib" ) ) ;
1097+
1098+ let mut cmd = Command :: new ( cargo_clippy. unwrap ( ) ) ;
1099+ cmd. env ( dylib_path_var ( ) , env:: join_paths ( & dylib_path) . unwrap ( ) ) ;
1100+ cmd. env ( "PATH" , path) ;
1101+ cmd
1102+ }
1103+
10641104 pub fn rustdoc_cmd ( & self , compiler : Compiler ) -> Command {
10651105 let mut cmd = Command :: new ( & self . bootstrap_out . join ( "rustdoc" ) ) ;
10661106 cmd. env ( "RUSTC_STAGE" , compiler. stage . to_string ( ) )
@@ -1115,7 +1155,7 @@ impl<'a> Builder<'a> {
11151155 cmd : & str ,
11161156 ) -> Command {
11171157 let mut cargo = if cmd == "clippy" {
1118- Command :: new ( self . initial_rustc . parent ( ) . unwrap ( ) . join ( "cargo-clippy" ) )
1158+ self . cargo_clippy_cmd ( compiler )
11191159 } else {
11201160 Command :: new ( & self . initial_cargo )
11211161 } ;
@@ -1270,20 +1310,20 @@ impl<'a> Builder<'a> {
12701310 cargo. args ( s. split_whitespace ( ) ) ;
12711311 }
12721312 rustflags. env ( "RUSTFLAGS_BOOTSTRAP" ) ;
1273- if cmd == "clippy" {
1274- // clippy overwrites sysroot if we pass it to cargo.
1275- // Pass it directly to clippy instead.
1276- // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
1277- // so it has no way of knowing the sysroot.
1278- rustflags. arg ( "--sysroot" ) ;
1279- rustflags. arg ( sysroot_str) ;
1280- // Only run clippy on a very limited subset of crates (in particular, not build scripts).
1281- cargo. arg ( "-Zunstable-options" ) ;
1282- }
1283-
12841313 rustflags. arg ( "--cfg=bootstrap" ) ;
12851314 }
12861315
1316+ if cmd == "clippy" {
1317+ // clippy overwrites sysroot if we pass it to cargo.
1318+ // Pass it directly to clippy instead.
1319+ // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
1320+ // so it has no way of knowing the sysroot.
1321+ rustflags. arg ( "--sysroot" ) ;
1322+ rustflags. arg ( sysroot_str) ;
1323+ // Only run clippy on a very limited subset of crates (in particular, not build scripts).
1324+ cargo. arg ( "-Zunstable-options" ) ;
1325+ }
1326+
12871327 let use_new_symbol_mangling = match self . config . rust_new_symbol_mangling {
12881328 Some ( setting) => {
12891329 // If an explicit setting is given, use that
@@ -1405,10 +1445,6 @@ impl<'a> Builder<'a> {
14051445 Mode :: Std | Mode :: Rustc | Mode :: Codegen | Mode :: ToolRustc => String :: new ( ) ,
14061446 } ;
14071447
1408- if self . jobs ( ) > 1 {
1409- //panic!("TESTING: Run with one job only!");
1410- }
1411-
14121448 cargo. arg ( "-j" ) . arg ( self . jobs ( ) . to_string ( ) ) ;
14131449
14141450 // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
@@ -1471,6 +1507,28 @@ impl<'a> Builder<'a> {
14711507 self . clear_if_dirty ( & out_dir, & self . rustc ( compiler) ) ;
14721508 }
14731509
1510+ // // Cargo doesn't pass `--sysroot` for build scripts and proc-macros, which is exactly when we want to use a different sysroot.
1511+ // if
1512+
1513+ if cmd == "clippy" {
1514+ let build_script_sysroot = if stage != 0 {
1515+ // Our fake rustc shim passes `-Zmark-unstable-if-unmarked` for stage != 0, which we can't
1516+ // replicate because clippy doesn't normally run the shim. We should talk with the clippy
1517+ // team about whether there's a way to do this; maybe cargo-clippy can invoke the shim
1518+ // which invokes clippy-driver?
1519+ cargo. env ( "RUSTC_CLIPPY_IGNORE_BUILD_SCRIPTS_AND_PROC_MACROS" , "1" ) ;
1520+ self . initial_rustc . ancestors ( ) . nth ( 2 ) . unwrap ( )
1521+ } else {
1522+ sysroot. clone ( )
1523+ } ;
1524+ // HACK: clippy will pass `--sysroot` to `RunCompiler` if and only if SYSROOT is set and
1525+ // `--sysroot is not already passed. We bypass clippy-driver altogether in stage 1
1526+ // because there's no way to set `-Zforce-unstable-if-unmarked` for only the correct
1527+ // crates, but for stage 0 build scripts and proc-macros we want to still set the right
1528+ // sysroot.
1529+ cargo. env ( "SYSROOT" , build_script_sysroot) ;
1530+ }
1531+
14741532 // Customize the compiler we're running. Specify the compiler to cargo
14751533 // as our shim and then pass it some various options used to configure
14761534 // how the actual compiler itself is called.
@@ -1481,11 +1539,7 @@ impl<'a> Builder<'a> {
14811539 . env ( "RUSTBUILD_NATIVE_DIR" , self . native_dir ( target) )
14821540 . env ( "RUSTC_REAL" , self . rustc ( compiler) )
14831541 . env ( "RUSTC_STAGE" , stage. to_string ( ) )
1484-
1485- // set for clippy to know the sysroot
1486- . env ( "SYSROOT" , & sysroot)
14871542 . env ( "RUSTC_COMMAND" , cmd)
1488-
14891543 . env ( "RUSTC_SYSROOT" , & sysroot)
14901544 . env ( "RUSTC_LIBDIR" , & libdir)
14911545 . env ( "RUSTDOC" , self . bootstrap_out . join ( "rustdoc" ) )
0 commit comments