mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
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>(
|
fn add_upstream_rust_crates<'a>(
|
||||||
cmd: &mut dyn Linker,
|
cmd: &mut dyn Linker,
|
||||||
sess: &'a Session,
|
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
|
// 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
|
// will slurp up the object files inside), and linking to a dynamic library
|
||||||
// involves just passing the right -l flag.
|
// involves just passing the right -l flag.
|
||||||
|
|
||||||
let (_, data) = codegen_results
|
let (_, data) = codegen_results
|
||||||
.crate_info
|
.crate_info
|
||||||
.dependency_formats
|
.dependency_formats
|
||||||
@ -2452,59 +2447,45 @@ fn add_upstream_rust_crates<'a>(
|
|||||||
.find(|(ty, _)| *ty == crate_type)
|
.find(|(ty, _)| *ty == crate_type)
|
||||||
.expect("failed to find crate type in dependency format list");
|
.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();
|
let search_paths = OnceCell::new();
|
||||||
|
for &cnum in &codegen_results.crate_info.used_crates {
|
||||||
for &cnum in deps.iter() {
|
// We may not pass all crates through to the linker. Some crates may appear statically in
|
||||||
// We may not pass all crates through to the linker. Some crates may
|
// an existing dylib, meaning we'll pick up all the symbols from the dylib.
|
||||||
// appear statically in an existing dylib, meaning we'll pick up all the
|
// We must always link crates `compiler_builtins` and `profiler_builtins` statically.
|
||||||
// symbols from the dylib.
|
// 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 linkage = data[cnum.as_usize() - 1];
|
||||||
let bundled_libs =
|
let link_static_crate = linkage == Linkage::Static
|
||||||
if sess.opts.unstable_opts.packed_bundled_libs && linkage == Linkage::Static {
|
|| linkage == Linkage::IncludedFromDylib
|
||||||
codegen_results.crate_info.native_libraries[&cnum]
|
&& (codegen_results.crate_info.compiler_builtins == Some(cnum)
|
||||||
.iter()
|
|| codegen_results.crate_info.profiler_runtime == Some(cnum));
|
||||||
.filter_map(|lib| lib.filename)
|
|
||||||
.collect::<FxHashSet<_>>()
|
let mut bundled_libs = Default::default();
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
};
|
|
||||||
match linkage {
|
match linkage {
|
||||||
_ if codegen_results.crate_info.profiler_runtime == Some(cnum) => {
|
Linkage::Static | Linkage::IncludedFromDylib => {
|
||||||
add_static_crate(
|
if link_static_crate {
|
||||||
cmd,
|
if sess.opts.unstable_opts.packed_bundled_libs {
|
||||||
sess,
|
bundled_libs = codegen_results.crate_info.native_libraries[&cnum]
|
||||||
archive_builder_builder,
|
.iter()
|
||||||
codegen_results,
|
.filter_map(|lib| lib.filename)
|
||||||
tmpdir,
|
.collect();
|
||||||
cnum,
|
}
|
||||||
&Default::default(),
|
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 => {
|
Linkage::Dynamic => {
|
||||||
let src = &codegen_results.crate_info.used_crate_source[&cnum];
|
let src = &codegen_results.crate_info.used_crate_source[&cnum];
|
||||||
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0);
|
add_dynamic_crate(cmd, sess, &src.dylib.as_ref().unwrap().0);
|
||||||
}
|
}
|
||||||
|
Linkage::NotLinked => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static libraries are linked for a subset of linked upstream crates.
|
// 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
|
// 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
|
// 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.
|
// 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`.
|
// Dynamic libraries are not linked here, see the FIXME in `add_upstream_native_libraries`.
|
||||||
let link_dynamic = false;
|
let link_dynamic = false;
|
||||||
add_native_libs_from_crate(
|
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
|
// Converts a library file-stem into a cc -l argument
|
||||||
fn unlib<'a>(target: &Target, stem: &'a str) -> &'a str {
|
fn unlib<'a>(target: &Target, stem: &'a str) -> &'a str {
|
||||||
if stem.starts_with("lib") && !target.is_like_windows { &stem[3..] } else { stem }
|
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
|
// 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.
|
// 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(())
|
.postorder_cnums(())
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.copied()
|
.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();
|
.collect();
|
||||||
|
// `compiler_builtins` are always placed last to ensure that they're linked correctly.
|
||||||
|
used_crates.extend(compiler_builtins);
|
||||||
|
|
||||||
let mut info = CrateInfo {
|
let mut info = CrateInfo {
|
||||||
target_cpu,
|
target_cpu,
|
||||||
exported_symbols,
|
exported_symbols,
|
||||||
linked_symbols,
|
linked_symbols,
|
||||||
local_crate_name,
|
local_crate_name,
|
||||||
compiler_builtins: None,
|
compiler_builtins,
|
||||||
profiler_runtime: None,
|
profiler_runtime: None,
|
||||||
is_no_builtins: Default::default(),
|
is_no_builtins: Default::default(),
|
||||||
native_libraries: Default::default(),
|
native_libraries: Default::default(),
|
||||||
@ -872,9 +882,6 @@ impl CrateInfo {
|
|||||||
|
|
||||||
let used_crate_source = tcx.used_crate_source(cnum);
|
let used_crate_source = tcx.used_crate_source(cnum);
|
||||||
info.used_crate_source.insert(cnum, used_crate_source.clone());
|
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) {
|
if tcx.is_profiler_runtime(cnum) {
|
||||||
info.profiler_runtime = Some(cnum);
|
info.profiler_runtime = Some(cnum);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user