Skip to content

Commit 00fcfd4

Browse files
authored
Rollup merge of rust-lang#88227 - 12101111:nobundle-link-order, r=petrochenkov
Adjust linking order of static nobundle libraries Link the static libraries with "-bundle" modifier from upstream rust crate right after linking this rust crate. Some linker such as GNU linker `ld.bdf` treat order of linking as order of dependency. After this change, static libraries with "-bundle" modifier is linked in the same order as "+bundle" modifier. So we can change the value of "bundle" modifier without causing linking error. fix: rust-lang#87541 r? ``@petrochenkov``
2 parents ad127ac + 118df1c commit 00fcfd4

File tree

1 file changed

+33
-36
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+33
-36
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+33-36
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)