@@ -57,7 +57,7 @@ use crate::errors::{
5757 RequiredPanicStrategy , RlibRequired , RustcLibRequired , TwoPanicRuntimes ,
5858} ;
5959
60- use rustc_data_structures:: fx:: FxHashMap ;
60+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
6161use rustc_hir:: def_id:: CrateNum ;
6262use rustc_middle:: middle:: dependency_format:: { Dependencies , DependencyList , Linkage } ;
6363use rustc_middle:: ty:: TyCtxt ;
@@ -156,25 +156,46 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
156156 Linkage :: Dynamic | Linkage :: IncludedFromDylib => { }
157157 }
158158
159+ let all_dylibs = || {
160+ tcx. crates ( ( ) ) . iter ( ) . filter ( |& & cnum| {
161+ !tcx. dep_kind ( cnum) . macros_only ( ) && tcx. used_crate_source ( cnum) . dylib . is_some ( )
162+ } )
163+ } ;
164+
165+ let mut upstream_in_dylibs = FxHashSet :: default ( ) ;
166+
167+ if sess. opts . unstable_opts . prefer_deps_of_dynamic || tcx. features ( ) . rustc_private {
168+ // Find all libraries statically linked to upstream dylibs.
169+ for & cnum in all_dylibs ( ) {
170+ let deps = tcx. dylib_dependency_formats ( cnum) ;
171+ for & ( depnum, style) in deps. iter ( ) {
172+ if let RequireStatic = style {
173+ upstream_in_dylibs. insert ( depnum) ;
174+ }
175+ }
176+ }
177+ }
178+
159179 let mut formats = FxHashMap :: default ( ) ;
160180
161181 // Sweep all crates for found dylibs. Add all dylibs, as well as their
162182 // dependencies, ensuring there are no conflicts. The only valid case for a
163183 // dependency to be relied upon twice is for both cases to rely on a dylib.
164- for & cnum in tcx. crates ( ( ) ) . iter ( ) {
165- if tcx. dep_kind ( cnum) . macros_only ( ) {
184+ for & cnum in all_dylibs ( ) {
185+ if upstream_in_dylibs. contains ( & cnum) {
186+ info ! ( "skipping dylib: {}" , tcx. crate_name( cnum) ) ;
187+ // If this dylib is also available statically linked to another dylib
188+ // we try to use that instead.
166189 continue ;
167190 }
191+
168192 let name = tcx. crate_name ( cnum) ;
169- let src = tcx. used_crate_source ( cnum) ;
170- if src. dylib . is_some ( ) {
171- info ! ( "adding dylib: {}" , name) ;
172- add_library ( tcx, cnum, RequireDynamic , & mut formats) ;
173- let deps = tcx. dylib_dependency_formats ( cnum) ;
174- for & ( depnum, style) in deps. iter ( ) {
175- info ! ( "adding {:?}: {}" , style, tcx. crate_name( depnum) ) ;
176- add_library ( tcx, depnum, style, & mut formats) ;
177- }
193+ info ! ( "adding dylib: {}" , name) ;
194+ add_library ( tcx, cnum, RequireDynamic , & mut formats) ;
195+ let deps = tcx. dylib_dependency_formats ( cnum) ;
196+ for & ( depnum, style) in deps. iter ( ) {
197+ info ! ( "adding {:?}: {}" , style, tcx. crate_name( depnum) ) ;
198+ add_library ( tcx, depnum, style, & mut formats) ;
178199 }
179200 }
180201
0 commit comments