@@ -11,7 +11,7 @@ use rustc_metadata::find_native_static_library;
11
11
use rustc_metadata:: fs:: { emit_wrapper_file, METADATA_FILENAME } ;
12
12
use rustc_middle:: middle:: dependency_format:: Linkage ;
13
13
use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
14
- use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , LdImpl , Lto , Strip } ;
14
+ use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , LdImpl , Strip } ;
15
15
use rustc_session:: config:: { OutputFilenames , OutputType , PrintRequest , SplitDwarfKind } ;
16
16
use rustc_session:: cstore:: DllImport ;
17
17
use rustc_session:: output:: { check_file_is_writeable, invalid_output_for_target, out_filename} ;
@@ -208,16 +208,16 @@ pub fn link_binary<'a>(
208
208
Ok ( ( ) )
209
209
}
210
210
211
+ // Crate type is not passed when calculating the dylibs to include for LTO. In that case all
212
+ // crate types must use the same dependency formats.
211
213
pub fn each_linked_rlib (
212
- sess : & Session ,
213
214
info : & CrateInfo ,
215
+ crate_type : Option < CrateType > ,
214
216
f : & mut dyn FnMut ( CrateNum , & Path ) ,
215
217
) -> Result < ( ) , errors:: LinkRlibError > {
216
218
let crates = info. used_crates . iter ( ) ;
217
- let mut fmts = None ;
218
219
219
- let lto_active = matches ! ( sess. lto( ) , Lto :: Fat | Lto :: Thin ) ;
220
- if lto_active {
220
+ let fmts = if crate_type. is_none ( ) {
221
221
for combination in info. dependency_formats . iter ( ) . combinations ( 2 ) {
222
222
let ( ty1, list1) = & combination[ 0 ] ;
223
223
let ( ty2, list2) = & combination[ 1 ] ;
@@ -230,27 +230,20 @@ pub fn each_linked_rlib(
230
230
} ) ;
231
231
}
232
232
}
233
- }
233
+ & info. dependency_formats [ 0 ] . 1
234
+ } else {
235
+ let fmts = info
236
+ . dependency_formats
237
+ . iter ( )
238
+ . find_map ( |& ( ty, ref list) | if Some ( ty) == crate_type { Some ( list) } else { None } ) ;
234
239
235
- for ( ty, list) in info. dependency_formats . iter ( ) {
236
- match ty {
237
- CrateType :: Executable
238
- | CrateType :: Staticlib
239
- | CrateType :: Cdylib
240
- | CrateType :: ProcMacro => {
241
- fmts = Some ( list) ;
242
- break ;
243
- }
244
- CrateType :: Dylib if lto_active => {
245
- fmts = Some ( list) ;
246
- break ;
247
- }
248
- _ => { }
249
- }
250
- }
251
- let Some ( fmts) = fmts else {
252
- return Err ( errors:: LinkRlibError :: MissingFormat ) ;
240
+ let Some ( fmts) = fmts else {
241
+ return Err ( errors:: LinkRlibError :: MissingFormat ) ;
242
+ } ;
243
+
244
+ fmts
253
245
} ;
246
+
254
247
for & cnum in crates {
255
248
match fmts. get ( cnum. as_usize ( ) - 1 ) {
256
249
Some ( & Linkage :: NotLinked | & Linkage :: Dynamic | & Linkage :: IncludedFromDylib ) => continue ,
@@ -516,64 +509,71 @@ fn link_staticlib<'a>(
516
509
) ?;
517
510
let mut all_native_libs = vec ! [ ] ;
518
511
519
- let res = each_linked_rlib ( sess, & codegen_results. crate_info , & mut |cnum, path| {
520
- let name = codegen_results. crate_info . crate_name [ & cnum] ;
521
- let native_libs = & codegen_results. crate_info . native_libraries [ & cnum] ;
522
-
523
- // Here when we include the rlib into our staticlib we need to make a
524
- // decision whether to include the extra object files along the way.
525
- // These extra object files come from statically included native
526
- // libraries, but they may be cfg'd away with #[link(cfg(..))].
527
- //
528
- // This unstable feature, though, only needs liblibc to work. The only
529
- // use case there is where musl is statically included in liblibc.rlib,
530
- // so if we don't want the included version we just need to skip it. As
531
- // a result the logic here is that if *any* linked library is cfg'd away
532
- // we just skip all object files.
533
- //
534
- // Clearly this is not sufficient for a general purpose feature, and
535
- // we'd want to read from the library's metadata to determine which
536
- // object files come from where and selectively skip them.
537
- let skip_object_files = native_libs. iter ( ) . any ( |lib| {
538
- matches ! ( lib. kind, NativeLibKind :: Static { bundle: None | Some ( true ) , .. } )
539
- && !relevant_lib ( sess, lib)
540
- } ) ;
512
+ let res = each_linked_rlib (
513
+ & codegen_results. crate_info ,
514
+ Some ( CrateType :: Staticlib ) ,
515
+ & mut |cnum, path| {
516
+ let name = codegen_results. crate_info . crate_name [ & cnum] ;
517
+ let native_libs = & codegen_results. crate_info . native_libraries [ & cnum] ;
518
+
519
+ // Here when we include the rlib into our staticlib we need to make a
520
+ // decision whether to include the extra object files along the way.
521
+ // These extra object files come from statically included native
522
+ // libraries, but they may be cfg'd away with #[link(cfg(..))].
523
+ //
524
+ // This unstable feature, though, only needs liblibc to work. The only
525
+ // use case there is where musl is statically included in liblibc.rlib,
526
+ // so if we don't want the included version we just need to skip it. As
527
+ // a result the logic here is that if *any* linked library is cfg'd away
528
+ // we just skip all object files.
529
+ //
530
+ // Clearly this is not sufficient for a general purpose feature, and
531
+ // we'd want to read from the library's metadata to determine which
532
+ // object files come from where and selectively skip them.
533
+ let skip_object_files = native_libs. iter ( ) . any ( |lib| {
534
+ matches ! ( lib. kind, NativeLibKind :: Static { bundle: None | Some ( true ) , .. } )
535
+ && !relevant_lib ( sess, lib)
536
+ } ) ;
541
537
542
- let lto = are_upstream_rust_objects_already_included ( sess)
543
- && !ignored_for_lto ( sess, & codegen_results. crate_info , cnum) ;
538
+ let lto = are_upstream_rust_objects_already_included ( sess)
539
+ && !ignored_for_lto ( sess, & codegen_results. crate_info , cnum) ;
544
540
545
- // Ignoring obj file starting with the crate name
546
- // as simple comparison is not enough - there
547
- // might be also an extra name suffix
548
- let obj_start = name. as_str ( ) . to_owned ( ) ;
541
+ // Ignoring obj file starting with the crate name
542
+ // as simple comparison is not enough - there
543
+ // might be also an extra name suffix
544
+ let obj_start = name. as_str ( ) . to_owned ( ) ;
549
545
550
- ab. add_archive (
551
- path,
552
- Box :: new ( move |fname : & str | {
553
- // Ignore metadata files, no matter the name.
554
- if fname == METADATA_FILENAME {
555
- return true ;
556
- }
546
+ ab. add_archive (
547
+ path,
548
+ Box :: new ( move |fname : & str | {
549
+ // Ignore metadata files, no matter the name.
550
+ if fname == METADATA_FILENAME {
551
+ return true ;
552
+ }
557
553
558
- // Don't include Rust objects if LTO is enabled
559
- if lto && looks_like_rust_object_file ( fname) {
560
- return true ;
561
- }
554
+ // Don't include Rust objects if LTO is enabled
555
+ if lto && looks_like_rust_object_file ( fname) {
556
+ return true ;
557
+ }
562
558
563
- // Otherwise if this is *not* a rust object and we're skipping
564
- // objects then skip this file
565
- if skip_object_files && ( !fname. starts_with ( & obj_start) || !fname. ends_with ( ".o" ) ) {
566
- return true ;
567
- }
559
+ // Otherwise if this is *not* a rust object and we're skipping
560
+ // objects then skip this file
561
+ if skip_object_files
562
+ && ( !fname. starts_with ( & obj_start) || !fname. ends_with ( ".o" ) )
563
+ {
564
+ return true ;
565
+ }
568
566
569
- // ok, don't skip this
570
- false
571
- } ) ,
572
- )
573
- . unwrap ( ) ;
567
+ // ok, don't skip this
568
+ false
569
+ } ) ,
570
+ )
571
+ . unwrap ( ) ;
574
572
575
- all_native_libs. extend ( codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) . cloned ( ) ) ;
576
- } ) ;
573
+ all_native_libs
574
+ . extend ( codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) . cloned ( ) ) ;
575
+ } ,
576
+ ) ;
577
577
if let Err ( e) = res {
578
578
sess. emit_fatal ( e) ;
579
579
}
0 commit comments