@@ -1803,15 +1803,16 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1803
1803
add_local_native_libraries ( cmd, sess, codegen_results) ;
1804
1804
}
1805
1805
1806
- // Rust libraries.
1806
+ // Upstream rust libraries and their nobundle static libraries
1807
1807
add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
1808
1808
1809
- // Native libraries linked with `#[link]` attributes at and `-l` command line options.
1809
+ // Upstream dymamic native libraries linked with `#[link]` attributes at and `-l`
1810
+ // command line options.
1810
1811
// If -Zlink-native-libraries=false is set, then the assumption is that an
1811
1812
// external build system already has the native dependencies defined, and it
1812
1813
// will provide them to the linker itself.
1813
1814
if sess. opts . debugging_opts . link_native_libraries {
1814
- add_upstream_native_libraries ( cmd, sess, codegen_results, crate_type ) ;
1815
+ add_upstream_native_libraries ( cmd, sess, codegen_results) ;
1815
1816
}
1816
1817
1817
1818
// Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
@@ -2033,7 +2034,7 @@ fn add_local_native_libraries(
2033
2034
}
2034
2035
}
2035
2036
2036
- /// # Rust Crate linking
2037
+ /// # Linking Rust crates and their nobundle static libraries
2037
2038
///
2038
2039
/// Rust crates are not considered at all when creating an rlib output. All dependencies will be
2039
2040
/// linked when producing the final output (instead of the intermediate rlib version).
@@ -2138,6 +2139,29 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
2138
2139
Linkage :: NotLinked | Linkage :: IncludedFromDylib => { }
2139
2140
Linkage :: Static => {
2140
2141
add_static_crate :: < B > ( cmd, sess, codegen_results, tmpdir, crate_type, cnum) ;
2142
+
2143
+ // Link static native libs with "-bundle" modifier only if the crate they originate from
2144
+ // is being linked statically to the current crate. If it's linked dynamically
2145
+ // or is an rlib already included via some other dylib crate, the symbols from
2146
+ // native libs will have already been included in that dylib.
2147
+ //
2148
+ // If -Zlink-native-libraries=false is set, then the assumption is that an
2149
+ // external build system already has the native dependencies defined, and it
2150
+ // will provide them to the linker itself.
2151
+ if sess. opts . debugging_opts . link_native_libraries {
2152
+ // Skip if this library is the same as the last.
2153
+ let mut last = None ;
2154
+ for lib in & codegen_results. crate_info . native_libraries [ & cnum] {
2155
+ if lib. name . is_some ( )
2156
+ && relevant_lib ( sess, lib)
2157
+ && matches ! ( lib. kind, NativeLibKind :: Static { bundle: Some ( false ) , .. } )
2158
+ && last != lib. name
2159
+ {
2160
+ cmd. link_staticlib ( lib. name . unwrap ( ) , lib. verbatim . unwrap_or ( false ) ) ;
2161
+ last = lib. name ;
2162
+ }
2163
+ }
2164
+ }
2141
2165
}
2142
2166
Linkage :: Dynamic => add_dynamic_crate ( cmd, sess, & src. dylib . as_ref ( ) . unwrap ( ) . 0 ) ,
2143
2167
}
@@ -2310,27 +2334,9 @@ fn add_upstream_native_libraries(
2310
2334
cmd : & mut dyn Linker ,
2311
2335
sess : & Session ,
2312
2336
codegen_results : & CodegenResults ,
2313
- crate_type : CrateType ,
2314
2337
) {
2315
- // Be sure to use a topological sorting of crates because there may be
2316
- // interdependencies between native libraries. When passing -nodefaultlibs,
2317
- // for example, almost all native libraries depend on libc, so we have to
2318
- // make sure that's all the way at the right (liblibc is near the base of
2319
- // the dependency chain).
2320
- //
2321
- // This passes RequireStatic, but the actual requirement doesn't matter,
2322
- // we're just getting an ordering of crate numbers, we're not worried about
2323
- // the paths.
2324
- let ( _, data) = codegen_results
2325
- . crate_info
2326
- . dependency_formats
2327
- . iter ( )
2328
- . find ( |( ty, _) | * ty == crate_type)
2329
- . expect ( "failed to find crate type in dependency format list" ) ;
2330
-
2331
- let crates = & codegen_results. crate_info . used_crates ;
2332
2338
let mut last = ( NativeLibKind :: Unspecified , None ) ;
2333
- for & cnum in crates {
2339
+ for & cnum in & codegen_results . crate_info . used_crates {
2334
2340
for lib in codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) {
2335
2341
let name = match lib. name {
2336
2342
Some ( l) => l,
@@ -2352,19 +2358,10 @@ fn add_upstream_native_libraries(
2352
2358
NativeLibKind :: Framework { as_needed } => {
2353
2359
cmd. link_framework ( name, as_needed. unwrap_or ( true ) )
2354
2360
}
2355
- NativeLibKind :: Static { bundle : Some ( false ) , .. } => {
2356
- // Link "static-nobundle" native libs only if the crate they originate from
2357
- // is being linked statically to the current crate. If it's linked dynamically
2358
- // or is an rlib already included via some other dylib crate, the symbols from
2359
- // native libs will have already been included in that dylib.
2360
- if data[ cnum. as_usize ( ) - 1 ] == Linkage :: Static {
2361
- cmd. link_staticlib ( name, verbatim)
2362
- }
2363
- }
2364
- // ignore statically included native libraries here as we've
2365
- // already included them when we included the rust library
2366
- // previously
2367
- NativeLibKind :: Static { bundle : None | Some ( true ) , .. } => { }
2361
+ // ignore static native libraries here as we've
2362
+ // already included them in add_local_native_libraries and
2363
+ // add_upstream_rust_crates
2364
+ NativeLibKind :: Static { .. } => { }
2368
2365
NativeLibKind :: RawDylib => { }
2369
2366
}
2370
2367
}
0 commit comments