Rollup merge of #103660 - ozkanonur:master, r=jyn514
improve `filesearch::get_or_default_sysroot` `fn get_or_default_sysroot` is now improved and used in `miri` and `clippy`, and tests are still passing as they should. So we no longer need to implement custom workarounds/hacks to find sysroot in tools like miri/clippy. Resolves https://github.com/rust-lang/rust/issues/98832 re-opened from #103581
This commit is contained in:
commit
bd9e6e05d2
@ -3664,7 +3664,6 @@ dependencies = [
|
||||
name = "rustc_interface"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libloading",
|
||||
"rustc-rayon",
|
||||
"rustc-rayon-core",
|
||||
@ -3707,7 +3706,6 @@ dependencies = [
|
||||
"rustc_ty_utils",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4127,6 +4125,7 @@ name = "rustc_session"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"getopts",
|
||||
"libc",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
@ -4138,7 +4137,9 @@ dependencies = [
|
||||
"rustc_serialize",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1123,7 +1123,8 @@ fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
|
||||
if path.exists() {
|
||||
return session_tlib;
|
||||
} else {
|
||||
let default_sysroot = filesearch::get_or_default_sysroot();
|
||||
let default_sysroot =
|
||||
filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
|
||||
let default_tlib = filesearch::make_target_lib_path(
|
||||
&default_sysroot,
|
||||
sess.opts.target_triple.triple(),
|
||||
|
@ -48,12 +48,6 @@ rustc_resolve = { path = "../rustc_resolve" }
|
||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||
rustc_ty_utils = { path = "../rustc_ty_utils" }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["libloaderapi"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
use rustc_session::config::CheckCfg;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
use rustc_session::config::{ErrorOutputType, Input, OutputFilenames};
|
||||
use rustc_session::filesearch::sysroot_candidates;
|
||||
use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::parse::CrateConfig;
|
||||
use rustc_session::{early_error, filesearch, output, Session};
|
||||
@ -78,7 +79,7 @@ pub fn create_session(
|
||||
|
||||
let bundle = match rustc_errors::fluent_bundle(
|
||||
sopts.maybe_sysroot.clone(),
|
||||
sysroot_candidates(),
|
||||
sysroot_candidates().to_vec(),
|
||||
sopts.unstable_opts.translate_lang.clone(),
|
||||
sopts.unstable_opts.translate_additional_ftl.as_deref(),
|
||||
sopts.unstable_opts.translate_directionality_markers,
|
||||
@ -273,100 +274,6 @@ fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
|
||||
})
|
||||
}
|
||||
|
||||
fn sysroot_candidates() -> Vec<PathBuf> {
|
||||
let target = session::config::host_triple();
|
||||
let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
|
||||
let path = current_dll_path().and_then(|s| s.canonicalize().ok());
|
||||
if let Some(dll) = path {
|
||||
// use `parent` twice to chop off the file name and then also the
|
||||
// directory containing the dll which should be either `lib` or `bin`.
|
||||
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
|
||||
// The original `path` pointed at the `rustc_driver` crate's dll.
|
||||
// Now that dll should only be in one of two locations. The first is
|
||||
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
|
||||
// other is the target's libdir, for example
|
||||
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
|
||||
//
|
||||
// We don't know which, so let's assume that if our `path` above
|
||||
// ends in `$target` we *could* be in the target libdir, and always
|
||||
// assume that we may be in the main libdir.
|
||||
sysroot_candidates.push(path.to_owned());
|
||||
|
||||
if path.ends_with(target) {
|
||||
sysroot_candidates.extend(
|
||||
path.parent() // chop off `$target`
|
||||
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||
.and_then(|p| p.parent()) // chop off `lib`
|
||||
.map(|s| s.to_owned()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sysroot_candidates;
|
||||
|
||||
#[cfg(unix)]
|
||||
fn current_dll_path() -> Option<PathBuf> {
|
||||
use std::ffi::{CStr, OsStr};
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
unsafe {
|
||||
let addr = current_dll_path as usize as *mut _;
|
||||
let mut info = mem::zeroed();
|
||||
if libc::dladdr(addr, &mut info) == 0 {
|
||||
info!("dladdr failed");
|
||||
return None;
|
||||
}
|
||||
if info.dli_fname.is_null() {
|
||||
info!("dladdr returned null pointer");
|
||||
return None;
|
||||
}
|
||||
let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
|
||||
let os = OsStr::from_bytes(bytes);
|
||||
Some(PathBuf::from(os))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn current_dll_path() -> Option<PathBuf> {
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use std::os::windows::prelude::*;
|
||||
use std::ptr;
|
||||
|
||||
use winapi::um::libloaderapi::{
|
||||
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let mut module = ptr::null_mut();
|
||||
let r = GetModuleHandleExW(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
current_dll_path as usize as *mut _,
|
||||
&mut module,
|
||||
);
|
||||
if r == 0 {
|
||||
info!("GetModuleHandleExW failed: {}", io::Error::last_os_error());
|
||||
return None;
|
||||
}
|
||||
let mut space = Vec::with_capacity(1024);
|
||||
let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
|
||||
if r == 0 {
|
||||
info!("GetModuleFileNameW failed: {}", io::Error::last_os_error());
|
||||
return None;
|
||||
}
|
||||
let r = r as usize;
|
||||
if r >= space.capacity() {
|
||||
info!("our buffer was too small? {}", io::Error::last_os_error());
|
||||
return None;
|
||||
}
|
||||
space.set_len(r);
|
||||
let os = OsString::from_wide(&space);
|
||||
Some(PathBuf::from(os))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_codegen_sysroot(maybe_sysroot: &Option<PathBuf>, backend_name: &str) -> MakeBackendFn {
|
||||
// For now we only allow this function to be called once as it'll dlopen a
|
||||
// few things, which seems to work best if we only do that once. In
|
||||
|
@ -17,3 +17,10 @@ rustc_span = { path = "../rustc_span" }
|
||||
rustc_fs_util = { path = "../rustc_fs_util" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_lint_defs = { path = "../rustc_lint_defs" }
|
||||
smallvec = "1.8.1"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = "0.2"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["libloaderapi"] }
|
||||
|
@ -2447,7 +2447,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
let sysroot = match &sysroot_opt {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
tmp_buf = crate::filesearch::get_or_default_sysroot();
|
||||
tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
|
||||
&tmp_buf
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! A module for searching for libraries
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::iter::FromIterator;
|
||||
@ -62,9 +63,99 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
|
||||
PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")])
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn current_dll_path() -> Result<PathBuf, String> {
|
||||
use std::ffi::{CStr, OsStr};
|
||||
use std::os::unix::prelude::*;
|
||||
|
||||
unsafe {
|
||||
let addr = current_dll_path as usize as *mut _;
|
||||
let mut info = std::mem::zeroed();
|
||||
if libc::dladdr(addr, &mut info) == 0 {
|
||||
return Err("dladdr failed".into());
|
||||
}
|
||||
if info.dli_fname.is_null() {
|
||||
return Err("dladdr returned null pointer".into());
|
||||
}
|
||||
let bytes = CStr::from_ptr(info.dli_fname).to_bytes();
|
||||
let os = OsStr::from_bytes(bytes);
|
||||
Ok(PathBuf::from(os))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn current_dll_path() -> Result<PathBuf, String> {
|
||||
use std::ffi::OsString;
|
||||
use std::io;
|
||||
use std::os::windows::prelude::*;
|
||||
use std::ptr;
|
||||
|
||||
use winapi::um::libloaderapi::{
|
||||
GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let mut module = ptr::null_mut();
|
||||
let r = GetModuleHandleExW(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
current_dll_path as usize as *mut _,
|
||||
&mut module,
|
||||
);
|
||||
if r == 0 {
|
||||
return Err(format!("GetModuleHandleExW failed: {}", io::Error::last_os_error()));
|
||||
}
|
||||
let mut space = Vec::with_capacity(1024);
|
||||
let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32);
|
||||
if r == 0 {
|
||||
return Err(format!("GetModuleFileNameW failed: {}", io::Error::last_os_error()));
|
||||
}
|
||||
let r = r as usize;
|
||||
if r >= space.capacity() {
|
||||
return Err(format!("our buffer was too small? {}", io::Error::last_os_error()));
|
||||
}
|
||||
space.set_len(r);
|
||||
let os = OsString::from_wide(&space);
|
||||
Ok(PathBuf::from(os))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
|
||||
let target = crate::config::host_triple();
|
||||
let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
|
||||
smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
|
||||
let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?));
|
||||
if let Ok(dll) = path {
|
||||
// use `parent` twice to chop off the file name and then also the
|
||||
// directory containing the dll which should be either `lib` or `bin`.
|
||||
if let Some(path) = dll.parent().and_then(|p| p.parent()) {
|
||||
// The original `path` pointed at the `rustc_driver` crate's dll.
|
||||
// Now that dll should only be in one of two locations. The first is
|
||||
// in the compiler's libdir, for example `$sysroot/lib/*.dll`. The
|
||||
// other is the target's libdir, for example
|
||||
// `$sysroot/lib/rustlib/$target/lib/*.dll`.
|
||||
//
|
||||
// We don't know which, so let's assume that if our `path` above
|
||||
// ends in `$target` we *could* be in the target libdir, and always
|
||||
// assume that we may be in the main libdir.
|
||||
sysroot_candidates.push(path.to_owned());
|
||||
|
||||
if path.ends_with(target) {
|
||||
sysroot_candidates.extend(
|
||||
path.parent() // chop off `$target`
|
||||
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||
.and_then(|p| p.parent()) // chop off `lib`
|
||||
.map(|s| s.to_owned()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sysroot_candidates;
|
||||
}
|
||||
|
||||
/// This function checks if sysroot is found using env::args().next(), and if it
|
||||
/// is not found, uses env::current_exe() to imply sysroot.
|
||||
pub fn get_or_default_sysroot() -> PathBuf {
|
||||
/// is not found, finds sysroot from current rustc_driver dll.
|
||||
pub fn get_or_default_sysroot() -> Result<PathBuf, String> {
|
||||
// Follow symlinks. If the resolved path is relative, make it absolute.
|
||||
fn canonicalize(path: PathBuf) -> PathBuf {
|
||||
let path = fs::canonicalize(&path).unwrap_or(path);
|
||||
@ -74,17 +165,32 @@ fn canonicalize(path: PathBuf) -> PathBuf {
|
||||
fix_windows_verbatim_for_gcc(&path)
|
||||
}
|
||||
|
||||
// Use env::current_exe() to get the path of the executable following
|
||||
// symlinks/canonicalizing components.
|
||||
fn from_current_exe() -> PathBuf {
|
||||
match env::current_exe() {
|
||||
Ok(exe) => {
|
||||
let mut p = canonicalize(exe);
|
||||
p.pop();
|
||||
p.pop();
|
||||
p
|
||||
}
|
||||
Err(e) => panic!("failed to get current_exe: {e}"),
|
||||
fn default_from_rustc_driver_dll() -> Result<PathBuf, String> {
|
||||
let dll = current_dll_path().and_then(|s| Ok(canonicalize(s)))?;
|
||||
|
||||
// `dll` will be in one of the following two:
|
||||
// - compiler's libdir: $sysroot/lib/*.dll
|
||||
// - target's libdir: $sysroot/lib/rustlib/$target/lib/*.dll
|
||||
//
|
||||
// use `parent` twice to chop off the file name and then also the
|
||||
// directory containing the dll
|
||||
let dir = dll.parent().and_then(|p| p.parent()).ok_or(format!(
|
||||
"Could not move 2 levels upper using `parent()` on {}",
|
||||
dll.display()
|
||||
))?;
|
||||
|
||||
// if `dir` points target's dir, move up to the sysroot
|
||||
if dir.ends_with(crate::config::host_triple()) {
|
||||
dir.parent() // chop off `$target`
|
||||
.and_then(|p| p.parent()) // chop off `rustlib`
|
||||
.and_then(|p| p.parent()) // chop off `lib`
|
||||
.map(|s| s.to_owned())
|
||||
.ok_or(format!(
|
||||
"Could not move 3 levels upper using `parent()` on {}",
|
||||
dir.display()
|
||||
))
|
||||
} else {
|
||||
Ok(dir.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +224,5 @@ fn from_env_args_next() -> Option<PathBuf> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if sysroot is found using env::args().next(), and if is not found,
|
||||
// use env::current_exe() to imply sysroot.
|
||||
from_env_args_next().unwrap_or_else(from_current_exe)
|
||||
Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?))
|
||||
}
|
||||
|
@ -1309,7 +1309,7 @@ pub fn build_session(
|
||||
|
||||
let sysroot = match &sopts.maybe_sysroot {
|
||||
Some(sysroot) => sysroot.clone(),
|
||||
None => filesearch::get_or_default_sysroot(),
|
||||
None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"),
|
||||
};
|
||||
|
||||
let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
|
||||
|
@ -23,8 +23,8 @@
|
||||
use std::env;
|
||||
use std::ops::Deref;
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{exit, Command};
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
||||
@ -210,17 +210,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
||||
interface::try_print_query_stack(&handler, num_frames);
|
||||
}
|
||||
|
||||
fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<PathBuf> {
|
||||
home.and_then(|home| {
|
||||
toolchain.map(|toolchain| {
|
||||
let mut path = PathBuf::from(home);
|
||||
path.push("toolchains");
|
||||
path.push(toolchain);
|
||||
path
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn main() {
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
@ -228,51 +217,6 @@ pub fn main() {
|
||||
exit(rustc_driver::catch_with_exit_code(move || {
|
||||
let mut orig_args: Vec<String> = env::args().collect();
|
||||
|
||||
// Get the sysroot, looking from most specific to this invocation to the least:
|
||||
// - command line
|
||||
// - runtime environment
|
||||
// - SYSROOT
|
||||
// - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
|
||||
// - sysroot from rustc in the path
|
||||
// - compile-time environment
|
||||
// - SYSROOT
|
||||
// - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
|
||||
let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true);
|
||||
let have_sys_root_arg = sys_root_arg.is_some();
|
||||
let sys_root = sys_root_arg
|
||||
.map(PathBuf::from)
|
||||
.or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from))
|
||||
.or_else(|| {
|
||||
let home = std::env::var("RUSTUP_HOME")
|
||||
.or_else(|_| std::env::var("MULTIRUST_HOME"))
|
||||
.ok();
|
||||
let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
|
||||
.or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN"))
|
||||
.ok();
|
||||
toolchain_path(home, toolchain)
|
||||
})
|
||||
.or_else(|| {
|
||||
Command::new("rustc")
|
||||
.arg("--print")
|
||||
.arg("sysroot")
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|out| String::from_utf8(out.stdout).ok())
|
||||
.map(|s| PathBuf::from(s.trim()))
|
||||
})
|
||||
.or_else(|| option_env!("SYSROOT").map(PathBuf::from))
|
||||
.or_else(|| {
|
||||
let home = option_env!("RUSTUP_HOME")
|
||||
.or(option_env!("MULTIRUST_HOME"))
|
||||
.map(ToString::to_string);
|
||||
let toolchain = option_env!("RUSTUP_TOOLCHAIN")
|
||||
.or(option_env!("MULTIRUST_TOOLCHAIN"))
|
||||
.map(ToString::to_string);
|
||||
toolchain_path(home, toolchain)
|
||||
})
|
||||
.map(|pb| pb.to_string_lossy().to_string())
|
||||
.expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
|
||||
|
||||
// make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
|
||||
// for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver
|
||||
// uses
|
||||
@ -280,13 +224,7 @@ pub fn main() {
|
||||
orig_args.remove(pos);
|
||||
orig_args[0] = "rustc".to_string();
|
||||
|
||||
// if we call "rustc", we need to pass --sysroot here as well
|
||||
let mut args: Vec<String> = orig_args.clone();
|
||||
if !have_sys_root_arg {
|
||||
args.extend(vec!["--sysroot".into(), sys_root]);
|
||||
};
|
||||
|
||||
return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
|
||||
return rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks).run();
|
||||
}
|
||||
|
||||
if orig_args.iter().any(|a| a == "--version" || a == "-V") {
|
||||
@ -309,14 +247,6 @@ pub fn main() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// this conditional check for the --sysroot flag is there so users can call
|
||||
// `clippy_driver` directly
|
||||
// without having to pass --sysroot or anything
|
||||
let mut args: Vec<String> = orig_args.clone();
|
||||
if !have_sys_root_arg {
|
||||
args.extend(vec!["--sysroot".into(), sys_root]);
|
||||
};
|
||||
|
||||
let mut no_deps = false;
|
||||
let clippy_args_var = env::var("CLIPPY_ARGS").ok();
|
||||
let clippy_args = clippy_args_var
|
||||
@ -345,10 +275,11 @@ pub fn main() {
|
||||
|
||||
let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
|
||||
if clippy_enabled {
|
||||
let mut args: Vec<String> = orig_args.clone();
|
||||
args.extend(clippy_args);
|
||||
rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run()
|
||||
} else {
|
||||
rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run()
|
||||
rustc_driver::RunCompiler::new(&orig_args, &mut RustcCallbacks { clippy_args_var }).run()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
@ -216,76 +216,28 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the "default sysroot" that Miri will use for host things if no `--sysroot` flag is set.
|
||||
/// Should be a compile-time constant.
|
||||
fn host_sysroot() -> Option<String> {
|
||||
if option_env!("RUSTC_STAGE").is_some() {
|
||||
// This is being built as part of rustc, and gets shipped with rustup.
|
||||
// We can rely on the sysroot computation in librustc_session.
|
||||
return None;
|
||||
}
|
||||
// For builds outside rustc, we need to ensure that we got a sysroot
|
||||
// that gets used as a default. The sysroot computation in librustc_session would
|
||||
// end up somewhere in the build dir (see `get_or_default_sysroot`).
|
||||
// Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
|
||||
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
|
||||
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
|
||||
Some(match (home, toolchain) {
|
||||
(Some(home), Some(toolchain)) => {
|
||||
// Check that at runtime, we are still in this toolchain (if there is any toolchain).
|
||||
if let Some(toolchain_runtime) =
|
||||
env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN"))
|
||||
{
|
||||
if toolchain_runtime != toolchain {
|
||||
show_error!(
|
||||
"This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\
|
||||
Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`."
|
||||
)
|
||||
}
|
||||
}
|
||||
format!("{home}/toolchains/{toolchain}")
|
||||
}
|
||||
_ => option_env!("RUST_SYSROOT")
|
||||
.unwrap_or_else(|| {
|
||||
show_error!(
|
||||
"To build Miri without rustup, set the `RUST_SYSROOT` env var at build time",
|
||||
)
|
||||
})
|
||||
.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Execute a compiler with the given CLI arguments and callbacks.
|
||||
fn run_compiler(
|
||||
mut args: Vec<String>,
|
||||
target_crate: bool,
|
||||
callbacks: &mut (dyn rustc_driver::Callbacks + Send),
|
||||
) -> ! {
|
||||
// Make sure we use the right default sysroot. The default sysroot is wrong,
|
||||
// because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
|
||||
//
|
||||
// Make sure we always call `host_sysroot` as that also does some sanity-checks
|
||||
// of the environment we were built in and whether it matches what we are running in.
|
||||
let host_default_sysroot = host_sysroot();
|
||||
// Now see if we even need to set something.
|
||||
let sysroot_flag = "--sysroot";
|
||||
if !args.iter().any(|e| e == sysroot_flag) {
|
||||
// No sysroot was set, let's see if we have a custom default we want to configure.
|
||||
let default_sysroot = if target_crate {
|
||||
if target_crate {
|
||||
// Miri needs a custom sysroot for target crates.
|
||||
// If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
|
||||
// that sysroot lives, and that is passed to rustc.
|
||||
let sysroot_flag = "--sysroot";
|
||||
if !args.iter().any(|e| e == sysroot_flag) {
|
||||
// Using the built-in default here would be plain wrong, so we *require*
|
||||
// the env var to make sure things make sense.
|
||||
Some(env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
|
||||
let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
|
||||
show_error!(
|
||||
"Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set"
|
||||
)
|
||||
}))
|
||||
} else {
|
||||
host_default_sysroot
|
||||
};
|
||||
if let Some(sysroot) = default_sysroot {
|
||||
// We need to overwrite the default that librustc_session would compute.
|
||||
)
|
||||
});
|
||||
|
||||
args.push(sysroot_flag.to_owned());
|
||||
args.push(sysroot);
|
||||
args.push(miri_sysroot);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user