@@ -389,25 +389,39 @@ pub fn link_binary(sess: &Session,
389
389
outputs : & OutputFilenames ,
390
390
crate_name : & str ) -> Vec < PathBuf > {
391
391
let mut out_filenames = Vec :: new ( ) ;
392
- for & crate_type in sess. crate_types . borrow ( ) . iter ( ) {
392
+ if sess. opts . output_types . contains ( & config:: OutputTypeExe ) {
393
+ for & crate_type in sess. crate_types . borrow ( ) . iter ( ) {
394
+ if invalid_output_for_target ( sess, crate_type) {
395
+ sess. bug ( & format ! ( "invalid output type `{:?}` for target os `{}`" ,
396
+ crate_type, sess. opts. target_triple) ) ;
397
+ }
398
+ let out_file = link_binary_output ( sess, trans, crate_type, outputs,
399
+ crate_name, None ) ;
400
+ out_filenames. push ( out_file) ;
401
+ }
402
+
403
+ // Remove the temporary object file and metadata if we aren't saving temps
404
+ if !sess. opts . cg . save_temps {
405
+ let obj_filename = outputs. temp_path ( OutputTypeObject ) ;
406
+ if !sess. opts . output_types . contains ( & OutputTypeObject ) {
407
+ remove ( sess, & obj_filename) ;
408
+ }
409
+ remove ( sess, & obj_filename. with_extension ( "metadata.o" ) ) ;
410
+ }
411
+ }
412
+
413
+ // Attempt to output an rlib with just metadata, if that was requested.
414
+ if sess. opts . output_types . contains ( & config:: OutputTypeRlibMeta ) {
415
+ let crate_type = config:: CrateTypeRlib ;
393
416
if invalid_output_for_target ( sess, crate_type) {
394
417
sess. bug ( & format ! ( "invalid output type `{:?}` for target os `{}`" ,
395
- crate_type, sess. opts. target_triple) ) ;
418
+ crate_type, sess. opts. target_triple) ) ;
396
419
}
397
420
let out_file = link_binary_output ( sess, trans, crate_type, outputs,
398
- crate_name) ;
421
+ crate_name, Some ( config :: OutputTypeRlibMeta ) ) ;
399
422
out_filenames. push ( out_file) ;
400
423
}
401
424
402
- // Remove the temporary object file and metadata if we aren't saving temps
403
- if !sess. opts . cg . save_temps {
404
- let obj_filename = outputs. temp_path ( OutputTypeObject ) ;
405
- if !sess. opts . output_types . contains ( & OutputTypeObject ) {
406
- remove ( sess, & obj_filename) ;
407
- }
408
- remove ( sess, & obj_filename. with_extension ( "metadata.o" ) ) ;
409
- }
410
-
411
425
out_filenames
412
426
}
413
427
@@ -449,12 +463,18 @@ fn is_writeable(p: &Path) -> bool {
449
463
450
464
pub fn filename_for_input ( sess : & Session ,
451
465
crate_type : config:: CrateType ,
466
+ output_type : config:: OutputType ,
452
467
name : & str ,
453
468
out_filename : & Path ) -> PathBuf {
454
469
let libname = format ! ( "{}{}" , name, sess. opts. cg. extra_filename) ;
455
470
match crate_type {
456
471
config:: CrateTypeRlib => {
457
- out_filename. with_file_name ( & format ! ( "lib{}.rlib" , libname) )
472
+ let suffix = if output_type == config:: OutputTypeRlibMeta {
473
+ ".rmeta"
474
+ } else {
475
+ ""
476
+ } ;
477
+ out_filename. with_file_name ( & format ! ( "lib{}{}.rlib" , libname, suffix) )
458
478
}
459
479
config:: CrateTypeDylib => {
460
480
let ( prefix, suffix) = ( & sess. target . target . options . dll_prefix ,
@@ -482,13 +502,16 @@ fn link_binary_output(sess: &Session,
482
502
trans : & CrateTranslation ,
483
503
crate_type : config:: CrateType ,
484
504
outputs : & OutputFilenames ,
485
- crate_name : & str ) -> PathBuf {
505
+ crate_name : & str ,
506
+ custom_rlib_emission : Option < config:: OutputType > )
507
+ -> PathBuf {
486
508
let obj_filename = outputs. temp_path ( OutputTypeObject ) ;
487
509
let out_filename = match outputs. single_output_file {
488
510
Some ( ref file) => file. clone ( ) ,
489
511
None => {
490
- let out_filename = outputs. path ( OutputTypeExe ) ;
491
- filename_for_input ( sess, crate_type, crate_name, & out_filename)
512
+ let output_type = custom_rlib_emission. unwrap_or ( OutputTypeExe ) ;
513
+ let out_filename = outputs. path ( output_type) ;
514
+ filename_for_input ( sess, crate_type, output_type, crate_name, & out_filename)
492
515
}
493
516
} ;
494
517
@@ -511,7 +534,12 @@ fn link_binary_output(sess: &Session,
511
534
512
535
match crate_type {
513
536
config:: CrateTypeRlib => {
514
- link_rlib ( sess, Some ( trans) , & obj_filename, & out_filename) . build ( ) ;
537
+ let obj_filename = if custom_rlib_emission. is_some ( ) {
538
+ None
539
+ } else {
540
+ Some ( & * obj_filename)
541
+ } ;
542
+ link_rlib ( sess, Some ( trans) , obj_filename, & out_filename) . build ( ) ;
515
543
}
516
544
config:: CrateTypeStaticlib => {
517
545
link_staticlib ( sess, & obj_filename, & out_filename) ;
@@ -544,7 +572,7 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
544
572
// native libraries and inserting all of the contents into this archive.
545
573
fn link_rlib < ' a > ( sess : & ' a Session ,
546
574
trans : Option < & CrateTranslation > , // None == no metadata/bytecode
547
- obj_filename : & Path ,
575
+ obj_filename : Option < & Path > ,
548
576
out_filename : & Path ) -> ArchiveBuilder < ' a > {
549
577
info ! ( "preparing rlib from {:?} to {:?}" , obj_filename, out_filename) ;
550
578
let handler = & sess. diagnostic ( ) . handler ;
@@ -557,7 +585,7 @@ fn link_rlib<'a>(sess: &'a Session,
557
585
ar_prog : get_ar_prog ( sess) ,
558
586
} ;
559
587
let mut ab = ArchiveBuilder :: create ( config) ;
560
- ab. add_file ( obj_filename ) . unwrap ( ) ;
588
+ obj_filename . map ( |file| ab. add_file ( file ) . unwrap ( ) ) ;
561
589
562
590
for & ( ref l, kind) in sess. cstore . get_used_libraries ( ) . borrow ( ) . iter ( ) {
563
591
match kind {
@@ -619,6 +647,13 @@ fn link_rlib<'a>(sess: &'a Session,
619
647
ab. add_file ( & metadata) . unwrap ( ) ;
620
648
remove ( sess, & metadata) ;
621
649
650
+ // Nothing else to add if we have no code.
651
+ let obj_filename = if let Some ( file) = obj_filename {
652
+ file
653
+ } else {
654
+ return ab;
655
+ } ;
656
+
622
657
// For LTO purposes, the bytecode of this library is also inserted
623
658
// into the archive. If codegen_units > 1, we insert each of the
624
659
// bitcode files.
@@ -734,7 +769,7 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
734
769
// link in the metadata object file (and also don't prepare the archive with a
735
770
// metadata file).
736
771
fn link_staticlib ( sess : & Session , obj_filename : & Path , out_filename : & Path ) {
737
- let ab = link_rlib ( sess, None , obj_filename, out_filename) ;
772
+ let ab = link_rlib ( sess, None , Some ( obj_filename) , out_filename) ;
738
773
let mut ab = match sess. target . target . options . is_like_osx {
739
774
true => ab. build ( ) . extend ( ) ,
740
775
false => ab,
0 commit comments