@@ -57,7 +57,7 @@ use crate::errors::{
57
57
NonStaticCrateDep , 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 ;
@@ -158,25 +158,49 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
158
158
Linkage :: Dynamic | Linkage :: IncludedFromDylib => { }
159
159
}
160
160
161
+ let all_dylibs = || {
162
+ tcx. crates ( ( ) ) . iter ( ) . filter ( |& & cnum| {
163
+ !tcx. dep_kind ( cnum) . macros_only ( ) && tcx. used_crate_source ( cnum) . dylib . is_some ( )
164
+ } )
165
+ } ;
166
+
167
+ let mut upstream_in_dylibs = FxHashSet :: default ( ) ;
168
+
169
+ if tcx. features ( ) . rustc_private {
170
+ // We need this to prevent users of `rustc_driver` from linking to dynamically to `std`
171
+ // which does not work as `std` is also statically linked into `rustc_driver`.
172
+
173
+ // Find all libraries statically linked to upstream dylibs.
174
+ for & cnum in all_dylibs ( ) {
175
+ let deps = tcx. dylib_dependency_formats ( cnum) ;
176
+ for & ( depnum, style) in deps. iter ( ) {
177
+ if let RequireStatic = style {
178
+ upstream_in_dylibs. insert ( depnum) ;
179
+ }
180
+ }
181
+ }
182
+ }
183
+
161
184
let mut formats = FxHashMap :: default ( ) ;
162
185
163
186
// Sweep all crates for found dylibs. Add all dylibs, as well as their
164
187
// dependencies, ensuring there are no conflicts. The only valid case for a
165
188
// dependency to be relied upon twice is for both cases to rely on a dylib.
166
- for & cnum in tcx. crates ( ( ) ) . iter ( ) {
167
- if tcx. dep_kind ( cnum) . macros_only ( ) {
189
+ for & cnum in all_dylibs ( ) {
190
+ if upstream_in_dylibs. contains ( & cnum) {
191
+ info ! ( "skipping dylib: {}" , tcx. crate_name( cnum) ) ;
192
+ // If this dylib is also available statically linked to another dylib
193
+ // we try to use that instead.
168
194
continue ;
169
195
}
196
+
170
197
let name = tcx. crate_name ( cnum) ;
171
- let src = tcx. used_crate_source ( cnum) ;
172
- if src. dylib . is_some ( ) {
173
- info ! ( "adding dylib: {}" , name) ;
174
- add_library ( tcx, cnum, RequireDynamic , & mut formats, & mut unavailable_as_static) ;
175
- let deps = tcx. dylib_dependency_formats ( cnum) ;
176
- for & ( depnum, style) in deps. iter ( ) {
177
- info ! ( "adding {:?}: {}" , style, tcx. crate_name( depnum) ) ;
178
- add_library ( tcx, depnum, style, & mut formats, & mut unavailable_as_static) ;
179
- }
198
+ info ! ( "adding dylib: {}" , name) ;
199
+ add_library ( tcx, cnum, RequireDynamic , & mut formats, & mut unavailable_as_static) ;
200
+ let deps = tcx. dylib_dependency_formats ( cnum) ;
201
+ for & ( depnum, style) in deps. iter ( ) {
202
+ info ! ( "adding {:?}: {}" , style, tcx. crate_name( depnum) ) ;
203
+ add_library ( tcx, depnum, style, & mut formats, & mut unavailable_as_static) ;
180
204
}
181
205
}
182
206
0 commit comments