@@ -747,6 +747,71 @@ pub fn link_binary(sess: Session,
747
747
obj_filename: &Path,
748
748
out_filename: &Path,
749
749
lm: LinkMeta) {
750
+ // In the future, FreeBSD will use clang as default compiler.
751
+ // It would be flexible to use cc (system's default C compiler)
752
+ // instead of hard-coded gcc.
753
+ // For win32, there is no cc command,
754
+ // so we add a condition to make it use gcc.
755
+ let cc_prog: ~str = if sess.targ_cfg.os == session::os_android {
756
+ match &sess.opts.android_cross_path {
757
+ &Some(copy path) => {
758
+ fmt!(" %s/bin/arm-linux-androideabi-gcc", path)
759
+ }
760
+ &None => {
761
+ sess.fatal(~" need Android NDK path for linking \
762
+ ( --android-cross-path) ")
763
+ }
764
+ }
765
+ } else if sess.targ_cfg.os == session::os_win32 { ~" gcc" }
766
+ else { ~" cc" };
767
+ // The invocations of cc share some flags across platforms
768
+
769
+
770
+ let output = if *sess.building_library {
771
+ let long_libname = output_dll_filename(sess.targ_cfg.os, lm);
772
+ debug!(" link_meta. name: %s", lm.name);
773
+ debug!(" long_libname: %s", long_libname);
774
+ debug!(" out_filename: %s", out_filename.to_str());
775
+ debug!(" dirname( out_filename) : %s", out_filename.dir_path().to_str());
776
+
777
+ out_filename.dir_path().push(long_libname)
778
+ } else {
779
+ /*bad*/copy *out_filename
780
+ };
781
+
782
+ debug!(" output: %s", output.to_str());
783
+ let mut cc_args = link_args(sess, obj_filename, out_filename, lm);
784
+ debug!(" %s link args: %s", cc_prog, str::connect(cc_args, ~" "));
785
+ // We run 'cc' here
786
+ let prog = run::program_output(cc_prog, cc_args);
787
+ if 0 != prog.status {
788
+ sess.err(fmt!(" linking with `%s` failed with code %d",
789
+ cc_prog, prog.status));
790
+ sess.note(fmt!(" %s arguments: %s",
791
+ cc_prog, str::connect(cc_args, ~" ")));
792
+ sess.note(prog.err + prog.out);
793
+ sess.abort_if_errors();
794
+ }
795
+
796
+ // Clean up on Darwin
797
+ if sess.targ_cfg.os == session::os_macos {
798
+ run::run_program(~" dsymutil", ~[output.to_str()]);
799
+ }
800
+
801
+ // Remove the temporary object file if we aren't saving temps
802
+ if !sess.opts.save_temps {
803
+ if ! os::remove_file(obj_filename) {
804
+ sess.warn(fmt!(" failed to delete object file `%s`",
805
+ obj_filename. to_str( ) ) ) ;
806
+ }
807
+ }
808
+ }
809
+
810
+ pub fn link_args( sess: Session ,
811
+ obj_filename: & Path ,
812
+ out_filename: & Path ,
813
+ lm: LinkMeta ) -> ~[ ~str ] {
814
+
750
815
// Converts a library file-stem into a cc -l argument
751
816
fn unlib( config: @session:: config, stem: ~str ) -> ~str {
752
817
if stem. starts_with( "lib") &&
@@ -757,48 +822,23 @@ pub fn link_binary(sess: Session,
757
822
}
758
823
}
759
824
825
+
760
826
let output = if * sess. building_library {
761
827
let long_libname = output_dll_filename( sess. targ_cfg. os, lm) ;
762
- debug!(" link_meta. name: %s", lm.name);
763
- debug!(" long_libname: %s", long_libname);
764
- debug!(" out_filename: %s", out_filename.to_str());
765
- debug!(" dirname( out_filename) : %s", out_filename.dir_path().to_str());
766
-
767
828
out_filename. dir_path( ) . push( long_libname)
768
829
} else {
769
830
/*bad*/ copy * out_filename
770
831
} ;
771
832
772
- debug!(" output: %s", output.to_str());
773
-
774
833
// The default library location, we need this to find the runtime.
775
834
// The location of crates will be determined as needed.
776
835
let stage: ~str = ~"-L " + sess. filesearch. get_target_lib_path( ) . to_str( ) ;
777
836
778
- // In the future, FreeBSD will use clang as default compiler.
779
- // It would be flexible to use cc (system's default C compiler)
780
- // instead of hard-coded gcc.
781
- // For win32, there is no cc command,
782
- // so we add a condition to make it use gcc.
783
- let cc_prog: ~str = if sess.targ_cfg.os == session::os_android {
784
- match &sess.opts.android_cross_path {
785
- &Some(copy path) => {
786
- fmt!(" %s/bin/arm-linux-androideabi-gcc", path)
787
- }
788
- &None => {
789
- sess.fatal(~" need Android NDK path for linking \
790
- ( --android-cross-path) ")
791
- }
792
- }
793
- } else if sess.targ_cfg.os == session::os_win32 { ~" gcc" }
794
- else { ~" cc" };
795
- // The invocations of cc share some flags across platforms
837
+ let mut args = vec:: append( ~[ stage] , sess. targ_cfg. target_strs. cc_args) ;
796
838
797
- let mut cc_args =
798
- vec::append(~[stage], sess.targ_cfg.target_strs.cc_args);
799
- cc_args.push(~" -o");
800
- cc_args.push(output.to_str());
801
- cc_args.push(obj_filename.to_str());
839
+ args. push( ~"-o") ;
840
+ args. push( output. to_str( ) ) ;
841
+ args. push( obj_filename. to_str( ) ) ;
802
842
803
843
let lib_cmd;
804
844
let os = sess. targ_cfg. os;
@@ -813,23 +853,23 @@ pub fn link_binary(sess: Session,
813
853
let cstore = sess. cstore;
814
854
for cstore:: get_used_crate_files( cstore) . each |cratepath| {
815
855
if cratepath. filetype( ) == Some ( ~". rlib") {
816
- cc_args .push(cratepath.to_str());
856
+ args . push( cratepath. to_str( ) ) ;
817
857
loop ;
818
858
}
819
859
let dir = cratepath. dirname( ) ;
820
- if dir != ~" " { cc_args .push(~" -L " + dir); }
860
+ if dir != ~"" { args . push( ~"-L " + dir) ; }
821
861
let libarg = unlib( sess. targ_cfg, cratepath. filestem( ) . get( ) ) ;
822
- cc_args .push(~" -l" + libarg);
862
+ args . push( ~"-l" + libarg) ;
823
863
}
824
864
825
865
let ula = cstore:: get_used_link_args( cstore) ;
826
- for ula.each |arg| { cc_args .push(/*bad*/copy *arg); }
866
+ for ula. each |arg| { args . push( /*bad*/ copy * arg) ; }
827
867
828
868
// Add all the link args for external crates.
829
869
do cstore:: iter_crate_data( cstore) |crate_num, _| {
830
870
let link_args = csearch:: get_link_args_for_crate( cstore, crate_num) ;
831
871
do vec:: consume( link_args) |_, link_arg| {
832
- cc_args .push(link_arg);
872
+ args . push( link_arg) ;
833
873
}
834
874
}
835
875
@@ -842,93 +882,74 @@ pub fn link_binary(sess: Session,
842
882
// forces to make sure that library can be found at runtime.
843
883
844
884
for sess. opts. addl_lib_search_paths. each |path| {
845
- cc_args .push(~" -L " + path.to_str());
885
+ args . push( ~"-L " + path. to_str( ) ) ;
846
886
}
847
887
848
888
// The names of the extern libraries
849
889
let used_libs = cstore:: get_used_libraries( cstore) ;
850
- for used_libs.each |l| { cc_args .push(~" -l" + *l); }
890
+ for used_libs. each |l| { args . push( ~"-l" + * l) ; }
851
891
852
892
if * sess. building_library {
853
- cc_args .push(lib_cmd);
893
+ args . push( lib_cmd) ;
854
894
855
895
// On mac we need to tell the linker to let this library
856
896
// be rpathed
857
897
if sess. targ_cfg. os == session:: os_macos {
858
- cc_args .push(~" -Wl , -install_name, @rpath/"
898
+ args . push( ~"-Wl , -install_name, @rpath/"
859
899
+ output. filename( ) . get( ) ) ;
860
900
}
861
901
}
862
902
863
903
// On linux librt and libdl are an indirect dependencies via rustrt,
864
904
// and binutils 2.22+ won't add them automatically
865
905
if sess. targ_cfg. os == session:: os_linux {
866
- cc_args .push_all(~[~" -lrt", ~" -ldl"]);
906
+ args . push_all( ~[ ~"-lrt", ~"-ldl"] ) ;
867
907
868
908
// LLVM implements the `frem` instruction as a call to `fmod`,
869
909
// which lives in libm. Similar to above, on some linuxes we
870
910
// have to be explicit about linking to it. See #2510
871
- cc_args .push(~" -lm");
911
+ args . push( ~"-lm") ;
872
912
}
873
913
else if sess. targ_cfg. os == session:: os_android {
874
- cc_args .push_all(~[~" -ldl", ~" -llog", ~" -lsupc++",
914
+ args . push_all( ~[ ~"-ldl", ~"-llog", ~"-lsupc++",
875
915
~"-lgnustl_shared"] ) ;
876
- cc_args .push(~" -lm");
916
+ args . push( ~"-lm") ;
877
917
}
878
918
879
919
if sess. targ_cfg. os == session:: os_freebsd {
880
- cc_args .push_all(~[~" -pthread", ~" -lrt",
881
- ~" -L /usr/local/lib", ~" -lexecinfo",
882
- ~" -L /usr/local/lib/gcc46",
883
- ~" -L /usr/local/lib/gcc44", ~" -lstdc++",
884
- ~" -Wl , -z, origin",
885
- ~" -Wl , -rpath, /usr/local/lib/gcc46",
886
- ~" -Wl , -rpath, /usr/local/lib/gcc44"]);
920
+ args . push_all( ~[ ~"-pthread", ~"-lrt",
921
+ ~"-L /usr/local/lib", ~"-lexecinfo",
922
+ ~"-L /usr/local/lib/gcc46",
923
+ ~"-L /usr/local/lib/gcc44", ~"-lstdc++",
924
+ ~"-Wl , -z, origin",
925
+ ~"-Wl , -rpath, /usr/local/lib/gcc46",
926
+ ~"-Wl , -rpath, /usr/local/lib/gcc44"] ) ;
887
927
}
888
928
889
929
// OS X 10.6 introduced 'compact unwind info', which is produced by the
890
930
// linker from the dwarf unwind info. Unfortunately, it does not seem to
891
931
// understand how to unwind our __morestack frame, so we have to turn it
892
932
// off. This has impacted some other projects like GHC.
893
933
if sess. targ_cfg. os == session:: os_macos {
894
- cc_args .push(~" -Wl , -no_compact_unwind");
934
+ args . push( ~"-Wl , -no_compact_unwind") ;
895
935
}
896
936
897
937
// Stack growth requires statically linking a __morestack function
898
- cc_args .push(~" -lmorestack");
938
+ args . push( ~"-lmorestack") ;
899
939
900
940
// Always want the runtime linked in
901
- cc_args .push(~" -lrustrt");
941
+ args . push( ~"-lrustrt") ;
902
942
903
943
// FIXME (#2397): At some point we want to rpath our guesses as to where
904
944
// extern libraries might live, based on the addl_lib_search_paths
905
- cc_args .push_all(rpath::get_rpath_flags(sess, &output));
945
+ args . push_all( rpath:: get_rpath_flags( sess, & output) ) ;
906
946
907
- debug!(" %s link args: %s", cc_prog, str::connect(cc_args, ~" "));
908
- // We run 'cc' here
909
- let prog = run::program_output(cc_prog, cc_args);
910
- if 0 != prog.status {
911
- sess.err(fmt!(" linking with `%s` failed with code %d",
912
- cc_prog, prog.status));
913
- sess.note(fmt!(" %s arguments: %s",
914
- cc_prog, str::connect(cc_args, ~" ")));
915
- sess.note(prog.err + prog.out);
916
- sess.abort_if_errors();
917
- }
947
+ // Finally add all the linker arguments provided on the command line
948
+ args. push_all( sess. opts. linker_args) ;
918
949
919
- // Clean up on Darwin
920
- if sess.targ_cfg.os == session::os_macos {
921
- run::run_program(~" dsymutil", ~[output.to_str()]);
922
- }
923
-
924
- // Remove the temporary object file if we aren't saving temps
925
- if !sess.opts.save_temps {
926
- if ! os::remove_file(obj_filename) {
927
- sess.warn(fmt!(" failed to delete object file `%s`",
928
- obj_filename. to_str( ) ) ) ;
929
- }
930
- }
950
+ return args;
931
951
}
952
+
932
953
//
933
954
// Local Variables:
934
955
// mode: rust
0 commit comments