mirror of https://github.com/rust-lang/rust.git
Prefer system MinGW libs when available
This commit is contained in:
parent
b1cb3c0909
commit
1fad337f79
|
@ -968,7 +968,78 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary
|
|||
}
|
||||
}
|
||||
|
||||
// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles
|
||||
// own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64
|
||||
// installed in the system. This breaks many cases where Rust is mixed with other languages
|
||||
// (e.g. *-sys crates).
|
||||
// We prefer system mingw-w64 libraries if they are available to avoid this issue.
|
||||
fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
|
||||
fn find_exe_in_path<P>(exe_name: P) -> Option<PathBuf>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
for dir in env::split_paths(&env::var_os("PATH")?) {
|
||||
let full_path = dir.join(&exe_name);
|
||||
if full_path.is_file() {
|
||||
return Some(fix_windows_verbatim_for_gcc(&full_path));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn probe(sess: &Session) -> Option<PathBuf> {
|
||||
if let (linker, LinkerFlavor::Gcc) = linker_and_flavor(&sess) {
|
||||
let linker_path = if cfg!(windows) && linker.extension().is_none() {
|
||||
linker.with_extension("exe")
|
||||
} else {
|
||||
linker
|
||||
};
|
||||
if let Some(linker_path) = find_exe_in_path(linker_path) {
|
||||
let mingw_arch = match &sess.target.target.arch {
|
||||
x if x == "x86" => "i686",
|
||||
x => x,
|
||||
};
|
||||
let mingw_dir = format!("{}-w64-mingw32", mingw_arch);
|
||||
// Here we have path/bin/gcc but we need path/
|
||||
let mut path = linker_path;
|
||||
path.pop();
|
||||
path.pop();
|
||||
// Based on Clang MinGW driver
|
||||
let probe_path = path.join(&mingw_dir).join("lib");
|
||||
if probe_path.exists() {
|
||||
return Some(probe_path);
|
||||
};
|
||||
let probe_path = path.join(&mingw_dir).join("sys-root/mingw/lib");
|
||||
if probe_path.exists() {
|
||||
return Some(probe_path);
|
||||
};
|
||||
};
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
let mut system_library_path = sess.system_library_path.borrow_mut();
|
||||
match &*system_library_path {
|
||||
Some(Some(compiler_libs_path)) => Some(compiler_libs_path.clone()),
|
||||
Some(None) => None,
|
||||
None => {
|
||||
let path = probe(sess);
|
||||
*system_library_path = Some(path.clone());
|
||||
path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_file_path(sess: &Session, name: &str) -> PathBuf {
|
||||
// prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
|
||||
if sess.target.target.llvm_target.contains("windows-gnu") {
|
||||
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
|
||||
let file_path = compiler_libs_path.join(name);
|
||||
if file_path.exists() {
|
||||
return file_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
let fs = sess.target_filesearch(PathKind::Native);
|
||||
let file_path = fs.get_lib_path().join(name);
|
||||
if file_path.exists() {
|
||||
|
@ -1150,6 +1221,13 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
|
|||
// target descriptor
|
||||
let t = &sess.target.target;
|
||||
|
||||
// prefer system mingw-w64 libs, see get_crt_libs_path comment for more details
|
||||
if cfg!(windows) && sess.target.target.llvm_target.contains("windows-gnu") {
|
||||
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
|
||||
cmd.include_path(&compiler_libs_path);
|
||||
}
|
||||
}
|
||||
|
||||
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
|
||||
|
||||
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
|
||||
|
|
|
@ -133,6 +133,10 @@ pub struct Session {
|
|||
/// Mapping from ident span to path span for paths that don't exist as written, but that
|
||||
/// exist under `std`. For example, wrote `str::from_utf8` instead of `std::str::from_utf8`.
|
||||
pub confused_type_with_std_module: Lock<FxHashMap<Span, Span>>,
|
||||
|
||||
/// Path for libraries that will take preference over libraries shipped by Rust.
|
||||
/// Used by windows-gnu targets to priortize system mingw-w64 libraries.
|
||||
pub system_library_path: OneThread<RefCell<Option<Option<PathBuf>>>>,
|
||||
}
|
||||
|
||||
pub struct PerfStats {
|
||||
|
@ -1069,6 +1073,7 @@ fn build_session_(
|
|||
driver_lint_caps,
|
||||
trait_methods_not_found: Lock::new(Default::default()),
|
||||
confused_type_with_std_module: Lock::new(Default::default()),
|
||||
system_library_path: OneThread::new(RefCell::new(Default::default())),
|
||||
};
|
||||
|
||||
validate_commandline_args_with_session_available(&sess);
|
||||
|
|
Loading…
Reference in New Issue