@@ -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,23 @@ pub fn each_linked_rlib(
230
230
} ) ;
231
231
}
232
232
}
233
- }
234
-
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
- _ => { }
233
+ if info. dependency_formats . is_empty ( ) {
234
+ return Err ( errors:: LinkRlibError :: MissingFormat ) ;
249
235
}
250
- }
251
- let Some ( fmts) = fmts else {
252
- return Err ( errors:: LinkRlibError :: MissingFormat ) ;
236
+ & info. dependency_formats [ 0 ] . 1
237
+ } else {
238
+ let fmts = info
239
+ . dependency_formats
240
+ . iter ( )
241
+ . find_map ( |& ( ty, ref list) | if Some ( ty) == crate_type { Some ( list) } else { None } ) ;
242
+
243
+ let Some ( fmts) = fmts else {
244
+ return Err ( errors:: LinkRlibError :: MissingFormat ) ;
245
+ } ;
246
+
247
+ fmts
253
248
} ;
249
+
254
250
for & cnum in crates {
255
251
match fmts. get ( cnum. as_usize ( ) - 1 ) {
256
252
Some ( & Linkage :: NotLinked | & Linkage :: Dynamic | & Linkage :: IncludedFromDylib ) => continue ,
@@ -516,64 +512,71 @@ fn link_staticlib<'a>(
516
512
) ?;
517
513
let mut all_native_libs = vec ! [ ] ;
518
514
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
- } ) ;
515
+ let res = each_linked_rlib (
516
+ & codegen_results. crate_info ,
517
+ Some ( CrateType :: Staticlib ) ,
518
+ & mut |cnum, path| {
519
+ let name = codegen_results. crate_info . crate_name [ & cnum] ;
520
+ let native_libs = & codegen_results. crate_info . native_libraries [ & cnum] ;
521
+
522
+ // Here when we include the rlib into our staticlib we need to make a
523
+ // decision whether to include the extra object files along the way.
524
+ // These extra object files come from statically included native
525
+ // libraries, but they may be cfg'd away with #[link(cfg(..))].
526
+ //
527
+ // This unstable feature, though, only needs liblibc to work. The only
528
+ // use case there is where musl is statically included in liblibc.rlib,
529
+ // so if we don't want the included version we just need to skip it. As
530
+ // a result the logic here is that if *any* linked library is cfg'd away
531
+ // we just skip all object files.
532
+ //
533
+ // Clearly this is not sufficient for a general purpose feature, and
534
+ // we'd want to read from the library's metadata to determine which
535
+ // object files come from where and selectively skip them.
536
+ let skip_object_files = native_libs. iter ( ) . any ( |lib| {
537
+ matches ! ( lib. kind, NativeLibKind :: Static { bundle: None | Some ( true ) , .. } )
538
+ && !relevant_lib ( sess, lib)
539
+ } ) ;
541
540
542
- let lto = are_upstream_rust_objects_already_included ( sess)
543
- && !ignored_for_lto ( sess, & codegen_results. crate_info , cnum) ;
541
+ let lto = are_upstream_rust_objects_already_included ( sess)
542
+ && !ignored_for_lto ( sess, & codegen_results. crate_info , cnum) ;
544
543
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 ( ) ;
544
+ // Ignoring obj file starting with the crate name
545
+ // as simple comparison is not enough - there
546
+ // might be also an extra name suffix
547
+ let obj_start = name. as_str ( ) . to_owned ( ) ;
549
548
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
- }
549
+ ab. add_archive (
550
+ path,
551
+ Box :: new ( move |fname : & str | {
552
+ // Ignore metadata files, no matter the name.
553
+ if fname == METADATA_FILENAME {
554
+ return true ;
555
+ }
557
556
558
- // Don't include Rust objects if LTO is enabled
559
- if lto && looks_like_rust_object_file ( fname) {
560
- return true ;
561
- }
557
+ // Don't include Rust objects if LTO is enabled
558
+ if lto && looks_like_rust_object_file ( fname) {
559
+ return true ;
560
+ }
562
561
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
- }
562
+ // Otherwise if this is *not* a rust object and we're skipping
563
+ // objects then skip this file
564
+ if skip_object_files
565
+ && ( !fname. starts_with ( & obj_start) || !fname. ends_with ( ".o" ) )
566
+ {
567
+ return true ;
568
+ }
568
569
569
- // ok, don't skip this
570
- false
571
- } ) ,
572
- )
573
- . unwrap ( ) ;
570
+ // ok, don't skip this
571
+ false
572
+ } ) ,
573
+ )
574
+ . unwrap ( ) ;
574
575
575
- all_native_libs. extend ( codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) . cloned ( ) ) ;
576
- } ) ;
576
+ all_native_libs
577
+ . extend ( codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) . cloned ( ) ) ;
578
+ } ,
579
+ ) ;
577
580
if let Err ( e) = res {
578
581
sess. emit_fatal ( e) ;
579
582
}
@@ -1354,7 +1357,8 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
1354
1357
if !lib_args. is_empty ( ) {
1355
1358
sess. emit_note ( errors:: StaticLibraryNativeArtifacts ) ;
1356
1359
// Prefix for greppability
1357
- sess. emit_note ( errors:: NativeStaticLibs { arguments : lib_args. join ( " " ) } ) ;
1360
+ // Note: This must not be translated as tools are allowed to depend on this exact string.
1361
+ sess. note_without_error ( & format ! ( "native-static-libs: {}" , & lib_args. join( " " ) ) ) ;
1358
1362
}
1359
1363
}
1360
1364
0 commit comments