@@ -417,11 +417,10 @@ pub fn link_binary(sess: &Session,
417
417
418
418
// Remove the temporary object file and metadata if we aren't saving temps
419
419
if !sess. opts . cg . save_temps {
420
- let obj_filename = outputs. temp_path ( OutputTypeObject ) ;
421
- if !sess. opts . output_types . contains ( & OutputTypeObject ) {
422
- remove ( sess, & obj_filename) ;
420
+ for obj in object_filenames ( sess, outputs) {
421
+ remove ( sess, & obj) ;
423
422
}
424
- remove ( sess, & obj_filename . with_extension ( "metadata.o" ) ) ;
423
+ remove ( sess, & outputs . with_extension ( "metadata.o" ) ) ;
425
424
}
426
425
427
426
out_filenames
@@ -499,7 +498,7 @@ fn link_binary_output(sess: &Session,
499
498
crate_type : config:: CrateType ,
500
499
outputs : & OutputFilenames ,
501
500
crate_name : & str ) -> PathBuf {
502
- let obj_filename = outputs . temp_path ( OutputTypeObject ) ;
501
+ let objects = object_filenames ( sess , outputs ) ;
503
502
let out_filename = match outputs. single_output_file {
504
503
Some ( ref file) => file. clone ( ) ,
505
504
None => {
@@ -508,41 +507,41 @@ fn link_binary_output(sess: &Session,
508
507
}
509
508
} ;
510
509
511
- // Make sure the output and obj_filename are both writeable.
512
- // Mac, FreeBSD, and Windows system linkers check this already --
513
- // however, the Linux linker will happily overwrite a read-only file.
514
- // We should be consistent.
515
- let obj_is_writeable = is_writeable ( & obj_filename) ;
516
- let out_is_writeable = is_writeable ( & out_filename) ;
517
- if !out_is_writeable {
518
- sess. fatal ( & format ! ( "output file {} is not writeable -- check its \
519
- permissions.",
520
- out_filename. display( ) ) ) ;
521
- }
522
- else if !obj_is_writeable {
523
- sess. fatal ( & format ! ( "object file {} is not writeable -- check its \
524
- permissions.",
525
- obj_filename. display( ) ) ) ;
510
+ // Make sure files are writeable. Mac, FreeBSD, and Windows system linkers
511
+ // check this already -- however, the Linux linker will happily overwrite a
512
+ // read-only file. We should be consistent.
513
+ for file in objects. iter ( ) . chain ( Some ( & out_filename) ) {
514
+ if !is_writeable ( file) {
515
+ sess. fatal ( & format ! ( "output file {} is not writeable -- check its \
516
+ permissions", file. display( ) ) ) ;
517
+ }
526
518
}
527
519
528
520
match crate_type {
529
521
config:: CrateTypeRlib => {
530
- link_rlib ( sess, Some ( trans) , & obj_filename , & out_filename) . build ( ) ;
522
+ link_rlib ( sess, Some ( trans) , & objects , & out_filename) . build ( ) ;
531
523
}
532
524
config:: CrateTypeStaticlib => {
533
- link_staticlib ( sess, & obj_filename , & out_filename) ;
525
+ link_staticlib ( sess, & objects , & out_filename) ;
534
526
}
535
527
config:: CrateTypeExecutable => {
536
- link_natively ( sess, trans, false , & obj_filename , & out_filename) ;
528
+ link_natively ( sess, trans, false , & objects , & out_filename, outputs ) ;
537
529
}
538
530
config:: CrateTypeDylib => {
539
- link_natively ( sess, trans, true , & obj_filename , & out_filename) ;
531
+ link_natively ( sess, trans, true , & objects , & out_filename, outputs ) ;
540
532
}
541
533
}
542
534
543
535
out_filename
544
536
}
545
537
538
+ fn object_filenames ( sess : & Session , outputs : & OutputFilenames ) -> Vec < PathBuf > {
539
+ ( 0 ..sess. opts . cg . codegen_units ) . map ( |i| {
540
+ let ext = format ! ( "{}.o" , i) ;
541
+ outputs. temp_path ( OutputTypeObject ) . with_extension ( & ext)
542
+ } ) . collect ( )
543
+ }
544
+
546
545
fn archive_search_paths ( sess : & Session ) -> Vec < PathBuf > {
547
546
let mut search = Vec :: new ( ) ;
548
547
sess. target_filesearch ( PathKind :: Native ) . for_each_lib_search_path ( |path, _| {
@@ -560,9 +559,9 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
560
559
// native libraries and inserting all of the contents into this archive.
561
560
fn link_rlib < ' a > ( sess : & ' a Session ,
562
561
trans : Option < & CrateTranslation > , // None == no metadata/bytecode
563
- obj_filename : & Path ,
562
+ objects : & [ PathBuf ] ,
564
563
out_filename : & Path ) -> ArchiveBuilder < ' a > {
565
- info ! ( "preparing rlib from {:?} to {:?}" , obj_filename , out_filename) ;
564
+ info ! ( "preparing rlib from {:?} to {:?}" , objects , out_filename) ;
566
565
let handler = & sess. diagnostic ( ) . handler ;
567
566
let config = ArchiveConfig {
568
567
handler : handler,
@@ -574,7 +573,9 @@ fn link_rlib<'a>(sess: &'a Session,
574
573
command_path : command_path ( sess) ,
575
574
} ;
576
575
let mut ab = ArchiveBuilder :: create ( config) ;
577
- ab. add_file ( obj_filename) . unwrap ( ) ;
576
+ for obj in objects {
577
+ ab. add_file ( obj) . unwrap ( ) ;
578
+ }
578
579
579
580
for & ( ref l, kind) in sess. cstore . get_used_libraries ( ) . borrow ( ) . iter ( ) {
580
581
match kind {
@@ -600,7 +601,7 @@ fn link_rlib<'a>(sess: &'a Session,
600
601
// this is as follows:
601
602
//
602
603
// * When performing LTO, this archive will be modified to remove
603
- // obj_filename from above. The reason for this is described below.
604
+ // objects from above. The reason for this is described below.
604
605
//
605
606
// * When the system linker looks at an archive, it will attempt to
606
607
// determine the architecture of the archive in order to see whether its
@@ -639,15 +640,14 @@ fn link_rlib<'a>(sess: &'a Session,
639
640
// For LTO purposes, the bytecode of this library is also inserted
640
641
// into the archive. If codegen_units > 1, we insert each of the
641
642
// bitcode files.
642
- for i in 0 ..sess . opts . cg . codegen_units {
643
+ for obj in objects {
643
644
// Note that we make sure that the bytecode filename in the
644
645
// archive is never exactly 16 bytes long by adding a 16 byte
645
646
// extension to it. This is to work around a bug in LLDB that
646
647
// would cause it to crash if the name of a file in an archive
647
648
// was exactly 16 bytes.
648
- let bc_filename = obj_filename. with_extension ( & format ! ( "{}.bc" , i) ) ;
649
- let bc_deflated_filename = obj_filename. with_extension (
650
- & format ! ( "{}.bytecode.deflate" , i) ) ;
649
+ let bc_filename = obj. with_extension ( "bc" ) ;
650
+ let bc_deflated_filename = obj. with_extension ( "bytecode.deflate" ) ;
651
651
652
652
let mut bc_data = Vec :: new ( ) ;
653
653
match fs:: File :: open ( & bc_filename) . and_then ( |mut f| {
@@ -750,8 +750,8 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
750
750
// There's no need to include metadata in a static archive, so ensure to not
751
751
// link in the metadata object file (and also don't prepare the archive with a
752
752
// metadata file).
753
- fn link_staticlib ( sess : & Session , obj_filename : & Path , out_filename : & Path ) {
754
- let ab = link_rlib ( sess, None , obj_filename , out_filename) ;
753
+ fn link_staticlib ( sess : & Session , objects : & [ PathBuf ] , out_filename : & Path ) {
754
+ let ab = link_rlib ( sess, None , objects , out_filename) ;
755
755
let mut ab = match sess. target . target . options . is_like_osx {
756
756
true => ab. build ( ) . extend ( ) ,
757
757
false => ab,
@@ -806,8 +806,9 @@ fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
806
806
// This will invoke the system linker/cc to create the resulting file. This
807
807
// links to all upstream files as well.
808
808
fn link_natively ( sess : & Session , trans : & CrateTranslation , dylib : bool ,
809
- obj_filename : & Path , out_filename : & Path ) {
810
- info ! ( "preparing dylib? ({}) from {:?} to {:?}" , dylib, obj_filename,
809
+ objects : & [ PathBuf ] , out_filename : & Path ,
810
+ outputs : & OutputFilenames ) {
811
+ info ! ( "preparing dylib? ({}) from {:?} to {:?}" , dylib, objects,
811
812
out_filename) ;
812
813
let tmpdir = TempDir :: new ( "rustc" ) . ok ( ) . expect ( "needs a temp dir" ) ;
813
814
@@ -828,7 +829,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
828
829
Box :: new ( GnuLinker { cmd : & mut cmd, sess : & sess } ) as Box < Linker >
829
830
} ;
830
831
link_args ( & mut * linker, sess, dylib, tmpdir. path ( ) ,
831
- trans, obj_filename , out_filename) ;
832
+ trans, objects , out_filename, outputs ) ;
832
833
if !sess. target . target . options . no_compiler_rt {
833
834
linker. link_staticlib ( "compiler-rt" ) ;
834
835
}
@@ -884,8 +885,9 @@ fn link_args(cmd: &mut Linker,
884
885
dylib : bool ,
885
886
tmpdir : & Path ,
886
887
trans : & CrateTranslation ,
887
- obj_filename : & Path ,
888
- out_filename : & Path ) {
888
+ objects : & [ PathBuf ] ,
889
+ out_filename : & Path ,
890
+ outputs : & OutputFilenames ) {
889
891
890
892
// The default library location, we need this to find the runtime.
891
893
// The location of crates will be determined as needed.
@@ -895,7 +897,9 @@ fn link_args(cmd: &mut Linker,
895
897
let t = & sess. target . target ;
896
898
897
899
cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
898
- cmd. add_object ( obj_filename) ;
900
+ for obj in objects {
901
+ cmd. add_object ( obj) ;
902
+ }
899
903
cmd. output_filename ( out_filename) ;
900
904
901
905
// Stack growth requires statically linking a __morestack function. Note
@@ -922,7 +926,7 @@ fn link_args(cmd: &mut Linker,
922
926
// executable. This metadata is in a separate object file from the main
923
927
// object file, so we link that in here.
924
928
if dylib {
925
- cmd. add_object ( & obj_filename . with_extension ( "metadata.o" ) ) ;
929
+ cmd. add_object ( & outputs . with_extension ( "metadata.o" ) ) ;
926
930
}
927
931
928
932
// Try to strip as much out of the generated object by removing unused
0 commit comments