@@ -154,7 +154,7 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
154
154
// The third parameter is for env vars, used on windows to set up the
155
155
// path for MSVC to find its DLLs, and gcc to find its bundled
156
156
// 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 {
158
158
let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
159
159
160
160
// 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
232
232
}
233
233
cmd. env ( "PATH" , env:: join_paths ( new_path) . unwrap ( ) ) ;
234
234
235
- ( linker . to_path_buf ( ) , cmd)
235
+ cmd
236
236
}
237
237
238
238
pub fn each_linked_rlib (
@@ -487,95 +487,18 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
487
487
target_cpu : & str ,
488
488
) {
489
489
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
+ ) ;
541
501
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
- }
579
502
for & ( ref k, ref v) in & sess. target . target . options . link_env {
580
503
cmd. env ( k, v) ;
581
504
}
@@ -597,7 +520,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
597
520
let mut i = 0 ;
598
521
loop {
599
522
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) ) ;
601
524
let output = match prog {
602
525
Ok ( ref output) => output,
603
526
Err ( _) => break ,
@@ -698,7 +621,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
698
621
output. extend_from_slice ( & prog. stdout ) ;
699
622
sess. struct_err ( & format ! (
700
623
"linking with `{}` failed: {}" ,
701
- pname . display( ) ,
624
+ linker_path . display( ) ,
702
625
prog. status
703
626
) )
704
627
. note ( & format ! ( "{:?}" , & cmd) )
@@ -714,9 +637,12 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
714
637
715
638
let mut linker_error = {
716
639
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( ) ) )
718
641
} 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
+ ) )
720
646
}
721
647
} ;
722
648
@@ -1087,7 +1013,7 @@ pub fn get_file_path(sess: &Session, name: &str) -> PathBuf {
1087
1013
1088
1014
pub fn exec_linker (
1089
1015
sess : & Session ,
1090
- cmd : & mut Command ,
1016
+ cmd : & Command ,
1091
1017
out_filename : & Path ,
1092
1018
tmpdir : & Path ,
1093
1019
) -> io:: Result < Output > {
@@ -1233,15 +1159,66 @@ pub fn exec_linker(
1233
1159
}
1234
1160
}
1235
1161
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 ,
1238
1164
flavor : LinkerFlavor ,
1239
1165
sess : & ' a Session ,
1240
1166
crate_type : config:: CrateType ,
1241
1167
tmpdir : & Path ,
1242
1168
out_filename : & Path ,
1243
1169
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
+
1245
1222
// Linker plugins should be specified early in the list of arguments
1246
1223
cmd. linker_plugin_lto ( ) ;
1247
1224
@@ -1440,6 +1417,38 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
1440
1417
// Finally add all the linker arguments provided on the command line along
1441
1418
// with any #[link_args] attributes found inside the crate
1442
1419
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 ( )
1443
1452
}
1444
1453
1445
1454
// # Native library linking
0 commit comments