linker: Simplify linking of compiler_builtins
and profiler_builtins
This also fixes linking of native libraries bundled into these crates when `-Zpacked-bundled-libs` is enabled
This commit is contained in:
parent
cae3c936eb
commit
e792de28c8
@ -2425,10 +2425,6 @@ fn add_local_native_libraries(
|
||||
);
|
||||
}
|
||||
|
||||
/// # Linking Rust crates and their non-bundled static libraries
|
||||
///
|
||||
/// Rust crates are not considered at all when creating an rlib output. All dependencies will be
|
||||
/// linked when producing the final output (instead of the intermediate rlib version).
|
||||
fn add_upstream_rust_crates<'a>(
|
||||
cmd: &mut dyn Linker,
|
||||
sess: &'a Session,
|
||||
@ -2444,7 +2440,6 @@ fn add_upstream_rust_crates<'a>(
|
||||
// Linking to a rlib involves just passing it to the linker (the linker
|
||||
// will slurp up the object files inside), and linking to a dynamic library
|
||||
// involves just passing the right -l flag.
|
||||
|
||||
let (_, data) = codegen_results
|
||||
.crate_info
|
||||
.dependency_formats
|
||||
@ -2452,59 +2447,45 @@ fn add_upstream_rust_crates<'a>(
|
||||
.find(|(ty, _)| *ty == crate_type)
|
||||
.expect("failed to find crate type in dependency format list");
|
||||
|
||||
// Invoke get_used_crates to ensure that we get a topological sorting of
|
||||
// crates.
|
||||
let deps = &codegen_results.crate_info.used_crates;
|
||||
|
||||
let mut compiler_builtins = None;
|
||||
let search_paths = OnceCell::new();
|
||||
|
||||
for &cnum in deps.iter() {
|
||||
// We may not pass all crates through to the linker. Some crates may
|
||||
// appear statically in an existing dylib, meaning we'll pick up all the
|
||||
// symbols from the dylib.
|
||||
for &cnum in &codegen_results.crate_info.used_crates {
|
||||
// We may not pass all crates through to the linker. Some crates may appear statically in
|
||||
// an existing dylib, meaning we'll pick up all the symbols from the dylib.
|
||||
// We must always link crates `compiler_builtins` and `profiler_builtins` statically.
|
||||
// Even if they were already included into a dylib
|
||||
// (e.g. `libstd` when `-C prefer-dynamic` is used).
|
||||
let linkage = data[cnum.as_usize() - 1];
|
||||
let bundled_libs =
|
||||
if sess.opts.unstable_opts.packed_bundled_libs && linkage == Linkage::Static {
|
||||
codegen_results.crate_info.native_libraries[&cnum]
|
||||
.iter()
|
||||
.filter_map(|lib| lib.filename)
|
||||
.collect::<FxHashSet<_>>()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
let link_static_crate = linkage == Linkage::Static
|
||||
|| linkage == Linkage::IncludedFromDylib
|
||||
&& (codegen_results.crate_info.compiler_builtins == Some(cnum)
|
||||
|| codegen_results.crate_info.profiler_runtime == Some(cnum));
|
||||
|
||||
let mut bundled_libs = Default::default();
|
||||
match linkage {
|
||||
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&Default::default(),
|
||||
);
|
||||
Linkage::Static | Linkage::IncludedFromDylib => {
|
||||
if link_static_crate {
|
||||
if sess.opts.unstable_opts.packed_bundled_libs {
|
||||
bundled_libs = codegen_results.crate_info.native_libraries[&cnum]
|
||||
.iter()
|
||||
.filter_map(|lib| lib.filename)
|
||||
.collect();
|
||||
}
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&bundled_libs,
|
||||
);
|
||||
}
|
||||
}
|
||||
// compiler-builtins are always placed last to ensure that they're
|
||||
// linked correctly.
|
||||
_ if codegen_results.crate_info.compiler_builtins == Some(cnum) => {
|
||||
assert!(compiler_builtins.is_none());
|
||||
compiler_builtins = Some(cnum);
|
||||
}
|
||||
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
|
||||
Linkage::Static => add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&bundled_libs,
|
||||
),
|
||||
Linkage::Dynamic => {
|
||||
let src = &codegen_results.crate_info.used_crate_source[&cnum];
|
||||
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0);
|
||||
}
|
||||
Linkage::NotLinked => {}
|
||||
}
|
||||
|
||||
// Static libraries are linked for a subset of linked upstream crates.
|
||||
@ -2514,7 +2495,8 @@ fn add_upstream_rust_crates<'a>(
|
||||
// the native library because it is already linked into the dylib, and even if
|
||||
// inline/const/generic functions from the dylib can refer to symbols from the native
|
||||
// library, those symbols should be exported and available from the dylib anyway.
|
||||
let link_static = linkage == Linkage::Static;
|
||||
// 3. Libraries bundled into `(compiler,profiler)_builtins` are special, see above.
|
||||
let link_static = link_static_crate;
|
||||
// Dynamic libraries are not linked here, see the FIXME in `add_upstream_native_libraries`.
|
||||
let link_dynamic = false;
|
||||
add_native_libs_from_crate(
|
||||
@ -2531,23 +2513,6 @@ fn add_upstream_rust_crates<'a>(
|
||||
);
|
||||
}
|
||||
|
||||
// compiler-builtins are always placed last to ensure that they're
|
||||
// linked correctly.
|
||||
// We must always link the `compiler_builtins` crate statically. Even if it
|
||||
// was already "included" in a dylib (e.g., `libstd` when `-C prefer-dynamic`
|
||||
// is used)
|
||||
if let Some(cnum) = compiler_builtins {
|
||||
add_static_crate(
|
||||
cmd,
|
||||
sess,
|
||||
archive_builder_builder,
|
||||
codegen_results,
|
||||
tmpdir,
|
||||
cnum,
|
||||
&Default::default(),
|
||||
);
|
||||
}
|
||||
|
||||
// Converts a library file-stem into a cc -l argument
|
||||
fn unlib<'a>(target: &Target, stem: &'a str) -> &'a str {
|
||||
if stem.starts_with("lib") && !target.is_like_windows { &stem[3..] } else { stem }
|
||||
|
@ -833,20 +833,30 @@ impl CrateInfo {
|
||||
//
|
||||
// In order to get this left-to-right dependency ordering, we use the reverse
|
||||
// postorder of all crates putting the leaves at the right-most positions.
|
||||
let used_crates = tcx
|
||||
let mut compiler_builtins = None;
|
||||
let mut used_crates: Vec<_> = tcx
|
||||
.postorder_cnums(())
|
||||
.iter()
|
||||
.rev()
|
||||
.copied()
|
||||
.filter(|&cnum| !tcx.dep_kind(cnum).macros_only())
|
||||
.filter(|&cnum| {
|
||||
let link = !tcx.dep_kind(cnum).macros_only();
|
||||
if link && tcx.is_compiler_builtins(cnum) {
|
||||
compiler_builtins = Some(cnum);
|
||||
return false;
|
||||
}
|
||||
link
|
||||
})
|
||||
.collect();
|
||||
// `compiler_builtins` are always placed last to ensure that they're linked correctly.
|
||||
used_crates.extend(compiler_builtins);
|
||||
|
||||
let mut info = CrateInfo {
|
||||
target_cpu,
|
||||
exported_symbols,
|
||||
linked_symbols,
|
||||
local_crate_name,
|
||||
compiler_builtins: None,
|
||||
compiler_builtins,
|
||||
profiler_runtime: None,
|
||||
is_no_builtins: Default::default(),
|
||||
native_libraries: Default::default(),
|
||||
@ -872,9 +882,6 @@ impl CrateInfo {
|
||||
|
||||
let used_crate_source = tcx.used_crate_source(cnum);
|
||||
info.used_crate_source.insert(cnum, used_crate_source.clone());
|
||||
if tcx.is_compiler_builtins(cnum) {
|
||||
info.compiler_builtins = Some(cnum);
|
||||
}
|
||||
if tcx.is_profiler_runtime(cnum) {
|
||||
info.profiler_runtime = Some(cnum);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user