@@ -11,7 +11,7 @@ use rustc_metadata::find_native_static_library;
1111use rustc_metadata:: fs:: { emit_wrapper_file, METADATA_FILENAME } ;
1212use rustc_middle:: middle:: dependency_format:: Linkage ;
1313use 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 } ;
1515use rustc_session:: config:: { OutputFilenames , OutputType , PrintRequest , SplitDwarfKind } ;
1616use rustc_session:: cstore:: DllImport ;
1717use rustc_session:: output:: { check_file_is_writeable, invalid_output_for_target, out_filename} ;
@@ -208,16 +208,16 @@ pub fn link_binary<'a>(
208208 Ok ( ( ) )
209209}
210210
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.
211213pub fn each_linked_rlib (
212- sess : & Session ,
213214 info : & CrateInfo ,
215+ crate_type : Option < CrateType > ,
214216 f : & mut dyn FnMut ( CrateNum , & Path ) ,
215217) -> Result < ( ) , errors:: LinkRlibError > {
216218 let crates = info. used_crates . iter ( ) ;
217- let mut fmts = None ;
218219
219- let lto_active = matches ! ( sess. lto( ) , Lto :: Fat | Lto :: Thin ) ;
220- if lto_active {
220+ let fmts = if crate_type. is_none ( ) {
221221 for combination in info. dependency_formats . iter ( ) . combinations ( 2 ) {
222222 let ( ty1, list1) = & combination[ 0 ] ;
223223 let ( ty2, list2) = & combination[ 1 ] ;
@@ -230,27 +230,23 @@ pub fn each_linked_rlib(
230230 } ) ;
231231 }
232232 }
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 ) ;
249235 }
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
253248 } ;
249+
254250 for & cnum in crates {
255251 match fmts. get ( cnum. as_usize ( ) - 1 ) {
256252 Some ( & Linkage :: NotLinked | & Linkage :: Dynamic | & Linkage :: IncludedFromDylib ) => continue ,
@@ -516,64 +512,71 @@ fn link_staticlib<'a>(
516512 ) ?;
517513 let mut all_native_libs = vec ! [ ] ;
518514
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+ } ) ;
541540
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) ;
544543
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 ( ) ;
549548
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+ }
557556
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+ }
562561
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+ }
568569
569- // ok, don't skip this
570- false
571- } ) ,
572- )
573- . unwrap ( ) ;
570+ // ok, don't skip this
571+ false
572+ } ) ,
573+ )
574+ . unwrap ( ) ;
574575
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+ ) ;
577580 if let Err ( e) = res {
578581 sess. emit_fatal ( e) ;
579582 }
@@ -1354,7 +1357,8 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
13541357 if !lib_args. is_empty ( ) {
13551358 sess. emit_note ( errors:: StaticLibraryNativeArtifacts ) ;
13561359 // 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( " " ) ) ) ;
13581362 }
13591363}
13601364
0 commit comments