@samitouri / QOSamiQemu / commits / 6d28fc6089

rust: switch to cargo subprojects

Let Meson parse Cargo.lock and Cargo.toml and figure out the set of Rust build dependencies. For now, the only change is that subprojects are retrieved with "cargo_ws.subproject('NAME')" instead of "subproject('NAME-API-rs')". However, just calling "import('rust').workspace()" enables extra functionality that operates by parsing Cargo.toml; it will be introduced a step at a time in subsequent commits. Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo Bonzini committed Oct 17, 2025 at 14:06 UTC 6d28fc60891fd5643f2fbc8bf4c6ff57f21b5070
23 files changed +40 -52
.gitlab-ci.d/static_checks.yml
+2 -2
@@ -55,7 +55,7 @@ check-rust-tools-nightly:
55 - source scripts/ci/gitlab-ci-section
56 - section_start test "Running Rust code checks"
57 - cd build
58 - - pyvenv/bin/meson devenv -w ../rust ${CARGO-cargo} fmt --check
58 + - pyvenv/bin/meson devenv -w ../ ${CARGO-cargo} fmt --check
59 - make clippy
60 - make rustdoc
61 - section_end test
@@ -69,7 +69,7 @@ check-rust-tools-nightly:
69 when: on_success
70 expire_in: 2 days
71 paths:
72 - - rust/target/doc
72 + - target/doc
73
74 check-build-units:
75 extends: .base_job_template
Cargo.lock renamed
Cargo.toml renamed
+3 -3
@@ -1,9 +1,9 @@
1 [workspace]
2 resolver = "2"
3 members = [
4 - "hw/char/pl011",
5 - "hw/timer/hpet",
6 - "tests",
4 + "rust/hw/char/pl011",
5 + "rust/hw/timer/hpet",
6 + "rust/tests",
7 ]
8
9 [workspace.package]
docs/devel/rust.rst
+4 -4
@@ -26,14 +26,14 @@ are accustomed to the more "normal" Cargo-based development workflow.
26 In particular:
27
28 * the set of warnings and lints that are used to build QEMU always
29 - comes from the ``rust/Cargo.toml`` workspace file
29 + comes from the ``Cargo.toml`` workspace file
30
31 * it is also possible to use ``cargo`` for common Rust-specific coding
32 tasks, in particular to invoke ``clippy``, ``rustfmt`` and ``rustdoc``.
33
34 To this end, QEMU includes a ``build.rs`` build script that picks up
35 generated sources from QEMU's build directory and puts it in Cargo's
36 -output directory (typically ``rust/target/``). A vanilla invocation
36 +output directory (typically ``target/``). A vanilla invocation
37 of Cargo will complain that it cannot find the generated sources,
38 which can be fixed in different ways:
39
@@ -475,8 +475,8 @@ files, it is still highly experimental and is therefore not used.
475
476 Therefore, external crates must be added as subprojects for Meson to
477 learn how to build them, as well as to the relevant ``Cargo.toml`` files.
478 -The versions specified in ``rust/Cargo.lock`` must be the same as the
479 -subprojects; note that the ``rust/`` directory forms a Cargo `workspace`__,
478 +The versions specified in ``Cargo.lock`` must be the same as the
479 +subprojects; note that the QEMU source tree forms a Cargo `workspace`__,
480 and therefore there is a single lock file for the whole build.
481
482 __ https://doc.rust-lang.org/cargo/reference/workspaces.html#virtual-workspace
meson.build
+2 -1
@@ -130,7 +130,8 @@ endif
130 if have_rust
131 rustc_args = [find_program('scripts/rust/rustc_args.py'),
132 '--rustc-version', rustc.version(),
133 - '--workspace', meson.project_source_root() / 'rust']
133 + '--workspace', meson.project_source_root()]
134 +
135 rustfmt = find_program('rustfmt', required: false)
136
137 rustc_lint_args = run_command(rustc_args, '--lints',
rust/meson.build
+12 -25
@@ -4,31 +4,18 @@ else
4 message('Rust enabled but it is only used by system emulators.')
5 endif
6
7 -subproject('anyhow-1-rs', required: true)
8 -subproject('bilge-0.2-rs', required: true)
9 -subproject('bilge-impl-0.2-rs', required: true)
10 -subproject('foreign-0.3-rs', required: true)
11 -subproject('glib-sys-0.21-rs', required: true)
12 -subproject('libc-0.2-rs', required: true)
13 -subproject('probe-0.5-rs', required: true)
14 -
15 -anyhow_rs = dependency('anyhow-1-rs')
16 -bilge_rs = dependency('bilge-0.2-rs')
17 -bilge_impl_rs = dependency('bilge-impl-0.2-rs')
18 -foreign_rs = dependency('foreign-0.3-rs')
19 -glib_sys_rs = dependency('glib-sys-0.21-rs')
20 -libc_rs = dependency('libc-0.2-rs')
21 -probe_rs = dependency('probe-0.5-rs')
22 -
23 -subproject('proc-macro2-1-rs', required: true)
24 -subproject('quote-1-rs', required: true)
25 -subproject('syn-2-rs', required: true)
26 -subproject('attrs-0.2-rs', required: true)
27 -
28 -quote_rs_native = dependency('quote-1-rs', native: true)
29 -syn_rs_native = dependency('syn-2-rs', native: true)
30 -proc_macro2_rs_native = dependency('proc-macro2-1-rs', native: true)
31 -attrs_rs_native = dependency('attrs-0.2-rs', native: true)
7 +cargo_ws = import('rust').workspace()
8 +anyhow_rs = cargo_ws.subproject('anyhow').dependency()
9 +bilge_rs = cargo_ws.subproject('bilge').dependency()
10 +bilge_impl_rs = cargo_ws.subproject('bilge-impl').dependency()
11 +foreign_rs = cargo_ws.subproject('foreign').dependency()
12 +glib_sys_rs = cargo_ws.subproject('glib-sys').dependency()
13 +libc_rs = cargo_ws.subproject('libc').dependency()
14 +probe_rs = cargo_ws.subproject('probe').dependency()
15 +quote_rs_native = cargo_ws.subproject('quote').dependency()
16 +syn_rs_native = cargo_ws.subproject('syn').dependency()
17 +proc_macro2_rs_native = cargo_ws.subproject('proc-macro2').dependency()
18 +attrs_rs_native = cargo_ws.subproject('attrs').dependency()
19
20 genrs = []
21
subprojects/anyhow-1-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = anyhow-1.0.98
3 source_url = https://crates.io/api/v1/crates/anyhow/1.0.98/download
4 source_filename = anyhow-1.0.98.tar.gz
5 source_hash = e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487
6 -#method = cargo
6 +method = cargo
7 patch_directory = anyhow-1-rs
subprojects/arbitrary-int-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = arbitrary-int-1.2.7
3 source_url = https://crates.io/api/v1/crates/arbitrary-int/1.2.7/download
4 source_filename = arbitrary-int-1.2.7.tar.gz
5 source_hash = c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d
6 -#method = cargo
6 +method = cargo
7 patch_directory = arbitrary-int-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/attrs-0.2-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = attrs-0.2.9
3 source_url = https://crates.io/api/v1/crates/attrs/0.2.9/download
4 source_filename = attrs-0.2.9.tar.gz
5 source_hash = 2a207d40f43de65285f3de0509bb6cb16bc46098864fce957122bbacce327e5f
6 -#method = cargo
6 +method = cargo
7 patch_directory = attrs-0.2-rs
subprojects/bilge-0.2-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = bilge-0.2.0
3 source_url = https://crates.io/api/v1/crates/bilge/0.2.0/download
4 source_filename = bilge-0.2.0.tar.gz
5 source_hash = dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e67b57
6 -#method = cargo
6 +method = cargo
7 patch_directory = bilge-0.2-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/bilge-impl-0.2-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = bilge-impl-0.2.0
3 source_url = https://crates.io/api/v1/crates/bilge-impl/0.2.0/download
4 source_filename = bilge-impl-0.2.0.tar.gz
5 source_hash = feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000adb2d8
6 -#method = cargo
6 +method = cargo
7 patch_directory = bilge-impl-0.2-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/either-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = either-1.12.0
3 source_url = https://crates.io/api/v1/crates/either/1.12.0/download
4 source_filename = either-1.12.0.tar.gz
5 source_hash = 3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b
6 -#method = cargo
6 +method = cargo
7 patch_directory = either-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/foreign-0.3-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = foreign-0.3.1
3 source_url = https://crates.io/api/v1/crates/foreign/0.3.1/download
4 source_filename = foreign-0.3.1.tar.gz
5 source_hash = 17ca1b5be8c9d320daf386f1809c7acc0cb09accbae795c2001953fa50585846
6 -#method = cargo
6 +method = cargo
7 patch_directory = foreign-0.3-rs
subprojects/glib-sys-0.21-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = glib-sys-0.21.2
3 source_url = https://crates.io/api/v1/crates/glib-sys/0.21.2/download
4 source_filename = glib-sys-0.21.2.tar.gz
5 source_hash = d09d3d0fddf7239521674e57b0465dfbd844632fec54f059f7f56112e3f927e1
6 -#method = cargo
6 +method = cargo
7 patch_directory = glib-sys-0.21-rs
subprojects/itertools-0.11-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = itertools-0.11.0
3 source_url = https://crates.io/api/v1/crates/itertools/0.11.0/download
4 source_filename = itertools-0.11.0.tar.gz
5 source_hash = b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57
6 -#method = cargo
6 +method = cargo
7 patch_directory = itertools-0.11-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/libc-0.2-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = libc-0.2.162
3 source_url = https://crates.io/api/v1/crates/libc/0.2.162/download
4 source_filename = libc-0.2.162.tar.gz
5 source_hash = 18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398
6 -#method = cargo
6 +method = cargo
7 patch_directory = libc-0.2-rs
subprojects/probe-0.5-rs.wrap
+1 -1
@@ -3,5 +3,5 @@ directory = probe-0.5.2
3 source_url = https://crates.io/api/v1/crates/probe/0.5.2/download
4 source_filename = probe-0.5.2.tar.gz
5 source_hash = 136558b6e1ebaecc92755d0ffaf9421f519531bed30cc2ad23b22cb00965cc5e
6 -#method = cargo
6 +method = cargo
7 patch_directory = probe-0.5-rs
subprojects/proc-macro-error-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = proc-macro-error-1.0.4
3 source_url = https://crates.io/api/v1/crates/proc-macro-error/1.0.4/download
4 source_filename = proc-macro-error-1.0.4.tar.gz
5 source_hash = da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c
6 -#method = cargo
6 +method = cargo
7 patch_directory = proc-macro-error-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/proc-macro-error-attr-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = proc-macro-error-attr-1.0.4
3 source_url = https://crates.io/api/v1/crates/proc-macro-error-attr/1.0.4/download
4 source_filename = proc-macro-error-attr-1.0.4.tar.gz
5 source_hash = a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869
6 -#method = cargo
6 +method = cargo
7 patch_directory = proc-macro-error-attr-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/proc-macro2-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = proc-macro2-1.0.95
3 source_url = https://crates.io/api/v1/crates/proc-macro2/1.0.95/download
4 source_filename = proc-macro2-1.0.95.0.tar.gz
5 source_hash = 02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778
6 -#method = cargo
6 +method = cargo
7 patch_directory = proc-macro2-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/quote-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = quote-1.0.36
3 source_url = https://crates.io/api/v1/crates/quote/1.0.36/download
4 source_filename = quote-1.0.36.0.tar.gz
5 source_hash = 0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7
6 -#method = cargo
6 +method = cargo
7 patch_directory = quote-1-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/syn-2-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = syn-2.0.104
3 source_url = https://crates.io/api/v1/crates/syn/2.0.104/download
4 source_filename = syn-2.0.104.0.tar.gz
5 source_hash = 17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40
6 -#method = cargo
6 +method = cargo
7 patch_directory = syn-2-rs
8
9 # bump this version number on every change to meson.build or the patches:
subprojects/unicode-ident-1-rs.wrap
+1 -1
@@ -3,7 +3,7 @@ directory = unicode-ident-1.0.12
3 source_url = https://crates.io/api/v1/crates/unicode-ident/1.0.12/download
4 source_filename = unicode-ident-1.0.12.tar.gz
5 source_hash = 3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b
6 -#method = cargo
6 +method = cargo
7 patch_directory = unicode-ident-1-rs
8
9 # bump this version number on every change to meson.build or the patches: