When a C library is linked into a Rust rlib, rustc remembers the dependency
into the metadata and adds the library to the linker command line.
Unfortunately, static libraries are sensitive to their position on the
command line and rustc does not always get it right.

Meson could work around it itself by never adding these static libraries
to the rlibs (after all, Meson tracks the transitive dependencies already
and knows how to add them to dependents of those rlibs); at least for now,
do it in QEMU: never link C libraries into Rust rlibs, and add them to the
final build products only.

Signed-off-by: Paolo Bonzini <pbonz...@redhat.com>
---
 rust/hw/char/pl011/meson.build |  2 +-
 rust/hw/timer/hpet/meson.build |  2 +-
 rust/meson.build               |  2 --
 rust/qemu-api/meson.build      | 15 +++++++++------
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/rust/hw/char/pl011/meson.build b/rust/hw/char/pl011/meson.build
index 2a1be329abc..16acf12f7cc 100644
--- a/rust/hw/char/pl011/meson.build
+++ b/rust/hw/char/pl011/meson.build
@@ -7,7 +7,7 @@ _libpl011_rs = static_library(
     bilge_rs,
     bilge_impl_rs,
     bits_rs,
-    qemu_api,
+    qemu_api_rs,
     qemu_api_macros,
   ],
 )
diff --git a/rust/hw/timer/hpet/meson.build b/rust/hw/timer/hpet/meson.build
index c2d7c0532ca..64195410a3e 100644
--- a/rust/hw/timer/hpet/meson.build
+++ b/rust/hw/timer/hpet/meson.build
@@ -4,7 +4,7 @@ _libhpet_rs = static_library(
   override_options: ['rust_std=2021', 'build.rust_std=2021'],
   rust_abi: 'rust',
   dependencies: [
-    qemu_api,
+    qemu_api_rs,
     qemu_api_macros,
   ],
 )
diff --git a/rust/meson.build b/rust/meson.build
index 331f11b7e72..45936a0a731 100644
--- a/rust/meson.build
+++ b/rust/meson.build
@@ -18,8 +18,6 @@ quote_rs_native = dependency('quote-1-rs', native: true)
 syn_rs_native = dependency('syn-2-rs', native: true)
 proc_macro2_rs_native = dependency('proc-macro2-1-rs', native: true)
 
-qemuutil_rs = qemuutil.partial_dependency(link_args: true, links: true)
-
 genrs = []
 
 subdir('qemu-api-macros')
diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build
index a090297c458..88875e723d8 100644
--- a/rust/qemu-api/meson.build
+++ b/rust/qemu-api/meson.build
@@ -79,15 +79,18 @@ _qemu_api_rs = static_library(
   override_options: ['rust_std=2021', 'build.rust_std=2021'],
   rust_abi: 'rust',
   rust_args: _qemu_api_cfg,
-  dependencies: [anyhow_rs, foreign_rs, libc_rs, qemu_api_macros, qemuutil_rs,
-                 qom, hwcore, chardev, migration],
+  # Cannot add qemuutil here; rustc adds it too early to the linker command 
line.
+  # Instead, we add it and all C static libraries to the executables only.
+  dependencies: [anyhow_rs, foreign_rs, libc_rs, qemu_api_macros],
 )
 
-rust.test('rust-qemu-api-tests', _qemu_api_rs,
-          suite: ['unit', 'rust'])
-
+qemu_api_rs = declare_dependency(link_with: _qemu_api_rs)
 qemu_api = declare_dependency(link_with: [_qemu_api_rs],
-  dependencies: [qemu_api_macros, qom, hwcore, chardev, migration])
+  dependencies: [qemu_api_macros, qom, hwcore, chardev, migration, qemuutil])
+
+rust.test('rust-qemu-api-tests', _qemu_api_rs,
+          suite: ['unit', 'rust'],
+          dependencies: [qemu_api_macros, qom, hwcore, chardev, migration, 
qemuutil])
 
 # Doctests are essentially integration tests, so they need the same 
dependencies.
 # Note that running them requires the object files for C code, so place them
-- 
2.50.1


Reply via email to