@@ -69,18 +69,13 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
6969 // This worked historically but is needed manually since #42436 (regression
7070 // was tagged as #42791) and some more info can be found on #44443 for
7171 // emscripten itself.
72- let mut cmd = ( || {
73- if let Some ( linker) = linker. to_str ( ) {
74- if cfg ! ( windows) && linker. ends_with ( ".bat" ) {
75- return Command :: bat_script ( linker)
76- }
77- }
78- match flavor {
72+ let mut cmd = match linker. to_str ( ) {
73+ Some ( linker) if cfg ! ( windows) && linker. ends_with ( ".bat" ) => Command :: bat_script ( linker) ,
74+ _ => match flavor {
7975 LinkerFlavor :: Lld ( f) => Command :: lld ( linker, f) ,
8076 _ => Command :: new ( linker) ,
81-
8277 }
83- } ) ( ) ;
78+ } ;
8479
8580 let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
8681
@@ -600,33 +595,26 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary]) {
600595 }
601596}
602597
603- pub fn linker_and_flavor ( sess : & Session ) -> Result < ( PathBuf , LinkerFlavor ) , ( ) > {
604- fn from < F > (
598+ pub fn linker_and_flavor ( sess : & Session ) -> ( PathBuf , LinkerFlavor ) {
599+ fn infer_from (
605600 sess : & Session ,
606601 linker : Option < PathBuf > ,
607602 flavor : Option < LinkerFlavor > ,
608- otherwise : F ,
609- ) -> Result < ( PathBuf , LinkerFlavor ) , ( ) >
610- where
611- F : FnOnce ( ) -> Result < ( PathBuf , LinkerFlavor ) , ( ) >
612- {
603+ ) -> Option < ( PathBuf , LinkerFlavor ) > {
613604 match ( linker, flavor) {
614- ( Some ( linker) , Some ( flavor) ) => Ok ( ( linker, flavor) ) ,
605+ ( Some ( linker) , Some ( flavor) ) => Some ( ( linker, flavor) ) ,
615606 // only the linker flavor is known; use the default linker for the selected flavor
616- ( None , Some ( flavor) ) => Ok ( ( PathBuf :: from ( match flavor {
617- LinkerFlavor :: Em => "emcc" ,
607+ ( None , Some ( flavor) ) => Some ( ( PathBuf :: from ( match flavor {
608+ LinkerFlavor :: Em => if cfg ! ( windows ) { "emcc.bat" } else { "emcc" } ,
618609 LinkerFlavor :: Gcc => "gcc" ,
619610 LinkerFlavor :: Ld => "ld" ,
620611 LinkerFlavor :: Msvc => "link.exe" ,
621612 LinkerFlavor :: Lld ( _) => "lld" ,
622613 } ) , flavor) ) ,
623- // infer the linker flavor from the linker name
624614 ( Some ( linker) , None ) => {
625- let stem = linker. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) . ok_or_else ( || {
626- sess
627- . struct_err ( & format ! ( "couldn't extract file stem from specified linker" ) )
628- . emit ( ) ;
629- } ) ?. to_owned ( ) ;
615+ let stem = linker. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) . unwrap_or_else ( || {
616+ sess. fatal ( "couldn't extract file stem from specified linker" ) ;
617+ } ) . to_owned ( ) ;
630618
631619 let flavor = if stem == "emcc" {
632620 LinkerFlavor :: Em
@@ -637,32 +625,35 @@ pub fn linker_and_flavor(sess: &Session) -> Result<(PathBuf, LinkerFlavor), ()>
637625 } else if stem == "link" || stem == "lld-link" {
638626 LinkerFlavor :: Msvc
639627 } else {
640- sess
641- . struct_err ( & format ! ( "couldn't infer linker flavor from specified linker" ) )
642- . emit ( ) ;
643- return Err ( ( ) ) ;
628+ // fall back to the value in the target spec
629+ sess. target . target . linker_flavor
644630 } ;
645631
646- Ok ( ( linker, flavor) )
632+ Some ( ( linker, flavor) )
647633 } ,
648- ( None , None ) => otherwise ( ) ,
634+ ( None , None ) => None ,
649635 }
650636 }
651637
652638 // linker and linker flavor specified via command line have precedence over what the target
653639 // specification specifies
654- from ( sess, sess. opts . cg . linker . clone ( ) , sess. opts . debugging_opts . linker_flavor , || {
655- from (
656- sess,
657- sess. target . target . options . linker . clone ( ) . map ( PathBuf :: from) ,
658- Some ( sess. target . target . linker_flavor ) ,
659- || {
660- sess
661- . struct_err ( & format ! ( "no linker or linker flavor information provided" ) )
662- . emit ( ) ;
663- Err ( ( ) )
664- } )
665- } )
640+ if let Some ( ret) = infer_from (
641+ sess,
642+ sess. opts . cg . linker . clone ( ) ,
643+ sess. opts . debugging_opts . linker_flavor ,
644+ ) {
645+ return ret;
646+ }
647+
648+ if let Some ( ret) = infer_from (
649+ sess,
650+ sess. target . target . options . linker . clone ( ) . map ( PathBuf :: from) ,
651+ Some ( sess. target . target . linker_flavor ) ,
652+ ) {
653+ return ret;
654+ }
655+
656+ sess. fatal ( "Not enough information provided to determine how to invoke the linker" ) ;
666657}
667658
668659// Create a dynamic library or executable
@@ -675,12 +666,7 @@ fn link_natively(sess: &Session,
675666 codegen_results : & CodegenResults ,
676667 tmpdir : & Path ) {
677668 info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
678- let ( linker, flavor) = if let Ok ( ( linker, flavor) ) = linker_and_flavor ( sess) {
679- ( linker, flavor)
680- } else {
681- sess. abort_if_errors ( ) ;
682- return ;
683- } ;
669+ let ( linker, flavor) = linker_and_flavor ( sess) ;
684670
685671 // The invocations of cc share some flags across platforms
686672 let ( pname, mut cmd) = get_linker ( sess, & linker, flavor) ;
0 commit comments