@@ -13,7 +13,7 @@ use std::process::Command;
1313use std:: time:: { Duration , Instant } ;
1414
1515use crate :: cache:: { Cache , Interned , INTERNER } ;
16- use crate :: config:: { SplitDebuginfo , TargetSelection , DryRun } ;
16+ use crate :: config:: { DryRun , SplitDebuginfo , TargetSelection } ;
1717use crate :: doc;
1818use crate :: flags:: { Color , Subcommand } ;
1919use crate :: install;
@@ -22,7 +22,9 @@ use crate::run;
2222use crate :: setup;
2323use crate :: test;
2424use crate :: tool:: { self , SourceType } ;
25- use crate :: util:: { self , add_dylib_path, add_link_lib_path, exe, libdir, output, t} ;
25+ use crate :: util:: {
26+ self , add_dylib_path, add_link_lib_path, dylib_path, dylib_path_var, exe, libdir, output, t,
27+ } ;
2628use crate :: EXTRA_CHECK_CFGS ;
2729use crate :: { check, compile, Crate } ;
2830use crate :: { clean, dist} ;
@@ -1118,6 +1120,44 @@ impl<'a> Builder<'a> {
11181120 self . ensure ( tool:: Rustdoc { compiler } )
11191121 }
11201122
1123+ pub fn cargo_clippy_cmd ( & self , run_compiler : Compiler ) -> Command {
1124+ let initial_sysroot_bin = self . initial_rustc . parent ( ) . unwrap ( ) ;
1125+ // Set PATH to include the sysroot bin dir so clippy can find cargo.
1126+ let path = t ! ( env:: join_paths(
1127+ // The sysroot comes first in PATH to avoid using rustup's cargo.
1128+ std:: iter:: once( PathBuf :: from( initial_sysroot_bin) )
1129+ . chain( env:: split_paths( & t!( env:: var( "PATH" ) ) ) )
1130+ ) ) ;
1131+
1132+ if run_compiler. stage == 0 {
1133+ // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
1134+ let cargo_clippy = self . initial_rustc . parent ( ) . unwrap ( ) . join ( "cargo-clippy" ) ;
1135+ let mut cmd = Command :: new ( cargo_clippy) ;
1136+ cmd. env ( "PATH" , & path) ;
1137+ return cmd;
1138+ }
1139+
1140+ let build_compiler = self . compiler ( run_compiler. stage - 1 , self . build . build ) ;
1141+ self . ensure ( tool:: Clippy {
1142+ compiler : build_compiler,
1143+ target : self . build . build ,
1144+ extra_features : vec ! [ ] ,
1145+ } ) ;
1146+ let cargo_clippy = self . ensure ( tool:: CargoClippy {
1147+ compiler : build_compiler,
1148+ target : self . build . build ,
1149+ extra_features : vec ! [ ] ,
1150+ } ) ;
1151+ let mut dylib_path = dylib_path ( ) ;
1152+ let run_compiler = self . compiler ( build_compiler. stage + 1 , self . build . build ) ;
1153+ dylib_path. insert ( 0 , self . sysroot ( run_compiler) . join ( "lib" ) ) ;
1154+
1155+ let mut cmd = Command :: new ( cargo_clippy. unwrap ( ) ) ;
1156+ cmd. env ( dylib_path_var ( ) , env:: join_paths ( & dylib_path) . unwrap ( ) ) ;
1157+ cmd. env ( "PATH" , path) ;
1158+ cmd
1159+ }
1160+
11211161 pub fn rustdoc_cmd ( & self , compiler : Compiler ) -> Command {
11221162 let mut cmd = Command :: new ( & self . bootstrap_out . join ( "rustdoc" ) ) ;
11231163 cmd. env ( "RUSTC_STAGE" , compiler. stage . to_string ( ) )
@@ -1172,7 +1212,7 @@ impl<'a> Builder<'a> {
11721212 cmd : & str ,
11731213 ) -> Command {
11741214 let mut cargo = if cmd == "clippy" {
1175- Command :: new ( self . initial_rustc . parent ( ) . unwrap ( ) . join ( "cargo-clippy" ) )
1215+ self . cargo_clippy_cmd ( compiler )
11761216 } else {
11771217 Command :: new ( & self . initial_cargo )
11781218 } ;
@@ -1327,20 +1367,20 @@ impl<'a> Builder<'a> {
13271367 cargo. args ( s. split_whitespace ( ) ) ;
13281368 }
13291369 rustflags. env ( "RUSTFLAGS_BOOTSTRAP" ) ;
1330- if cmd == "clippy" {
1331- // clippy overwrites sysroot if we pass it to cargo.
1332- // Pass it directly to clippy instead.
1333- // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
1334- // so it has no way of knowing the sysroot.
1335- rustflags. arg ( "--sysroot" ) ;
1336- rustflags. arg ( sysroot_str) ;
1337- // Only run clippy on a very limited subset of crates (in particular, not build scripts).
1338- cargo. arg ( "-Zunstable-options" ) ;
1339- }
1340-
13411370 rustflags. arg ( "--cfg=bootstrap" ) ;
13421371 }
13431372
1373+ if cmd == "clippy" {
1374+ // clippy overwrites sysroot if we pass it to cargo.
1375+ // Pass it directly to clippy instead.
1376+ // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
1377+ // so it has no way of knowing the sysroot.
1378+ rustflags. arg ( "--sysroot" ) ;
1379+ rustflags. arg ( sysroot_str) ;
1380+ // Only run clippy on a very limited subset of crates (in particular, not build scripts).
1381+ cargo. arg ( "-Zunstable-options" ) ;
1382+ }
1383+
13441384 let use_new_symbol_mangling = match self . config . rust_new_symbol_mangling {
13451385 Some ( setting) => {
13461386 // If an explicit setting is given, use that
@@ -1470,10 +1510,6 @@ impl<'a> Builder<'a> {
14701510 Mode :: Std | Mode :: Rustc | Mode :: Codegen | Mode :: ToolRustc => String :: new ( ) ,
14711511 } ;
14721512
1473- if self . jobs ( ) > 1 {
1474- //panic!("TESTING: Run with one job only!");
1475- }
1476-
14771513 cargo. arg ( "-j" ) . arg ( self . jobs ( ) . to_string ( ) ) ;
14781514
14791515 // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
@@ -1536,6 +1572,28 @@ impl<'a> Builder<'a> {
15361572 self . clear_if_dirty ( & out_dir, & self . rustc ( compiler) ) ;
15371573 }
15381574
1575+ // // Cargo doesn't pass `--sysroot` for build scripts and proc-macros, which is exactly when we want to use a different sysroot.
1576+ // if
1577+
1578+ if cmd == "clippy" {
1579+ let build_script_sysroot = if stage != 0 {
1580+ // Our fake rustc shim passes `-Zmark-unstable-if-unmarked` for stage != 0, which we can't
1581+ // replicate because clippy doesn't normally run the shim. We should talk with the clippy
1582+ // team about whether there's a way to do this; maybe cargo-clippy can invoke the shim
1583+ // which invokes clippy-driver?
1584+ cargo. env ( "RUSTC_CLIPPY_IGNORE_BUILD_SCRIPTS_AND_PROC_MACROS" , "1" ) ;
1585+ self . initial_rustc . ancestors ( ) . nth ( 2 ) . unwrap ( )
1586+ } else {
1587+ sysroot. clone ( )
1588+ } ;
1589+ // HACK: clippy will pass `--sysroot` to `RunCompiler` if and only if SYSROOT is set and
1590+ // `--sysroot is not already passed. We bypass clippy-driver altogether in stage 1
1591+ // because there's no way to set `-Zforce-unstable-if-unmarked` for only the correct
1592+ // crates, but for stage 0 build scripts and proc-macros we want to still set the right
1593+ // sysroot.
1594+ cargo. env ( "SYSROOT" , build_script_sysroot) ;
1595+ }
1596+
15391597 // Customize the compiler we're running. Specify the compiler to cargo
15401598 // as our shim and then pass it some various options used to configure
15411599 // how the actual compiler itself is called.
@@ -1546,11 +1604,7 @@ impl<'a> Builder<'a> {
15461604 . env ( "RUSTBUILD_NATIVE_DIR" , self . native_dir ( target) )
15471605 . env ( "RUSTC_REAL" , self . rustc ( compiler) )
15481606 . env ( "RUSTC_STAGE" , stage. to_string ( ) )
1549-
1550- // set for clippy to know the sysroot
1551- . env ( "SYSROOT" , & sysroot)
15521607 . env ( "RUSTC_COMMAND" , cmd)
1553-
15541608 . env ( "RUSTC_SYSROOT" , & sysroot)
15551609 . env ( "RUSTC_LIBDIR" , & libdir)
15561610 . env ( "RUSTDOC" , self . bootstrap_out . join ( "rustdoc" ) )
0 commit comments