* [PATCH 1/2] rust: do not link C libraries into Rust rlibs
2025-08-11 16:17 [PATCH for-10.2 0/2] meson: let Meson handle mixed-language linking of Rust and C objects Paolo Bonzini
@ 2025-08-11 16:17 ` Paolo Bonzini
2025-08-11 16:17 ` [PATCH 2/2] meson: let Meson handle mixed-language linking of Rust and C objects Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2025-08-11 16:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-rust, manos.pitsidianakis
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 <pbonzini@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
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH 2/2] meson: let Meson handle mixed-language linking of Rust and C objects
2025-08-11 16:17 [PATCH for-10.2 0/2] meson: let Meson handle mixed-language linking of Rust and C objects Paolo Bonzini
2025-08-11 16:17 ` [PATCH 1/2] rust: do not link C libraries into Rust rlibs Paolo Bonzini
@ 2025-08-11 16:17 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2025-08-11 16:17 UTC (permalink / raw)
To: qemu-devel; +Cc: qemu-rust, manos.pitsidianakis
Meson 1.9.0 can pass C objects into rustc so that the final link pass can
add the Rust libstd. Use that to eliminate the staticlib and allow
dynamic linking with libstd (also introduced by Meson 1.9.0, but not
for staticlib crates due to lack of support in rustc).
The main() function is still provided by C, which is possible by
declaring the main source file of the Rust executable (which is
created by scripts/rust/rust_root_crate.sh) as #![no_main].
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
meson.build | 19 ++++++++-----------
scripts/rust/rust_root_crate.sh | 1 +
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/meson.build b/meson.build
index e53cd5b4138..0a921272f57 100644
--- a/meson.build
+++ b/meson.build
@@ -4377,25 +4377,22 @@ foreach target : target_dirs
arch_srcs += target_specific.sources()
arch_deps += target_specific.dependencies()
+ main_rs = []
+ crates = []
if have_rust and target_type == 'system'
target_rust = rust_devices_ss.apply(config_target, strict: false)
- crates = []
+ arch_deps += target_rust.dependencies()
foreach dep : target_rust.dependencies()
crates += dep.get_variable('crate')
endforeach
if crates.length() > 0
- rlib_rs = custom_target('rust_' + target.underscorify() + '.rs',
+ main_rs = custom_target('rust_' + target.underscorify() + '.rs',
output: 'rust_' + target.underscorify() + '.rs',
command: [rust_root_crate, crates],
capture: true,
build_by_default: true,
build_always_stale: true)
- rlib = static_library('rust_' + target.underscorify(),
- structured_sources([], {'.': rlib_rs}),
- dependencies: target_rust.dependencies(),
- override_options: ['rust_std=2021', 'build.rust_std=2021'],
- rust_abi: 'c')
- arch_deps += declare_dependency(link_whole: [rlib])
+ main_rs = structured_sources(main_rs)
endif
endif
@@ -4419,14 +4416,14 @@ foreach target : target_dirs
execs = [{
'name': 'qemu-system-' + target_name,
'win_subsystem': 'console',
- 'sources': files('system/main.c'),
+ 'sources': [main_rs, files('system/main.c')],
'dependencies': [sdl]
}]
if host_os == 'windows' and (sdl.found() or gtk.found())
execs += [{
'name': 'qemu-system-' + target_name + 'w',
'win_subsystem': 'windows',
- 'sources': files('system/main.c'),
+ 'sources': [main_rs, files('system/main.c')],
'dependencies': [sdl]
}]
endif
@@ -4435,7 +4432,7 @@ foreach target : target_dirs
execs += [{
'name': 'qemu-fuzz-' + target_name,
'win_subsystem': 'console',
- 'sources': specific_fuzz.sources(),
+ 'sources': [main_rs, specific_fuzz.sources()],
'dependencies': specific_fuzz.dependencies(),
}]
endif
diff --git a/scripts/rust/rust_root_crate.sh b/scripts/rust/rust_root_crate.sh
index 975bddf7f1a..1ee88114ad9 100755
--- a/scripts/rust/rust_root_crate.sh
+++ b/scripts/rust/rust_root_crate.sh
@@ -6,6 +6,7 @@ cat <<EOF
// @generated
// This file is autogenerated by scripts/rust_root_crate.sh
+#![no_main]
EOF
for crate in $*; do
--
2.50.1
^ permalink raw reply related [flat|nested] 3+ messages in thread