@@ -968,7 +968,53 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary
968
968
}
969
969
}
970
970
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
+
971
1009
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
+ }
972
1018
let fs = sess. target_filesearch ( PathKind :: Native ) ;
973
1019
let file_path = fs. get_lib_path ( ) . join ( name) ;
974
1020
if file_path. exists ( ) {
@@ -1150,6 +1196,12 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
1150
1196
// target descriptor
1151
1197
let t = & sess. target . target ;
1152
1198
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
+
1153
1205
cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
1154
1206
1155
1207
for obj in codegen_results. modules . iter ( ) . filter_map ( |m| m. object . as_ref ( ) ) {
0 commit comments