@@ -135,14 +135,14 @@ pub fn build_link_meta(tcx: &TyCtxt,
135
135
return r;
136
136
}
137
137
138
- pub fn get_linker ( sess : & Session ) -> ( String , Command ) {
138
+ pub fn get_linker ( sess : & Session ) -> ( & str , Command ) {
139
139
if let Some ( ref linker) = sess. opts . cg . linker {
140
- ( linker. clone ( ) , Command :: new ( linker) )
140
+ ( linker, Command :: new ( linker) )
141
141
} else if sess. target . target . options . is_like_msvc {
142
- ( "link.exe" . to_string ( ) , msvc:: link_exe_cmd ( sess) )
142
+ ( "link.exe" , msvc:: link_exe_cmd ( sess) )
143
143
} else {
144
- ( sess. target . target . options . linker . clone ( ) ,
145
- Command :: new ( & sess . target . target . options . linker ) )
144
+ let linker = & sess. target . target . options . linker ;
145
+ ( linker , Command :: new ( linker) )
146
146
}
147
147
}
148
148
@@ -621,6 +621,54 @@ fn link_natively(sess: &Session, dylib: bool,
621
621
let ( pname, mut cmd) = get_linker ( sess) ;
622
622
cmd. env ( "PATH" , command_path ( sess) ) ;
623
623
624
+ if sess. target . target . options . is_like_msvc {
625
+ let mut linker = MsvcLinker {
626
+ name : pname,
627
+ cmd : cmd,
628
+ sess : & sess,
629
+ } ;
630
+ link_natively_helper ( & mut linker,
631
+ sess,
632
+ dylib,
633
+ objects,
634
+ out_filename,
635
+ trans,
636
+ outputs,
637
+ tmpdir) ;
638
+ } else {
639
+ let mut linker = GnuLinker {
640
+ name : pname,
641
+ cmd : cmd,
642
+ sess : & sess,
643
+ } ;
644
+ link_natively_helper ( & mut linker,
645
+ sess,
646
+ dylib,
647
+ objects,
648
+ out_filename,
649
+ trans,
650
+ outputs,
651
+ tmpdir) ;
652
+ }
653
+
654
+ // On OSX, debuggers need this utility to get run to do some munging of
655
+ // the symbols
656
+ if sess. target . target . options . is_like_osx && sess. opts . debuginfo != NoDebugInfo {
657
+ match Command :: new ( "dsymutil" ) . arg ( out_filename) . output ( ) {
658
+ Ok ( ..) => { }
659
+ Err ( e) => sess. fatal ( & format ! ( "failed to run dsymutil: {}" , e) ) ,
660
+ }
661
+ }
662
+ }
663
+
664
+ fn link_natively_helper < T : Linker > ( cmd : & mut T ,
665
+ sess : & Session ,
666
+ dylib : bool ,
667
+ objects : & [ PathBuf ] ,
668
+ out_filename : & Path ,
669
+ trans : & CrateTranslation ,
670
+ outputs : & OutputFilenames ,
671
+ tmpdir : & Path ) {
624
672
let root = sess. target_filesearch ( PathKind :: Native ) . get_lib_path ( ) ;
625
673
cmd. args ( & sess. target . target . options . pre_link_args ) ;
626
674
@@ -633,18 +681,18 @@ fn link_natively(sess: &Session, dylib: bool,
633
681
cmd. arg ( root. join ( obj) ) ;
634
682
}
635
683
636
- {
637
- let mut linker = if sess. target . target . options . is_like_msvc {
638
- Box :: new ( MsvcLinker { cmd : & mut cmd, sess : & sess } ) as Box < Linker >
639
- } else {
640
- Box :: new ( GnuLinker { cmd : & mut cmd, sess : & sess } ) as Box < Linker >
641
- } ;
642
- link_args ( & mut * linker, sess, dylib, tmpdir,
643
- objects, out_filename, trans, outputs) ;
644
- if !sess. target . target . options . no_compiler_rt {
645
- linker. link_staticlib ( "compiler-rt" ) ;
646
- }
684
+ link_args ( cmd,
685
+ sess,
686
+ dylib,
687
+ tmpdir,
688
+ objects,
689
+ out_filename,
690
+ trans,
691
+ outputs) ;
692
+ if !sess. target . target . options . no_compiler_rt {
693
+ cmd. link_staticlib ( "compiler-rt" ) ;
647
694
}
695
+
648
696
cmd. args ( & sess. target . target . options . late_link_args ) ;
649
697
for obj in & sess. target . target . options . post_link_objects {
650
698
cmd. arg ( root. join ( obj) ) ;
@@ -677,7 +725,7 @@ fn link_natively(sess: &Session, dylib: bool,
677
725
let mut output = prog. stderr . clone ( ) ;
678
726
output. extend_from_slice ( & prog. stdout ) ;
679
727
sess. struct_err ( & format ! ( "linking with `{}` failed: {}" ,
680
- pname ,
728
+ cmd ,
681
729
prog. status) )
682
730
. note ( & format ! ( "{:?}" , & cmd) )
683
731
. note ( & escape_string ( & output[ ..] ) )
@@ -688,29 +736,19 @@ fn link_natively(sess: &Session, dylib: bool,
688
736
info ! ( "linker stdout:\n {}" , escape_string( & prog. stdout[ ..] ) ) ;
689
737
} ,
690
738
Err ( e) => {
691
- sess. fatal ( & format ! ( "could not exec the linker `{}`: {}" , pname, e) ) ;
692
- }
693
- }
694
-
695
-
696
- // On OSX, debuggers need this utility to get run to do some munging of
697
- // the symbols
698
- if sess. target . target . options . is_like_osx && sess. opts . debuginfo != NoDebugInfo {
699
- match Command :: new ( "dsymutil" ) . arg ( out_filename) . output ( ) {
700
- Ok ( ..) => { }
701
- Err ( e) => sess. fatal ( & format ! ( "failed to run dsymutil: {}" , e) ) ,
739
+ sess. fatal ( & format ! ( "could not exec the linker `{}`: {}" , cmd, e) ) ;
702
740
}
703
741
}
704
742
}
705
743
706
- fn link_args ( cmd : & mut Linker ,
707
- sess : & Session ,
708
- dylib : bool ,
709
- tmpdir : & Path ,
710
- objects : & [ PathBuf ] ,
711
- out_filename : & Path ,
712
- trans : & CrateTranslation ,
713
- outputs : & OutputFilenames ) {
744
+ fn link_args < T : Linker > ( cmd : & mut T ,
745
+ sess : & Session ,
746
+ dylib : bool ,
747
+ tmpdir : & Path ,
748
+ objects : & [ PathBuf ] ,
749
+ out_filename : & Path ,
750
+ trans : & CrateTranslation ,
751
+ outputs : & OutputFilenames ) {
714
752
715
753
// The default library location, we need this to find the runtime.
716
754
// The location of crates will be determined as needed.
@@ -854,7 +892,7 @@ fn link_args(cmd: &mut Linker,
854
892
// Also note that the native libraries linked here are only the ones located
855
893
// in the current crate. Upstream crates with native library dependencies
856
894
// may have their native library pulled in above.
857
- fn add_local_native_libraries ( cmd : & mut Linker , sess : & Session ) {
895
+ fn add_local_native_libraries < T : Linker > ( cmd : & mut T , sess : & Session ) {
858
896
sess. target_filesearch ( PathKind :: All ) . for_each_lib_search_path ( |path, k| {
859
897
match k {
860
898
PathKind :: Framework => { cmd. framework_path ( path) ; }
@@ -904,8 +942,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
904
942
// Rust crates are not considered at all when creating an rlib output. All
905
943
// dependencies will be linked when producing the final output (instead of
906
944
// the intermediate rlib version)
907
- fn add_upstream_rust_crates ( cmd : & mut Linker , sess : & Session ,
908
- dylib : bool , tmpdir : & Path ) {
945
+ fn add_upstream_rust_crates < T : Linker > ( cmd : & mut T , sess : & Session , dylib : bool , tmpdir : & Path ) {
909
946
// All of the heavy lifting has previously been accomplished by the
910
947
// dependency_format module of the compiler. This is just crawling the
911
948
// output of that module, adding crates as necessary.
@@ -979,8 +1016,11 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
979
1016
// (aka we're making an executable), we can just pass the rlib blindly to
980
1017
// the linker (fast) because it's fine if it's not actually included as
981
1018
// we're at the end of the dependency chain.
982
- fn add_static_crate ( cmd : & mut Linker , sess : & Session , tmpdir : & Path ,
983
- dylib : bool , cratepath : & Path ) {
1019
+ fn add_static_crate < T : Linker > ( cmd : & mut T ,
1020
+ sess : & Session ,
1021
+ tmpdir : & Path ,
1022
+ dylib : bool ,
1023
+ cratepath : & Path ) {
984
1024
if !sess. lto ( ) && !dylib {
985
1025
cmd. link_rlib ( & fix_windows_verbatim_for_gcc ( cratepath) ) ;
986
1026
return
@@ -1027,7 +1067,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
1027
1067
}
1028
1068
1029
1069
// Same thing as above, but for dynamic crates instead of static crates.
1030
- fn add_dynamic_crate ( cmd : & mut Linker , sess : & Session , cratepath : & Path ) {
1070
+ fn add_dynamic_crate < T : Linker > ( cmd : & mut T , sess : & Session , cratepath : & Path ) {
1031
1071
// If we're performing LTO, then it should have been previously required
1032
1072
// that all upstream rust dependencies were available in an rlib format.
1033
1073
assert ! ( !sess. lto( ) ) ;
@@ -1062,7 +1102,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
1062
1102
// generic function calls a native function, then the generic function must
1063
1103
// be instantiated in the target crate, meaning that the native symbol must
1064
1104
// also be resolved in the target crate.
1065
- fn add_upstream_native_libraries ( cmd : & mut Linker , sess : & Session ) {
1105
+ fn add_upstream_native_libraries < T : Linker > ( cmd : & mut T , sess : & Session ) {
1066
1106
// Be sure to use a topological sorting of crates because there may be
1067
1107
// interdependencies between native libraries. When passing -nodefaultlibs,
1068
1108
// for example, almost all native libraries depend on libc, so we have to
0 commit comments