From 2979a2c72dad76130594cd9e4d006db280f0ba27 Mon Sep 17 00:00:00 2001 From: jyn Date: Sat, 4 Nov 2023 18:15:02 -0400 Subject: [PATCH] use RUSTC_WRAPPER instead of RUSTC --- src/bootstrap/src/bin/rustc.rs | 44 ++++++++++++++++++++++++++---- src/bootstrap/src/core/builder.rs | 16 +++++++++++ src/bootstrap/src/utils/dylib.rs | 13 +++++++++ src/bootstrap/src/utils/helpers.rs | 10 +------ 4 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 18136635c42a8..bebdb288d0f39 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -16,11 +16,11 @@ //! never get replaced. use std::env; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::{Child, Command}; use std::time::Instant; -use dylib_util::{dylib_path, dylib_path_var}; +use dylib_util::{dylib_path, dylib_path_var, exe}; #[path = "../utils/bin_helpers.rs"] mod bin_helpers; @@ -29,8 +29,10 @@ mod bin_helpers; mod dylib_util; fn main() { - let args = env::args_os().skip(1).collect::>(); - let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); + let orig_args = env::args_os().skip(1).collect::>(); + let mut args = orig_args.clone(); + let arg = + |name| orig_args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); let stage = bin_helpers::parse_rustc_stage(); let verbose = bin_helpers::parse_rustc_verbose(); @@ -54,12 +56,42 @@ fn main() { let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new); - let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); + let rustc_real = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc)); let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir)); let mut dylib_path = dylib_path(); dylib_path.insert(0, PathBuf::from(&libdir)); - let mut cmd = Command::new(rustc); + // if we're running clippy, trust cargo-clippy to set clippy-driver appropriately (and don't override it with rustc). + // otherwise, substitute whatever cargo thinks rustc should be with RUSTC_REAL. + // NOTE: this means we ignore RUSTC in the environment. + // FIXME: We might want to consider removing RUSTC_REAL and setting RUSTC directly? + let target_name = target + .map(|s| s.to_owned()) + .unwrap_or_else(|| env::var("CFG_COMPILER_HOST_TRIPLE").unwrap()); + let is_clippy = args[0].to_string_lossy().ends_with(&exe("clippy-driver", &target_name)); + let rustc_driver = if is_clippy { + args.remove(0) + } else { + // Cargo doesn't respect RUSTC_WRAPPER for version information >:( + // don't remove the first arg if we're being run as RUSTC instead of RUSTC_WRAPPER. + // Cargo also sometimes doesn't pass the `.exe` suffix on Windows - add it manually. + let current_exe = env::current_exe().expect("couldn't get path to rustc shim"); + // NOTE: we intentionally pass the name of the host, not the target. + let host = env::var("CFG_COMPILER_BUILD_TRIPLE").unwrap(); + let arg0 = exe(args[0].to_str().expect("only utf8 paths are supported"), &host); + if Path::new(&arg0) == current_exe { + args.remove(0); + } + rustc_real + }; + + let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER_REAL") { + let mut cmd = Command::new(wrapper); + cmd.arg(rustc_driver); + cmd + } else { + Command::new(rustc_driver) + }; cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 28761a7ee4b26..ead84ada8f7d7 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -1614,7 +1614,19 @@ impl<'a> Builder<'a> { // Clippy support is a hack and uses the default `cargo-clippy` in path. // Don't override RUSTC so that the `cargo-clippy` in path will be run. if cmd != "clippy" { + // Set RUSTC_WRAPPER to the bootstrap shim, which switches between beta and in-tree + // sysroot depending on whether we're building build scripts. + // NOTE: we intentionally use RUSTC_WRAPPER so that we can support clippy - RUSTC is not + // respected by clippy-driver; RUSTC_WRAPPER happens earlier, before clippy runs. + cargo.env("RUSTC_WRAPPER", self.bootstrap_out.join("rustc")); + // NOTE: we also need to set RUSTC so cargo can run `rustc -vV`; apparently that ignores RUSTC_WRAPPER >:( cargo.env("RUSTC", self.bootstrap_out.join("rustc")); + + // Someone might have set some previous rustc wrapper (e.g. + // sccache) before bootstrap overrode it. Respect that variable. + if let Some(existing_wrapper) = env::var_os("RUSTC_WRAPPER") { + cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper); + } } // Dealing with rpath here is a little special, so let's go into some @@ -1991,7 +2003,11 @@ impl<'a> Builder<'a> { // Environment variables *required* throughout the build // // FIXME: should update code to not require this env var + + // The host this new compiler will *run* on. cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple); + // The host this new compiler is being *built* on. + cargo.env("CFG_COMPILER_BUILD_TRIPLE", compiler.host.triple); // Set this for all builds to make sure doc builds also get it. cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel); diff --git a/src/bootstrap/src/utils/dylib.rs b/src/bootstrap/src/utils/dylib.rs index 279a6a010f1d5..b6e7aec1756b6 100644 --- a/src/bootstrap/src/utils/dylib.rs +++ b/src/bootstrap/src/utils/dylib.rs @@ -25,3 +25,16 @@ pub fn dylib_path() -> Vec { }; std::env::split_paths(&var).collect() } + +/// Given an executable called `name`, return the filename for the +/// executable for a particular target. +#[allow(dead_code)] +pub fn exe(name: &str, target: &str) -> String { + if target.contains("windows") { + format!("{name}.exe") + } else if target.contains("uefi") { + format!("{name}.efi") + } else { + name.to_string() + } +} diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index d96608db22c0e..031d56beb6704 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -46,16 +46,8 @@ macro_rules! t { } pub use t; -/// Given an executable called `name`, return the filename for the -/// executable for a particular target. pub fn exe(name: &str, target: TargetSelection) -> String { - if target.is_windows() { - format!("{name}.exe") - } else if target.contains("uefi") { - format!("{name}.efi") - } else { - name.to_string() - } + crate::utils::dylib::exe(name, &target.triple) } /// Returns `true` if the file name given looks like a dynamic library.