@@ -983,7 +983,7 @@ fn is_rustc_like<P: AsRef<Path>>(p: P) -> bool {
983
983
/// Returns true if the given path looks like a c compiler program
984
984
///
985
985
/// This does not check c compilers, it only report programs that are definitely not rustc
986
- fn is_like_c_compiler < P : AsRef < Path > > ( p : P ) -> bool {
986
+ fn is_known_c_compiler < P : AsRef < Path > > ( p : P ) -> bool {
987
987
matches ! (
988
988
p. as_ref( )
989
989
. file_stem( )
@@ -1020,49 +1020,52 @@ where
1020
1020
trace ! ( "detect_compiler: {}" , executable. display( ) ) ;
1021
1021
// First, see if this looks like rustc.
1022
1022
1023
- let mut must_be_rust = false ;
1024
- let mut rustc_executable = executable. to_path_buf ( ) ;
1025
- if is_rustc_like ( executable) {
1026
- must_be_rust = true ;
1023
+ let maybe_rustc_executable = if is_rustc_like ( executable) {
1024
+ Some ( executable. to_path_buf ( ) )
1027
1025
} else if env. iter ( ) . any ( |( k, _) | k == OsStr :: new ( "CARGO" ) ) {
1028
1026
// If not, detect the scenario where cargo is configured to wrap rustc with something other than sccache.
1029
1027
// This happens when sccache is used as a `RUSTC_WRAPPER` and another tool is used as a
1030
1028
// `RUSTC_WORKSPACE_WRAPPER`. In that case rustc will be the first argument rather than the command.
1031
1029
//
1032
1030
// The check for the `CARGO` env acts as a guardrail against false positives.
1033
1031
// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-reads
1034
- if let Some ( arg1 ) = args. iter ( ) . next ( ) {
1035
- if is_rustc_like ( arg1 ) {
1036
- must_be_rust = true ;
1037
- rustc_executable = PathBuf :: from ( arg1 )
1038
- }
1039
- }
1032
+ args. iter ( )
1033
+ . next ( )
1034
+ . filter ( |arg1| is_rustc_like ( arg1 ) )
1035
+ . map ( PathBuf :: from)
1036
+ } else {
1037
+ None
1040
1038
} ;
1041
1039
1042
1040
let pool = pool. clone ( ) ;
1043
- if !must_be_rust && is_like_c_compiler ( & rustc_executable) {
1044
- let executable = executable. to_owned ( ) ;
1041
+
1042
+ let rustc_executable = if let Some ( ref rustc_executable) = maybe_rustc_executable {
1043
+ rustc_executable
1044
+ } else if is_known_c_compiler ( executable) {
1045
1045
let cc = detect_c_compiler ( creator, executable, args, env. to_vec ( ) , pool) . await ;
1046
1046
return cc. map ( |c| ( c, None ) ) ;
1047
- }
1047
+ } else {
1048
+ // Even if it does not look like rustc like it might still be rustc driver
1049
+ // so we do full check
1050
+ executable
1051
+ } ;
1048
1052
1049
- // Even if it does not look like rustc like it might still be rustc driver
1050
- // so we do full check
1051
1053
match resolve_rust_compiler (
1052
1054
creator. clone ( ) ,
1053
1055
executable,
1054
- rustc_executable,
1056
+ rustc_executable. to_path_buf ( ) ,
1055
1057
env,
1056
- cwd. to_owned ( ) ,
1058
+ cwd. to_path_buf ( ) ,
1057
1059
dist_archive,
1058
1060
pool. clone ( ) ,
1059
1061
)
1060
1062
. await
1061
1063
{
1062
1064
Ok ( res) => Ok ( res) ,
1063
1065
Err ( e) => {
1064
- if !must_be_rust {
1065
- let executable = executable. to_owned ( ) ;
1066
+ // in case we attempted to test for rustc while it didn't look like it, fallback to c compiler detection one lat time
1067
+ if maybe_rustc_executable. is_none ( ) {
1068
+ let executable = executable. to_path_buf ( ) ;
1066
1069
let cc = detect_c_compiler ( creator, executable, args, env. to_vec ( ) , pool) . await ;
1067
1070
cc. map ( |c| ( c, None ) )
1068
1071
} else {
@@ -1201,15 +1204,16 @@ counted_array!(static ARGS: [ArgInfo<ArgData>; _] = [
1201
1204
take_arg!( "-ccbin" , OsString , CanBeSeparated ( '=' ) , Detect_PassThrough ) ,
1202
1205
] ) ;
1203
1206
1204
- async fn detect_c_compiler < T > (
1207
+ async fn detect_c_compiler < T , P > (
1205
1208
creator : T ,
1206
- executable : PathBuf ,
1209
+ executable : P ,
1207
1210
arguments : & [ OsString ] ,
1208
1211
env : Vec < ( OsString , OsString ) > ,
1209
1212
pool : tokio:: runtime:: Handle ,
1210
1213
) -> Result < Box < dyn Compiler < T > > >
1211
1214
where
1212
1215
T : CommandCreatorSync ,
1216
+ P : AsRef < Path > ,
1213
1217
{
1214
1218
trace ! ( "detect_c_compiler" ) ;
1215
1219
@@ -1261,7 +1265,8 @@ compiler_version=__VERSION__
1261
1265
. to_vec ( ) ;
1262
1266
let ( tempdir, src) = write_temp_file ( & pool, "testfile.c" . as_ref ( ) , test) . await ?;
1263
1267
1264
- let mut cmd = creator. clone ( ) . new_command_sync ( & executable) ;
1268
+ let executable = executable. as_ref ( ) ;
1269
+ let mut cmd = creator. clone ( ) . new_command_sync ( executable) ;
1265
1270
cmd. stdout ( Stdio :: piped ( ) )
1266
1271
. stderr ( Stdio :: piped ( ) )
1267
1272
. envs ( env. iter ( ) . map ( |s| ( & s. 0 , & s. 1 ) ) ) ;
@@ -1302,6 +1307,7 @@ compiler_version=__VERSION__
1302
1307
}
1303
1308
} ) ;
1304
1309
if let Some ( kind) = lines. next ( ) {
1310
+ let executable = executable. to_owned ( ) ;
1305
1311
let version = lines
1306
1312
. next ( )
1307
1313
// In case the compiler didn't expand the macro.
0 commit comments