1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
From: Angus Lees <gus@debian.org>
Date: Thu, 14 Jul 2022 13:17:39 +0200
Subject: Set DT_SONAME when building dylibs
In Rust, library filenames include a version-specific hash to help
the run-time linker find the correct version. Unlike in C/C++, the
compiler looks for all libraries matching a glob that ignores the
hash and reads embedded metadata to work out versions, etc.
The upshot is that there is no need for the usual "libfoo.so ->
libfoo-1.2.3.so" symlink common with C/C++ when building with Rust,
and no need to communicate an alternate filename to use at run-time
vs compile time. If linking to a Rust dylib from C/C++ however, a
"libfoo.so -> libfoo-$hash.so" symlink may well be useful and in
this case DT_SONAME=libfoo-$hash.so would be required. More
mundanely, various tools (eg: dpkg-shlibdeps) complain if they don't
find DT_SONAME on shared libraries in public directories.
This patch passes -Wl,-soname=$outfile when building dylibs (and
using a GNU linker).
Forwarded: no
---
compiler/rustc_codegen_ssa/src/back/link.rs | 7 +++++++
tests/run-make/dylib-soname/rmake.rs | 4 +++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index e2081ad..e0594f9 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2548,6 +2548,13 @@ fn add_order_independent_options(
}
add_rpath_args(cmd, sess, codegen_results, out_filename);
+
+ if (crate_type == config::CrateType::Dylib || crate_type == config::CrateType::Cdylib)
+ && sess.target.linker_flavor.is_gnu() {
+ let filename = String::from(out_filename.file_name().unwrap().to_str().unwrap());
+ let soname = [String::from("-Wl,-soname=") + &filename];
+ cmd.cc_args(&soname);
+ }
}
// Write the NatVis debugger visualizer files for each crate to the temp directory and gather the file paths.
diff --git a/tests/run-make/dylib-soname/rmake.rs b/tests/run-make/dylib-soname/rmake.rs
index 714997c..653a0fe 100644
--- a/tests/run-make/dylib-soname/rmake.rs
+++ b/tests/run-make/dylib-soname/rmake.rs
@@ -3,10 +3,12 @@
//@ only-linux
//@ ignore-cross-compile
-
use run_make_support::{cmd, run_in_tmpdir, rustc};
fn main() {
+ // Debian: we patch rustc to intentionally insert the soname
+ return;
+
let check = |ty: &str| {
rustc().crate_name("foo").crate_type(ty).input("foo.rs").run();
cmd("readelf").arg("-d").arg("libfoo.so").run()
|