@@ -154,7 +154,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
154154// The third parameter is for env vars, used on windows to set up the
155155// path for MSVC to find its DLLs, and gcc to find its bundled
156156// toolchain
157- pub fn get_linker ( sess : & Session , linker : & Path , flavor : LinkerFlavor ) -> ( PathBuf , Command ) {
157+ pub fn get_linker ( sess : & Session , linker : & Path , flavor : LinkerFlavor ) -> Command {
158158 let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
159159
160160 // If our linker looks like a batch script on Windows then to execute this
@@ -232,7 +232,7 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
232232 }
233233 cmd. env ( "PATH" , env:: join_paths ( new_path) . unwrap ( ) ) ;
234234
235- ( linker . to_path_buf ( ) , cmd)
235+ cmd
236236}
237237
238238pub fn each_linked_rlib (
@@ -487,95 +487,18 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
487487 target_cpu : & str ,
488488) {
489489 info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
490- let ( linker, flavor) = linker_and_flavor ( sess) ;
491-
492- let any_dynamic_crate = crate_type == config:: CrateType :: Dylib
493- || codegen_results. crate_info . dependency_formats . iter ( ) . any ( |( ty, list) | {
494- * ty == crate_type && list. iter ( ) . any ( |& linkage| linkage == Linkage :: Dynamic )
495- } ) ;
496-
497- // The invocations of cc share some flags across platforms
498- let ( pname, mut cmd) = get_linker ( sess, & linker, flavor) ;
499-
500- if let Some ( args) = sess. target . target . options . pre_link_args . get ( & flavor) {
501- cmd. args ( args) ;
502- }
503- if let Some ( args) = sess. target . target . options . pre_link_args_crt . get ( & flavor) {
504- if sess. crt_static ( Some ( crate_type) ) {
505- cmd. args ( args) ;
506- }
507- }
508- cmd. args ( & sess. opts . debugging_opts . pre_link_args ) ;
509-
510- if sess. target . target . options . is_like_fuchsia {
511- let prefix = match sess. opts . debugging_opts . sanitizer {
512- Some ( Sanitizer :: Address ) => "asan/" ,
513- _ => "" ,
514- } ;
515- cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
516- }
517-
518- let pre_link_objects = if crate_type == config:: CrateType :: Executable {
519- & sess. target . target . options . pre_link_objects_exe
520- } else {
521- & sess. target . target . options . pre_link_objects_dll
522- } ;
523- for obj in pre_link_objects {
524- cmd. arg ( get_file_path ( sess, obj) ) ;
525- }
526-
527- if crate_type == config:: CrateType :: Executable && sess. crt_static ( Some ( crate_type) ) {
528- for obj in & sess. target . target . options . pre_link_objects_exe_crt {
529- cmd. arg ( get_file_path ( sess, obj) ) ;
530- }
531- }
532-
533- if sess. target . target . options . is_like_emscripten {
534- cmd. arg ( "-s" ) ;
535- cmd. arg ( if sess. panic_strategy ( ) == PanicStrategy :: Abort {
536- "DISABLE_EXCEPTION_CATCHING=1"
537- } else {
538- "DISABLE_EXCEPTION_CATCHING=0"
539- } ) ;
540- }
490+ let ( linker_path, flavor) = linker_and_flavor ( sess) ;
491+ let mut cmd = linker_with_args :: < B > (
492+ & linker_path,
493+ flavor,
494+ sess,
495+ crate_type,
496+ tmpdir,
497+ out_filename,
498+ codegen_results,
499+ target_cpu,
500+ ) ;
541501
542- {
543- let mut linker = codegen_results. linker_info . to_linker ( cmd, & sess, flavor, target_cpu) ;
544- link_sanitizer_runtime ( sess, crate_type, & mut * linker) ;
545- link_args :: < B > (
546- & mut * linker,
547- flavor,
548- sess,
549- crate_type,
550- tmpdir,
551- out_filename,
552- codegen_results,
553- ) ;
554- cmd = linker. finalize ( ) ;
555- }
556- if let Some ( args) = sess. target . target . options . late_link_args . get ( & flavor) {
557- cmd. args ( args) ;
558- }
559- if any_dynamic_crate {
560- if let Some ( args) = sess. target . target . options . late_link_args_dynamic . get ( & flavor) {
561- cmd. args ( args) ;
562- }
563- } else {
564- if let Some ( args) = sess. target . target . options . late_link_args_static . get ( & flavor) {
565- cmd. args ( args) ;
566- }
567- }
568- for obj in & sess. target . target . options . post_link_objects {
569- cmd. arg ( get_file_path ( sess, obj) ) ;
570- }
571- if sess. crt_static ( Some ( crate_type) ) {
572- for obj in & sess. target . target . options . post_link_objects_crt {
573- cmd. arg ( get_file_path ( sess, obj) ) ;
574- }
575- }
576- if let Some ( args) = sess. target . target . options . post_link_args . get ( & flavor) {
577- cmd. args ( args) ;
578- }
579502 for & ( ref k, ref v) in & sess. target . target . options . link_env {
580503 cmd. env ( k, v) ;
581504 }
@@ -597,7 +520,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
597520 let mut i = 0 ;
598521 loop {
599522 i += 1 ;
600- prog = sess. time ( "run_linker" , || exec_linker ( sess, & mut cmd, out_filename, tmpdir) ) ;
523+ prog = sess. time ( "run_linker" , || exec_linker ( sess, & cmd, out_filename, tmpdir) ) ;
601524 let output = match prog {
602525 Ok ( ref output) => output,
603526 Err ( _) => break ,
@@ -698,7 +621,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
698621 output. extend_from_slice ( & prog. stdout ) ;
699622 sess. struct_err ( & format ! (
700623 "linking with `{}` failed: {}" ,
701- pname . display( ) ,
624+ linker_path . display( ) ,
702625 prog. status
703626 ) )
704627 . note ( & format ! ( "{:?}" , & cmd) )
@@ -714,9 +637,12 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
714637
715638 let mut linker_error = {
716639 if linker_not_found {
717- sess. struct_err ( & format ! ( "linker `{}` not found" , pname . display( ) ) )
640+ sess. struct_err ( & format ! ( "linker `{}` not found" , linker_path . display( ) ) )
718641 } else {
719- sess. struct_err ( & format ! ( "could not exec the linker `{}`" , pname. display( ) ) )
642+ sess. struct_err ( & format ! (
643+ "could not exec the linker `{}`" ,
644+ linker_path. display( )
645+ ) )
720646 }
721647 } ;
722648
@@ -1087,7 +1013,7 @@ pub fn get_file_path(sess: &Session, name: &str) -> PathBuf {
10871013
10881014pub fn exec_linker (
10891015 sess : & Session ,
1090- cmd : & mut Command ,
1016+ cmd : & Command ,
10911017 out_filename : & Path ,
10921018 tmpdir : & Path ,
10931019) -> io:: Result < Output > {
@@ -1233,15 +1159,66 @@ pub fn exec_linker(
12331159 }
12341160}
12351161
1236- fn link_args < ' a , B : ArchiveBuilder < ' a > > (
1237- cmd : & mut dyn Linker ,
1162+ fn linker_with_args < ' a , B : ArchiveBuilder < ' a > > (
1163+ path : & Path ,
12381164 flavor : LinkerFlavor ,
12391165 sess : & ' a Session ,
12401166 crate_type : config:: CrateType ,
12411167 tmpdir : & Path ,
12421168 out_filename : & Path ,
12431169 codegen_results : & CodegenResults ,
1244- ) {
1170+ target_cpu : & str ,
1171+ ) -> Command {
1172+ let base_cmd = get_linker ( sess, path, flavor) ;
1173+ // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
1174+ // to the linker args construction.
1175+ assert ! ( base_cmd. get_args( ) . is_empty( ) || sess. target. target. target_vendor == "uwp" ) ;
1176+ let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor, target_cpu) ;
1177+
1178+ if let Some ( args) = sess. target . target . options . pre_link_args . get ( & flavor) {
1179+ cmd. args ( args) ;
1180+ }
1181+ if let Some ( args) = sess. target . target . options . pre_link_args_crt . get ( & flavor) {
1182+ if sess. crt_static ( Some ( crate_type) ) {
1183+ cmd. args ( args) ;
1184+ }
1185+ }
1186+ cmd. args ( & sess. opts . debugging_opts . pre_link_args ) ;
1187+
1188+ if sess. target . target . options . is_like_fuchsia {
1189+ let prefix = match sess. opts . debugging_opts . sanitizer {
1190+ Some ( Sanitizer :: Address ) => "asan/" ,
1191+ _ => "" ,
1192+ } ;
1193+ cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
1194+ }
1195+
1196+ let pre_link_objects = if crate_type == config:: CrateType :: Executable {
1197+ & sess. target . target . options . pre_link_objects_exe
1198+ } else {
1199+ & sess. target . target . options . pre_link_objects_dll
1200+ } ;
1201+ for obj in pre_link_objects {
1202+ cmd. arg ( get_file_path ( sess, obj) ) ;
1203+ }
1204+
1205+ if crate_type == config:: CrateType :: Executable && sess. crt_static ( Some ( crate_type) ) {
1206+ for obj in & sess. target . target . options . pre_link_objects_exe_crt {
1207+ cmd. arg ( get_file_path ( sess, obj) ) ;
1208+ }
1209+ }
1210+
1211+ if sess. target . target . options . is_like_emscripten {
1212+ cmd. arg ( "-s" ) ;
1213+ cmd. arg ( if sess. panic_strategy ( ) == PanicStrategy :: Abort {
1214+ "DISABLE_EXCEPTION_CATCHING=1"
1215+ } else {
1216+ "DISABLE_EXCEPTION_CATCHING=0"
1217+ } ) ;
1218+ }
1219+
1220+ link_sanitizer_runtime ( sess, crate_type, cmd) ;
1221+
12451222 // Linker plugins should be specified early in the list of arguments
12461223 cmd. linker_plugin_lto ( ) ;
12471224
@@ -1440,6 +1417,38 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
14401417 // Finally add all the linker arguments provided on the command line along
14411418 // with any #[link_args] attributes found inside the crate
14421419 cmd. args ( user_link_args) ;
1420+
1421+ cmd. finalize ( ) ;
1422+
1423+ if let Some ( args) = sess. target . target . options . late_link_args . get ( & flavor) {
1424+ cmd. args ( args) ;
1425+ }
1426+ let any_dynamic_crate = crate_type == config:: CrateType :: Dylib
1427+ || codegen_results. crate_info . dependency_formats . iter ( ) . any ( |( ty, list) | {
1428+ * ty == crate_type && list. iter ( ) . any ( |& linkage| linkage == Linkage :: Dynamic )
1429+ } ) ;
1430+ if any_dynamic_crate {
1431+ if let Some ( args) = sess. target . target . options . late_link_args_dynamic . get ( & flavor) {
1432+ cmd. args ( args) ;
1433+ }
1434+ } else {
1435+ if let Some ( args) = sess. target . target . options . late_link_args_static . get ( & flavor) {
1436+ cmd. args ( args) ;
1437+ }
1438+ }
1439+ for obj in & sess. target . target . options . post_link_objects {
1440+ cmd. arg ( get_file_path ( sess, obj) ) ;
1441+ }
1442+ if sess. crt_static ( Some ( crate_type) ) {
1443+ for obj in & sess. target . target . options . post_link_objects_crt {
1444+ cmd. arg ( get_file_path ( sess, obj) ) ;
1445+ }
1446+ }
1447+ if let Some ( args) = sess. target . target . options . post_link_args . get ( & flavor) {
1448+ cmd. args ( args) ;
1449+ }
1450+
1451+ cmd. take_cmd ( )
14431452}
14441453
14451454// # Native library linking
0 commit comments