@@ -1014,86 +1014,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
10141014 }
10151015}
10161016
1017- // Because windows-gnu target is meant to be self-contained for pure Rust code it bundles
1018- // own mingw-w64 libraries. These libraries are usually not compatible with mingw-w64
1019- // installed in the system. This breaks many cases where Rust is mixed with other languages
1020- // (e.g. *-sys crates).
1021- // We prefer system mingw-w64 libraries if they are available to avoid this issue.
1022- fn get_crt_libs_path ( sess : & Session ) -> Option < PathBuf > {
1023- fn find_exe_in_path < P > ( exe_name : P ) -> Option < PathBuf >
1024- where
1025- P : AsRef < Path > ,
1026- {
1027- for dir in env:: split_paths ( & env:: var_os ( "PATH" ) ?) {
1028- let full_path = dir. join ( & exe_name) ;
1029- if full_path. is_file ( ) {
1030- return Some ( fix_windows_verbatim_for_gcc ( & full_path) ) ;
1031- }
1032- }
1033- None
1034- }
1035-
1036- fn probe ( sess : & Session ) -> Option < PathBuf > {
1037- if let ( linker, LinkerFlavor :: Gcc ) = linker_and_flavor ( & sess) {
1038- let linker_path = if cfg ! ( windows) && linker. extension ( ) . is_none ( ) {
1039- linker. with_extension ( "exe" )
1040- } else {
1041- linker
1042- } ;
1043- if let Some ( linker_path) = find_exe_in_path ( linker_path) {
1044- let mingw_arch = match & sess. target . target . arch {
1045- x if x == "x86" => "i686" ,
1046- x => x,
1047- } ;
1048- let mingw_bits = & sess. target . target . target_pointer_width ;
1049- let mingw_dir = format ! ( "{}-w64-mingw32" , mingw_arch) ;
1050- // Here we have path/bin/gcc but we need path/
1051- let mut path = linker_path;
1052- path. pop ( ) ;
1053- path. pop ( ) ;
1054- // Loosely based on Clang MinGW driver
1055- let probe_paths = vec ! [
1056- path. join( & mingw_dir) . join( "lib" ) , // Typical path
1057- path. join( & mingw_dir) . join( "sys-root/mingw/lib" ) , // Rare path
1058- path. join( format!(
1059- "lib/mingw/tools/install/mingw{}/{}/lib" ,
1060- & mingw_bits, & mingw_dir
1061- ) ) , // Chocolatey is creative
1062- ] ;
1063- for probe_path in probe_paths {
1064- if probe_path. join ( "crt2.o" ) . exists ( ) {
1065- return Some ( probe_path) ;
1066- } ;
1067- }
1068- } ;
1069- } ;
1070- None
1071- }
1072-
1073- let mut system_library_path = sess. system_library_path . borrow_mut ( ) ;
1074- match & * system_library_path {
1075- Some ( Some ( compiler_libs_path) ) => Some ( compiler_libs_path. clone ( ) ) ,
1076- Some ( None ) => None ,
1077- None => {
1078- let path = probe ( sess) ;
1079- * system_library_path = Some ( path. clone ( ) ) ;
1080- path
1081- }
1082- }
1083- }
1084-
10851017fn get_object_file_path ( sess : & Session , name : & str , self_contained : bool ) -> PathBuf {
1086- // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
1087- if sess. opts . cg . link_self_contained . is_none ( )
1088- && sess. target . target . llvm_target . contains ( "windows-gnu" )
1089- {
1090- if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
1091- let file_path = compiler_libs_path. join ( name) ;
1092- if file_path. exists ( ) {
1093- return file_path;
1094- }
1095- }
1096- }
10971018 let fs = sess. target_filesearch ( PathKind :: Native ) ;
10981019 let file_path = fs. get_lib_path ( ) . join ( name) ;
10991020 if file_path. exists ( ) {
@@ -1286,6 +1207,28 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
12861207 }
12871208}
12881209
1210+ // Returns true if linker is located within sysroot
1211+ fn detect_self_contained_mingw ( sess : & Session ) -> bool {
1212+ let ( linker, _) = linker_and_flavor ( & sess) ;
1213+ // Assume `-C linker=rust-lld` as self-contained mode
1214+ if linker == Path :: new ( "rust-lld" ) {
1215+ return true ;
1216+ }
1217+ let linker_with_extension = if cfg ! ( windows) && linker. extension ( ) . is_none ( ) {
1218+ linker. with_extension ( "exe" )
1219+ } else {
1220+ linker
1221+ } ;
1222+ for dir in env:: split_paths ( & env:: var_os ( "PATH" ) . unwrap_or_default ( ) ) {
1223+ let full_path = dir. join ( & linker_with_extension) ;
1224+ // If linker comes from sysroot assume self-contained mode
1225+ if full_path. is_file ( ) && !full_path. starts_with ( & sess. sysroot ) {
1226+ return false ;
1227+ }
1228+ }
1229+ true
1230+ }
1231+
12891232/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
12901233/// We only provide such support for a very limited number of targets.
12911234fn crt_objects_fallback ( sess : & Session , crate_type : CrateType ) -> bool {
@@ -1298,10 +1241,10 @@ fn crt_objects_fallback(sess: &Session, crate_type: CrateType) -> bool {
12981241 // based on host and linker path, for example.
12991242 // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
13001243 Some ( CrtObjectsFallback :: Musl ) => sess. crt_static ( Some ( crate_type) ) ,
1301- // FIXME: Find some heuristic for "native mingw toolchain is available",
1302- // likely based on `get_crt_libs_path` (https://github.com/rust-lang/rust/pull/67429).
13031244 Some ( CrtObjectsFallback :: Mingw ) => {
1304- sess. host == sess. target . target && sess. target . target . target_vendor != "uwp"
1245+ sess. host == sess. target . target
1246+ && sess. target . target . target_vendor != "uwp"
1247+ && detect_self_contained_mingw ( & sess)
13051248 }
13061249 // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
13071250 Some ( CrtObjectsFallback :: Wasm ) => true ,
@@ -1498,16 +1441,6 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
14981441
14991442/// Add sysroot and other globally set directories to the directory search list.
15001443fn add_library_search_dirs ( cmd : & mut dyn Linker , sess : & Session , self_contained : bool ) {
1501- // Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details.
1502- if sess. opts . cg . link_self_contained . is_none ( )
1503- && cfg ! ( windows)
1504- && sess. target . target . llvm_target . contains ( "windows-gnu" )
1505- {
1506- if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
1507- cmd. include_path ( & compiler_libs_path) ;
1508- }
1509- }
1510-
15111444 // The default library location, we need this to find the runtime.
15121445 // The location of crates will be determined as needed.
15131446 let lib_path = sess. target_filesearch ( PathKind :: All ) . get_lib_path ( ) ;
0 commit comments