16
16
//! never get replaced.
17
17
18
18
use std:: env;
19
- use std:: path:: PathBuf ;
19
+ use std:: path:: { Path , PathBuf } ;
20
20
use std:: process:: { Child , Command } ;
21
21
use std:: time:: Instant ;
22
22
23
- use dylib_util:: { dylib_path, dylib_path_var} ;
23
+ use dylib_util:: { dylib_path, dylib_path_var, exe } ;
24
24
25
25
#[ path = "../utils/bin_helpers.rs" ]
26
26
mod bin_helpers;
@@ -29,8 +29,10 @@ mod bin_helpers;
29
29
mod dylib_util;
30
30
31
31
fn main ( ) {
32
- let args = env:: args_os ( ) . skip ( 1 ) . collect :: < Vec < _ > > ( ) ;
33
- let arg = |name| args. windows ( 2 ) . find ( |args| args[ 0 ] == name) . and_then ( |args| args[ 1 ] . to_str ( ) ) ;
32
+ let orig_args = env:: args_os ( ) . skip ( 1 ) . collect :: < Vec < _ > > ( ) ;
33
+ let mut args = orig_args. clone ( ) ;
34
+ let arg =
35
+ |name| orig_args. windows ( 2 ) . find ( |args| args[ 0 ] == name) . and_then ( |args| args[ 1 ] . to_str ( ) ) ;
34
36
35
37
let stage = bin_helpers:: parse_rustc_stage ( ) ;
36
38
let verbose = bin_helpers:: parse_rustc_verbose ( ) ;
@@ -54,12 +56,42 @@ fn main() {
54
56
let sysroot = env:: var_os ( "RUSTC_SYSROOT" ) . expect ( "RUSTC_SYSROOT was not set" ) ;
55
57
let on_fail = env:: var_os ( "RUSTC_ON_FAIL" ) . map ( Command :: new) ;
56
58
57
- let rustc = env:: var_os ( rustc) . unwrap_or_else ( || panic ! ( "{:?} was not set" , rustc) ) ;
59
+ let rustc_real = env:: var_os ( rustc) . unwrap_or_else ( || panic ! ( "{:?} was not set" , rustc) ) ;
58
60
let libdir = env:: var_os ( libdir) . unwrap_or_else ( || panic ! ( "{:?} was not set" , libdir) ) ;
59
61
let mut dylib_path = dylib_path ( ) ;
60
62
dylib_path. insert ( 0 , PathBuf :: from ( & libdir) ) ;
61
63
62
- let mut cmd = Command :: new ( rustc) ;
64
+ // if we're running clippy, trust cargo-clippy to set clippy-driver appropriately (and don't override it with rustc).
65
+ // otherwise, substitute whatever cargo thinks rustc should be with RUSTC_REAL.
66
+ // NOTE: this means we ignore RUSTC in the environment.
67
+ // FIXME: We might want to consider removing RUSTC_REAL and setting RUSTC directly?
68
+ let target_name = target
69
+ . map ( |s| s. to_owned ( ) )
70
+ . unwrap_or_else ( || env:: var ( "CFG_COMPILER_HOST_TRIPLE" ) . unwrap ( ) ) ;
71
+ let is_clippy = args[ 0 ] . to_string_lossy ( ) . ends_with ( & exe ( "clippy-driver" , & target_name) ) ;
72
+ let rustc_driver = if is_clippy {
73
+ args. remove ( 0 )
74
+ } else {
75
+ // Cargo doesn't respect RUSTC_WRAPPER for version information >:(
76
+ // don't remove the first arg if we're being run as RUSTC instead of RUSTC_WRAPPER.
77
+ // Cargo also sometimes doesn't pass the `.exe` suffix on Windows - add it manually.
78
+ let current_exe = env:: current_exe ( ) . expect ( "couldn't get path to rustc shim" ) ;
79
+ // NOTE: we intentionally pass the name of the host, not the target.
80
+ let host = env:: var ( "CFG_COMPILER_BUILD_TRIPLE" ) . unwrap ( ) ;
81
+ let arg0 = exe ( args[ 0 ] . to_str ( ) . expect ( "only utf8 paths are supported" ) , & host) ;
82
+ if Path :: new ( & arg0) == current_exe {
83
+ args. remove ( 0 ) ;
84
+ }
85
+ rustc_real
86
+ } ;
87
+
88
+ let mut cmd = if let Some ( wrapper) = env:: var_os ( "RUSTC_WRAPPER_REAL" ) {
89
+ let mut cmd = Command :: new ( wrapper) ;
90
+ cmd. arg ( rustc_driver) ;
91
+ cmd
92
+ } else {
93
+ Command :: new ( rustc_driver)
94
+ } ;
63
95
cmd. args ( & args) . env ( dylib_path_var ( ) , env:: join_paths ( & dylib_path) . unwrap ( ) ) ;
64
96
65
97
// Get the name of the crate we're compiling, if any.
0 commit comments