@@ -1803,15 +1803,16 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
18031803 add_local_native_libraries ( cmd, sess, codegen_results) ;
18041804 }
18051805
1806- // Rust libraries.
1806+ // Upstream rust libraries and their nobundle static libraries
18071807 add_upstream_rust_crates :: < B > ( cmd, sess, codegen_results, crate_type, tmpdir) ;
18081808
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.
18101811 // If -Zlink-native-libraries=false is set, then the assumption is that an
18111812 // external build system already has the native dependencies defined, and it
18121813 // will provide them to the linker itself.
18131814 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) ;
18151816 }
18161817
18171818 // Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
@@ -2033,7 +2034,7 @@ fn add_local_native_libraries(
20332034 }
20342035}
20352036
2036- /// # Rust Crate linking
2037+ /// # Linking Rust crates and their nobundle static libraries
20372038///
20382039/// Rust crates are not considered at all when creating an rlib output. All dependencies will be
20392040/// 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>>(
21382139 Linkage :: NotLinked | Linkage :: IncludedFromDylib => { }
21392140 Linkage :: Static => {
21402141 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+ }
21412165 }
21422166 Linkage :: Dynamic => add_dynamic_crate ( cmd, sess, & src. dylib . as_ref ( ) . unwrap ( ) . 0 ) ,
21432167 }
@@ -2310,27 +2334,9 @@ fn add_upstream_native_libraries(
23102334 cmd : & mut dyn Linker ,
23112335 sess : & Session ,
23122336 codegen_results : & CodegenResults ,
2313- crate_type : CrateType ,
23142337) {
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 ;
23322338 let mut last = ( NativeLibKind :: Unspecified , None ) ;
2333- for & cnum in crates {
2339+ for & cnum in & codegen_results . crate_info . used_crates {
23342340 for lib in codegen_results. crate_info . native_libraries [ & cnum] . iter ( ) {
23352341 let name = match lib. name {
23362342 Some ( l) => l,
@@ -2352,19 +2358,10 @@ fn add_upstream_native_libraries(
23522358 NativeLibKind :: Framework { as_needed } => {
23532359 cmd. link_framework ( name, as_needed. unwrap_or ( true ) )
23542360 }
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 { .. } => { }
23682365 NativeLibKind :: RawDylib => { }
23692366 }
23702367 }
0 commit comments