Skip to content

Commit 65766fd

Browse files
committed
Prefer system MinGW libs when available
1 parent b1cb3c0 commit 65766fd

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,6 +3436,7 @@ dependencies = [
34363436
"bitflags",
34373437
"cc",
34383438
"jobserver",
3439+
"lazy_static 1.3.0",
34393440
"libc",
34403441
"log",
34413442
"memmap",

src/librustc_codegen_ssa/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ bitflags = "1.2.1"
1414
cc = "1.0.1"
1515
num_cpus = "1.0"
1616
memmap = "0.7"
17+
lazy_static = "1"
1718
log = "0.4.5"
1819
libc = "0.2.44"
1920
jobserver = "0.1.11"

src/librustc_codegen_ssa/back/link.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,53 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary
968968
}
969969
}
970970

971+
// Because windows-gnu target is meant to be self-contained for pure Rust code it bundles
972+
// own mingw-w64 libraries. These libraries are often not compatible with mingw-w64
973+
// installed in the system. This breaks many cases where Rust is mixed with other languages
974+
// (e.g. *-sys crates).
975+
// We prefer system mingw-w64 libraries if they are available to avoid this issue.
976+
fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
977+
use std::sync::Mutex;
978+
979+
lazy_static::lazy_static! {
980+
static ref SYSTEM_LIBS: Mutex<Option<PathBuf>> = Mutex::new(None);
981+
}
982+
983+
let system_libs = SYSTEM_LIBS.lock().unwrap().clone();
984+
if let Some(compiler_libs_path) = system_libs {
985+
println!("cache: hit");
986+
return Some(compiler_libs_path);
987+
} else {
988+
println!("cache: miss");
989+
let compiler = if let Some(linker) = &sess.opts.cg.linker {
990+
linker.clone().into_os_string()
991+
} else if let Some(linker) = &sess.target.target.options.linker {
992+
linker.into()
993+
} else {
994+
return None;
995+
};
996+
if let Ok(output) = Command::new(compiler).arg("-print-file-name=crt2.o").output() {
997+
if let Some(compiler_libs_path) =
998+
PathBuf::from(std::str::from_utf8(&output.stdout).unwrap()).parent()
999+
{
1000+
let compiler_libs_path = fix_windows_verbatim_for_gcc(compiler_libs_path);
1001+
*SYSTEM_LIBS.lock().unwrap() = Some(compiler_libs_path.clone());
1002+
return Some(compiler_libs_path);
1003+
}
1004+
}
1005+
}
1006+
None
1007+
}
1008+
9711009
pub fn get_file_path(sess: &Session, name: &str) -> PathBuf {
1010+
if sess.target.target.llvm_target.contains("windows-gnu") {
1011+
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
1012+
let file_path = compiler_libs_path.join(name);
1013+
if file_path.exists() {
1014+
return file_path;
1015+
}
1016+
}
1017+
}
9721018
let fs = sess.target_filesearch(PathKind::Native);
9731019
let file_path = fs.get_lib_path().join(name);
9741020
if file_path.exists() {
@@ -1150,6 +1196,12 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
11501196
// target descriptor
11511197
let t = &sess.target.target;
11521198

1199+
if sess.target.target.llvm_target.contains("windows-gnu") {
1200+
if let Some(compiler_libs_path) = get_crt_libs_path(sess) {
1201+
cmd.include_path(&compiler_libs_path);
1202+
}
1203+
}
1204+
11531205
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
11541206

11551207
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {

0 commit comments

Comments
 (0)