summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-10-16 18:34:03 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-10-16 13:33:02 -0700
commit2c1dc736eb62ef6b3922f846785101cd3d2b2972 (patch)
treea980baa15094a3fd9b0033ae2e22481a3f548a73
parent9f83bbb0b680b51776ec9f6ac341f03465203f0b (diff)
downloadmeson-2c1dc736eb62ef6b3922f846785101cd3d2b2972.tar.gz
rust: work around unintuitive behavior of -l:-bundle
When a Rust target depends on an intermediate Rust library (.rlib) which itself has a dependency on a native static library, Meson's generated rustc command line failed to collect and propagate the search paths for these indirect native dependencies, leading to a linker error: error: linking with `cc` failed: exit status: 1 = note: rust-lld: error: unable to find library -l:libf.a collect2: error: ld returned 1 exit status The root cause is that the intermediate .rlib's metadata correctly stores the requirement to link the native library (via the -l flag), but it does not store the library's search path (the -L flag); the responsibility for providing the search path is therefore deferred to the final link command. Ensures that search paths for all transitive dependencies are collected, allowing the final linker invocation to find and correctly link the required native libraries. Reported-by: Martin Kletzander <nert.pinx@gmail.com> Fixes: 018d22482 ("ninjabackend: unify conversion from path to -L/-l", 2025-10-08) Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/backend/ninjabackend.py8
-rw-r--r--test cases/rust/29 rlib link subdir/cdep/f.c1
-rw-r--r--test cases/rust/29 rlib link subdir/cdep/meson.build1
-rw-r--r--test cases/rust/29 rlib link subdir/f-sys.rs3
-rw-r--r--test cases/rust/29 rlib link subdir/main.rs1
-rw-r--r--test cases/rust/29 rlib link subdir/meson.build21
6 files changed, 34 insertions, 1 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 3fd82a85b..50917aeef 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2079,11 +2079,17 @@ class NinjaBackend(backends.Backend):
external_deps = target.external_deps.copy()
target_deps = target.get_dependencies()
for d in target_deps:
+ # rlibs only store -l flags, not -L; help out rustc and always
+ # add the -L flag, in case it's needed to find non-bundled
+ # dependencies of an rlib. At this point we don't have
+ # information on whether this is a direct dependency (which
+ # might use -Clink-arg= below) or an indirect one, so always
+ # add to linkdirs.
+ linkdirs.add(d.subdir)
deps.append(self.get_dependency_filename(d))
if isinstance(d, build.StaticLibrary):
external_deps.extend(d.external_deps)
if d.uses_rust_abi():
- linkdirs.add(d.subdir)
if d not in itertools.chain(target.link_targets, target.link_whole_targets):
# Indirect Rust ABI dependency, we only need its path in linkdirs.
continue
diff --git a/test cases/rust/29 rlib link subdir/cdep/f.c b/test cases/rust/29 rlib link subdir/cdep/f.c
new file mode 100644
index 000000000..d64ff8ca2
--- /dev/null
+++ b/test cases/rust/29 rlib link subdir/cdep/f.c
@@ -0,0 +1 @@
+int f() { return 42; }
diff --git a/test cases/rust/29 rlib link subdir/cdep/meson.build b/test cases/rust/29 rlib link subdir/cdep/meson.build
new file mode 100644
index 000000000..b7fd7e28b
--- /dev/null
+++ b/test cases/rust/29 rlib link subdir/cdep/meson.build
@@ -0,0 +1 @@
+cdep = static_library('f', 'f.c')
diff --git a/test cases/rust/29 rlib link subdir/f-sys.rs b/test cases/rust/29 rlib link subdir/f-sys.rs
new file mode 100644
index 000000000..88971208d
--- /dev/null
+++ b/test cases/rust/29 rlib link subdir/f-sys.rs
@@ -0,0 +1,3 @@
+extern "C" {
+ pub fn f() -> ::std::os::raw::c_int;
+}
diff --git a/test cases/rust/29 rlib link subdir/main.rs b/test cases/rust/29 rlib link subdir/main.rs
new file mode 100644
index 000000000..8ae3c3255
--- /dev/null
+++ b/test cases/rust/29 rlib link subdir/main.rs
@@ -0,0 +1 @@
+fn main() { assert_eq!(unsafe { ::f_sys::f() }, 42); }
diff --git a/test cases/rust/29 rlib link subdir/meson.build b/test cases/rust/29 rlib link subdir/meson.build
new file mode 100644
index 000000000..89acff26f
--- /dev/null
+++ b/test cases/rust/29 rlib link subdir/meson.build
@@ -0,0 +1,21 @@
+project(
+ 'rlib-link-subdir',
+ ['c', 'rust'],
+ default_options: ['rust_std=2021']
+)
+
+subdir('cdep')
+f_sys = static_library(
+ 'f_sys',
+ 'f-sys.rs',
+ link_with: cdep,
+ rust_abi: 'rust',
+)
+
+exe = executable(
+ 'main',
+ 'main.rs',
+ link_with: f_sys,
+)
+
+test('basic', exe)