@@ -57,7 +57,7 @@ use crate::errors::{
57
57
RequiredPanicStrategy , RlibRequired , RustcLibRequired , TwoPanicRuntimes ,
58
58
} ;
59
59
60
- use rustc_data_structures:: fx:: FxHashMap ;
60
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
61
61
use rustc_hir:: def_id:: CrateNum ;
62
62
use rustc_middle:: middle:: dependency_format:: { Dependencies , DependencyList , Linkage } ;
63
63
use rustc_middle:: ty:: TyCtxt ;
@@ -156,25 +156,46 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
156
156
Linkage :: Dynamic | Linkage :: IncludedFromDylib => { }
157
157
}
158
158
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 {
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
+
159
179
let mut formats = FxHashMap :: default ( ) ;
160
180
161
181
// Sweep all crates for found dylibs. Add all dylibs, as well as their
162
182
// dependencies, ensuring there are no conflicts. The only valid case for a
163
183
// 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.
166
189
continue ;
167
190
}
191
+
168
192
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) ;
178
199
}
179
200
}
180
201
0 commit comments