@@ -112,26 +112,51 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
112112 return Vec :: new ( ) ;
113113 }
114114
115- match ty {
116- // If the global prefer_dynamic switch is turned off, first attempt
117- // static linkage (this can fail).
118- config:: CrateTypeExecutable if !sess. opts . cg . prefer_dynamic => {
119- if let Some ( v) = attempt_static ( tcx) {
120- return v;
121- }
122- }
115+ let preferred_linkage = match ty {
116+ // cdylibs must have all static dependencies.
117+ config:: CrateTypeCdylib => Linkage :: Static ,
118+
119+ // Generating a dylib without `-C prefer-dynamic` means that we're going
120+ // to try to eagerly statically link all dependencies. This is normally
121+ // done for end-product dylibs, not intermediate products.
122+ config:: CrateTypeDylib if !sess. opts . cg . prefer_dynamic => Linkage :: Static ,
123+ config:: CrateTypeDylib => Linkage :: Dynamic ,
124+
125+ // If the global prefer_dynamic switch is turned off, or the final
126+ // executable will be statically linked, prefer static crate linkage.
127+ config:: CrateTypeExecutable if !sess. opts . cg . prefer_dynamic ||
128+ sess. crt_static ( ) => Linkage :: Static ,
129+ config:: CrateTypeExecutable => Linkage :: Dynamic ,
130+
131+ // proc-macro crates are required to be dylibs, and they're currently
132+ // required to link to libsyntax as well.
133+ config:: CrateTypeProcMacro => Linkage :: Dynamic ,
123134
124135 // No linkage happens with rlibs, we just needed the metadata (which we
125136 // got long ago), so don't bother with anything.
126- config:: CrateTypeRlib => return Vec :: new ( ) ,
127-
128- // Staticlibs and cdylibs must have all static dependencies. If any fail
129- // to be found, we generate some nice pretty errors.
130- config:: CrateTypeStaticlib |
131- config:: CrateTypeCdylib => {
132- if let Some ( v) = attempt_static ( tcx) {
133- return v;
134- }
137+ config:: CrateTypeRlib => Linkage :: NotLinked ,
138+
139+ // staticlibs must have all static dependencies.
140+ config:: CrateTypeStaticlib => Linkage :: Static ,
141+ } ;
142+
143+ if preferred_linkage == Linkage :: NotLinked {
144+ // If the crate is not linked, there are no link-time dependencies.
145+ return Vec :: new ( ) ;
146+ }
147+
148+ if preferred_linkage == Linkage :: Static {
149+ // Attempt static linkage first. For dylibs and executables, we may be
150+ // able to retry below with dynamic linkage.
151+ if let Some ( v) = attempt_static ( tcx) {
152+ return v;
153+ }
154+
155+ // Staticlibs, cdylibs, and static executables must have all static
156+ // dependencies. If any are not found, generate some nice pretty errors.
157+ if ty == config:: CrateTypeCdylib || ty == config:: CrateTypeStaticlib ||
158+ ( ty == config:: CrateTypeExecutable && sess. crt_static ( ) &&
159+ !sess. target . target . options . crt_static_allows_dylibs ) {
135160 for & cnum in tcx. crates ( ) . iter ( ) {
136161 if tcx. dep_kind ( cnum) . macros_only ( ) { continue }
137162 let src = tcx. used_crate_source ( cnum) ;
@@ -141,23 +166,6 @@ fn calculate_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
141166 }
142167 return Vec :: new ( ) ;
143168 }
144-
145- // Generating a dylib without `-C prefer-dynamic` means that we're going
146- // to try to eagerly statically link all dependencies. This is normally
147- // done for end-product dylibs, not intermediate products.
148- config:: CrateTypeDylib if !sess. opts . cg . prefer_dynamic => {
149- if let Some ( v) = attempt_static ( tcx) {
150- return v;
151- }
152- }
153-
154- // Everything else falls through below. This will happen either with the
155- // `-C prefer-dynamic` or because we're a proc-macro crate. Note that
156- // proc-macro crates are required to be dylibs, and they're currently
157- // required to link to libsyntax as well.
158- config:: CrateTypeExecutable |
159- config:: CrateTypeDylib |
160- config:: CrateTypeProcMacro => { } ,
161169 }
162170
163171 let mut formats = FxHashMap ( ) ;
0 commit comments