mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Fix linking two dylibs together when both depend on profiler_builtins
See the comment inside this commit for why.
This commit is contained in:
@@ -2972,9 +2972,11 @@ fn add_upstream_rust_crates(
|
||||
// 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).
|
||||
// HACK: `dependency_formats` can report `profiler_builtins` as `NotLinked`.
|
||||
// See the comment in inject_profiler_runtime for why this is the case.
|
||||
let linkage = data[cnum];
|
||||
let link_static_crate = linkage == Linkage::Static
|
||||
|| linkage == Linkage::IncludedFromDylib
|
||||
|| (linkage == Linkage::IncludedFromDylib || linkage == Linkage::NotLinked)
|
||||
&& (crate_info.compiler_builtins == Some(cnum)
|
||||
|| crate_info.profiler_runtime == Some(cnum));
|
||||
|
||||
|
||||
@@ -1024,12 +1024,19 @@ fn inject_profiler_runtime(&mut self, tcx: TyCtxt<'_>) {
|
||||
|
||||
info!("loading profiler");
|
||||
|
||||
// HACK: This uses conditional despite actually being unconditional to ensure that
|
||||
// there is no error emitted when two dylibs independently depend on profiler_builtins.
|
||||
// This is fine as profiler_builtins is always statically linked into the dylib just
|
||||
// like compiler_builtins. Unlike compiler_builtins however there is no guaranteed
|
||||
// common dylib that the duplicate crate check believes the crate to be included in.
|
||||
// add_upstream_rust_crates has a corresponding check that forces profiler_builtins
|
||||
// to be statically linked in even when marked as NotLinked.
|
||||
let name = Symbol::intern(&tcx.sess.opts.unstable_opts.profiler_runtime);
|
||||
let Some(cnum) = self.resolve_crate(
|
||||
tcx,
|
||||
name,
|
||||
DUMMY_SP,
|
||||
CrateDepKind::Unconditional,
|
||||
CrateDepKind::Conditional,
|
||||
CrateOrigin::Injected,
|
||||
) else {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub fn something() {}
|
||||
@@ -0,0 +1 @@
|
||||
pub fn something_else() {}
|
||||
@@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
dylib_a::something();
|
||||
dylib_b::something_else();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Checks that two dylibs compiled with code coverage enabled can be linked
|
||||
// together without getting an error about duplicate profiler_builtins.
|
||||
|
||||
//@ needs-profiler-runtime
|
||||
|
||||
use run_make_support::{dynamic_lib_name, rustc};
|
||||
|
||||
fn main() {
|
||||
rustc()
|
||||
.crate_name("dylib_a")
|
||||
.crate_type("dylib")
|
||||
.arg("-Cinstrument-coverage")
|
||||
.arg("-Cprefer-dynamic")
|
||||
.input("dylib_a.rs")
|
||||
.run();
|
||||
rustc()
|
||||
.crate_name("dylib_b")
|
||||
.crate_type("dylib")
|
||||
.arg("-Cinstrument-coverage")
|
||||
.arg("-Cprefer-dynamic")
|
||||
.input("dylib_b.rs")
|
||||
.run();
|
||||
rustc()
|
||||
.crate_type("bin")
|
||||
.extern_("dylib_a", dynamic_lib_name("dylib_a"))
|
||||
.extern_("dylib_b", dynamic_lib_name("dylib_b"))
|
||||
.input("main.rs")
|
||||
.run();
|
||||
}
|
||||
Reference in New Issue
Block a user