Skip to content

Commit 6204f65

Browse files
committed
add -Z split_bundled_libs
1 parent 6077b7c commit 6204f65

File tree

2 files changed

+78
-29
lines changed

2 files changed

+78
-29
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 76 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -317,37 +317,66 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(
317317
// loaded from the libraries found here and then encode that into the
318318
// metadata of the rlib we're generating somehow.
319319
for lib in codegen_results.crate_info.used_libraries.iter() {
320-
match lib.kind {
321-
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
322-
if flavor == RlibFlavor::Normal =>
323-
{
324-
// Don't allow mixing +bundle with +whole_archive since an rlib may contain
325-
// multiple native libs, some of which are +whole-archive and some of which are
326-
// -whole-archive and it isn't clear how we can currently handle such a
327-
// situation correctly.
328-
// See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
329-
sess.err(
330-
"the linking modifiers `+bundle` and `+whole-archive` are not compatible \
320+
if !sess.opts.unstable_opts.split_bundled_libs {
321+
match lib.kind {
322+
NativeLibKind::Static { bundle: None | Some(true), whole_archive: Some(true) }
323+
if flavor == RlibFlavor::Normal =>
324+
{
325+
// Don't allow mixing +bundle with +whole_archive since an rlib may contain
326+
// multiple native libs, some of which are +whole-archive and some of which are
327+
// -whole-archive and it isn't clear how we can currently handle such a
328+
// situation correctly.
329+
// See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897
330+
sess.err(
331+
"the linking modifiers `+bundle` and `+whole-archive` are not compatible \
331332
with each other when generating rlibs",
333+
);
334+
}
335+
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
336+
NativeLibKind::Static { bundle: Some(false), .. }
337+
| NativeLibKind::Dylib { .. }
338+
| NativeLibKind::Framework { .. }
339+
| NativeLibKind::RawDylib
340+
| NativeLibKind::Unspecified => continue,
341+
}
342+
if let Some(name) = lib.name {
343+
let location = find_library(
344+
name.as_str(),
345+
lib.verbatim.unwrap_or(false),
346+
&lib_search_paths,
347+
sess,
332348
);
349+
ab.add_archive(&location, |_| false).unwrap_or_else(|e| {
350+
sess.fatal(&format!(
351+
"failed to add native library {}: {}",
352+
location.to_string_lossy(),
353+
e
354+
));
355+
});
356+
}
357+
} else {
358+
match lib.kind {
359+
NativeLibKind::Static { bundle: None | Some(true), .. }
360+
if flavor == RlibFlavor::Normal =>
361+
{
362+
let Some(name) = lib.name else {
363+
continue;
364+
};
365+
366+
let location = find_library(
367+
name.as_str(),
368+
lib.verbatim.unwrap_or(false),
369+
&lib_search_paths,
370+
sess,
371+
);
372+
373+
let suffix = &sess.target.staticlib_suffix;
374+
let crate_name = out_filename.to_str().unwrap();
375+
let bundle_lib = PathBuf::from(&format!("{crate_name}.bundle.{name}{suffix}"));
376+
fs::copy(location, bundle_lib).unwrap();
377+
}
378+
_ => {}
333379
}
334-
NativeLibKind::Static { bundle: None | Some(true), .. } => {}
335-
NativeLibKind::Static { bundle: Some(false), .. }
336-
| NativeLibKind::Dylib { .. }
337-
| NativeLibKind::Framework { .. }
338-
| NativeLibKind::RawDylib
339-
| NativeLibKind::Unspecified => continue,
340-
}
341-
if let Some(name) = lib.name {
342-
let location =
343-
find_library(name.as_str(), lib.verbatim.unwrap_or(false), &lib_search_paths, sess);
344-
ab.add_archive(&location, |_| false).unwrap_or_else(|e| {
345-
sess.fatal(&format!(
346-
"failed to add native library {}: {}",
347-
location.to_string_lossy(),
348-
e
349-
));
350-
});
351380
}
352381
}
353382

@@ -2362,7 +2391,24 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
23622391
(lib.name, lib.kind, lib.verbatim)
23632392
};
23642393

2365-
if let NativeLibKind::Static { bundle: Some(false), whole_archive } =
2394+
if sess.opts.unstable_opts.split_bundled_libs {
2395+
if let NativeLibKind::Static {
2396+
bundle: Some(true) | None,
2397+
whole_archive,
2398+
} = lib.kind
2399+
{
2400+
let suffix = &sess.target.staticlib_suffix;
2401+
let crate_path = src.paths().next().unwrap().to_str().unwrap();
2402+
let bundle_lib =
2403+
PathBuf::from(&format!("{crate_path}.bundle.{name}{suffix}"));
2404+
if whole_archive == Some(true) {
2405+
cmd.link_whole_rlib(&bundle_lib);
2406+
} else {
2407+
cmd.link_rlib(&bundle_lib);
2408+
}
2409+
}
2410+
} else {
2411+
if let NativeLibKind::Static { bundle: Some(false), whole_archive } =
23662412
lib.kind
23672413
{
23682414
let verbatim = lib.verbatim.unwrap_or(false);
@@ -2376,6 +2422,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(
23762422
cmd.link_staticlib(name, verbatim);
23772423
}
23782424
}
2425+
}
23792426
}
23802427
}
23812428
}

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,8 @@ options! {
15121512
file which is ignored by the linker
15131513
`single`: sections which do not require relocation are written into object file but ignored
15141514
by the linker"),
1515+
split_bundled_libs: bool = (false, parse_bool, [TRACKED],
1516+
"split bundled libs"),
15151517
split_dwarf_inlining: bool = (true, parse_bool, [TRACKED],
15161518
"provide minimal debug info in the object/executable to facilitate online \
15171519
symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF"),

0 commit comments

Comments
 (0)