summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2025-11-05 16:53:28 +0100
committerDylan Baker <dylan@pnwbakers.com>2025-11-19 09:14:05 -0800
commita01cedecc4fed77f468ee15d272f06c918f119e5 (patch)
treeac84a9f31aa2fd787fe4977407ace2ed3ad86dd3
parent665bf31e0b1c8905f107cb085e179dd8d8b82302 (diff)
downloadmeson-a01cedecc4fed77f468ee15d272f06c918f119e5.tar.gz
rust: search for native static libs in target libdir
Sometimes, a Rust static library's native static libs refer to libraries installed in the rustc target libdir. This is always the case for most musl targets (with the intention of making it easier to use them on non-musl systems), and other targets can also be configured to do this using e.g. the llvm-libunwind option when building the standard libraries for the target. When rustc is responsible for linking it will always add the appropriate directory to the linker search path, but if we're not using Rust for linking, we have to tell the linker about that directory ourselves. The added test demonstrates a scenario where this comes up: linking a static Rust library, built for musl, into a C executable. -lunwind is in the native static libs list from the compiler, but it's referring to the libunwind.a in the self-contained directory.
-rw-r--r--mesonbuild/build.py5
-rw-r--r--test cases/rust/28 self-contained/lib.rs4
-rw-r--r--test cases/rust/28 self-contained/main.c6
-rw-r--r--test cases/rust/28 self-contained/meson.build17
-rw-r--r--test cases/rust/28 self-contained/test.json6
5 files changed, 36 insertions, 2 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index a43709342..0ad679450 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -2327,8 +2327,9 @@ class StaticLibrary(BuildTarget):
# and thus, machine_info kernel should be set to 'none'.
# In that case, native_static_libs list is empty.
rustc = self.compilers['rust']
- d = dependencies.InternalDependency('undefined', [], [],
- rustc.native_static_libs,
+ link_args = ['-L' + rustc.get_target_libdir() + '/self-contained']
+ link_args += rustc.native_static_libs
+ d = dependencies.InternalDependency('undefined', [], [], link_args,
[], [], [], [], [], {}, [], [], [],
'_rust_native_static_libs')
self.external_deps.append(d)
diff --git a/test cases/rust/28 self-contained/lib.rs b/test cases/rust/28 self-contained/lib.rs
new file mode 100644
index 000000000..f8a8bf201
--- /dev/null
+++ b/test cases/rust/28 self-contained/lib.rs
@@ -0,0 +1,4 @@
+#[unsafe(export_name = "hello")]
+pub extern "C" fn hello() {
+ println!("Hello, world!");
+}
diff --git a/test cases/rust/28 self-contained/main.c b/test cases/rust/28 self-contained/main.c
new file mode 100644
index 000000000..11bedf5ae
--- /dev/null
+++ b/test cases/rust/28 self-contained/main.c
@@ -0,0 +1,6 @@
+extern void hello(void);
+
+int main(void)
+{
+ hello();
+}
diff --git a/test cases/rust/28 self-contained/meson.build b/test cases/rust/28 self-contained/meson.build
new file mode 100644
index 000000000..25de68f25
--- /dev/null
+++ b/test cases/rust/28 self-contained/meson.build
@@ -0,0 +1,17 @@
+project('self-contained', meson_version : '>= 1.3.0')
+
+if not add_languages('c', native : false, required : false)
+ error('MESON_SKIP_TEST clang not installed')
+endif
+
+if not add_languages('rust', native : false, required : false)
+ error('MESON_SKIP_TEST Rust x86_64-unknown-linux-musl target not installed')
+endif
+
+if meson.get_compiler('c').find_library('libunwind', required : false).found()
+ error('MESON_SKIP_TEST libunwind is installed globally')
+endif
+
+lib = static_library('rust', 'lib.rs', rust_abi : 'c')
+
+executable('exe', 'main.c', link_with : lib)
diff --git a/test cases/rust/28 self-contained/test.json b/test cases/rust/28 self-contained/test.json
new file mode 100644
index 000000000..fccefd6f1
--- /dev/null
+++ b/test cases/rust/28 self-contained/test.json
@@ -0,0 +1,6 @@
+{
+ "env": {
+ "CC": "clang -target x86_64-unknown-linux-musl",
+ "RUSTC": "rustc --target x86_64-unknown-linux-musl"
+ }
+}