Set DT_SONAME when building dylibs
authorAngus Lees <gus@debian.org>
Thu, 14 Jul 2022 11:17:39 +0000 (13:17 +0200)
committerFabian Grünbichler <debian@fabian.gruenbichler.email>
Fri, 4 Apr 2025 16:24:50 +0000 (18:24 +0200)
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

Gbp-Pq: Topic behaviour
Gbp-Pq: Name d-rustc-add-soname.patch

compiler/rustc_codegen_ssa/src/back/link.rs
tests/run-make/dylib-soname/rmake.rs

index e2081ad75633c747d0ab562788072c6dabad3b1b..e0594f97e9364486cfbb094637e9c9f587a675af 100644 (file)
@@ -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.
index 714997cbc1a171146e7a549fa057f7c2551b13b9..653a0feb84e8607a65edd043143856cf2dfa1938 100644 (file)
@@ -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()