@@ -1418,13 +1418,16 @@ pub fn linker_and_flavor(sess: &Session, self_contained: bool) -> (PathBuf, Link
14181418 return ret;
14191419 }
14201420
1421- // FIXME: do it better
1422- if sess. target . os == "windows"
1421+ // When using a supported target in self-contained mode, we want to use rust-lld directly.
1422+ let self_contained_target = sess. target . os == "windows"
14231423 && sess. target . env == "gnu"
14241424 && sess. target . abi == "llvm"
1425- && self_contained
1425+ && self_contained;
1426+ if self_contained_target
1427+ && let Some ( ret) =
1428+ infer_from ( sess, None , Some ( LinkerFlavor :: Gnu ( Cc :: No , Lld :: Yes ) ) , features)
14261429 {
1427- return ( PathBuf :: from ( "rust-lld.exe" ) , LinkerFlavor :: Gnu ( Cc :: No , Lld :: Yes ) ) ;
1430+ return ret ;
14281431 }
14291432
14301433 if let Some ( ret) = infer_from (
@@ -1773,30 +1776,30 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
17731776 }
17741777}
17751778
1776- // Returns true if linker is located within sysroot
1779+ /// Returns true if linker is shipped by Rust.
1780+ // There are currently two different solutions for self-contained mode with mingw-w64:
1781+ // using rust-lld directly (`-gnullvm`) or using shipped cc to call the linker (`-gnu`).
1782+ // Eventually, `-gnu` toolchains might be moved to calling the linker directly.
17771783fn detect_self_contained_mingw ( sess : & Session ) -> bool {
1778- // FIXME: this sort of duplicates `infer_from()` inside `linker_and_flavor()`
1779- let path_buf = sess
1780- . opts
1781- . cg
1782- . linker
1783- . as_ref ( )
1784- . map ( |l| l. as_path ( ) )
1785- . or_else ( || sess. target . linker . as_ref ( ) . map ( |linker| Path :: new ( linker. as_ref ( ) ) ) ) ;
1786- let linker = if let Some ( linker) = path_buf {
1787- linker
1788- } else {
1789- return false ;
1790- } ;
1784+ // Passing custom linker means non-self-contained mode.
1785+ if sess. opts . cg . linker . is_some ( ) {
1786+ // Unless running on `-windows-gnu-llvm` and using `-C linker=rust-lld`.
1787+ if sess. target . abi == "llvm" {
1788+ return sess
1789+ . opts
1790+ . cg
1791+ . linker
1792+ . as_ref ( )
1793+ . is_some_and ( |linker| linker == Path :: new ( "rust-lld" ) ) ;
1794+ }
17911795
1792- // Assume `-C linker=rust-lld` as self-contained mode
1793- if linker == Path :: new ( "rust-lld" ) {
1794- return true ;
1796+ return false ;
17951797 }
1796- let linker_with_extension = if cfg ! ( windows) && linker. extension ( ) . is_none ( ) {
1798+
1799+ let linker_with_extension = if let Some ( linker) = sess. target . linker . as_deref ( ) . map ( Path :: new) {
17971800 linker. with_extension ( "exe" )
17981801 } else {
1799- linker . to_path_buf ( )
1802+ return false ;
18001803 } ;
18011804 for dir in env:: split_paths ( & env:: var_os ( "PATH" ) . unwrap_or_default ( ) ) {
18021805 let full_path = dir. join ( & linker_with_extension) ;
0 commit comments