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
10 changed files with 152 additions and 255 deletions
|
@ -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 as session;
|
|||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue