mbox series

[v2,00/12] rust: improved integration with cargo

Message ID 20241115163944.1917393-1-pbonzini@redhat.com (mailing list archive)
Headers show
Series rust: improved integration with cargo | expand

Message

Paolo Bonzini Nov. 15, 2024, 4:39 p.m. UTC
While we're not sure where we'll be going in the future, for now
using cargo remains an important part of developing QEMU Rust code.
This is because cargo is the easiest way to run clippy, rustfmt,
rustdoc.  Cargo also allows working with doc tests, though there are
pretty much none yet, and provides tools such as "cargo expand".

This series aims at improving the integration with cargo and
cargo-based tooling, including rust-analyzer.

First, while it is currently possible to run cargo on the rust/
directory, this has the issue that the bindings.rs must be placed by hand
in the source tree.  Therefore, this series starts by allowing cargo to
"just work" when run in a "meson devenv" environment:

    pyvenv/bin/meson devenv -w ../rust cargo clippy --tests
    pyvenv/bin/meson devenv -w ../rust cargo fmt

If you are going to use cargo repeatedly, invoking just

    pyvenv/bin/meson devenv

will put you in a shell where commands like 'cargo clippy' just work.
For simplicity, I am also adding targets 'make clippy', 'make rustfmt',
'make rustdoc'.

Secondly, one problem with mixing Cargo and meson is having to redo the
configuration of "lints" in both sides.  This series standardizes
on using Cargo.toml to configure the build, and bringing the flags
over to build.ninja with extensions to the existing rustc_args.py script.
The RFC didn't have any objection but also no enthusiastic approval,
so once more if the additions to the script seem to be too large I'm
open to scrapping the idea.  I organizes the changes so that the changes
are split over multiple patches, but it does not make much sense to
only keep some of them.

Finally, this series adds a CI job that runs rustfmt, clippy, and
rustdoc.

I checked that you can point rust-analyzer at the sources, by adding
MESON_BUILD_ROOT in the rust-analyzer.cargo.extraEnv setting, too.  I'm
not sure if there's a better way.  We need to document all this somewhere
but Manos said he's working on documentation, so I'll let him post what
he has and possibly integrate it later.
 
Compared to the RFC there are a smattering of fixes in meson.build,
slightly different set of lints (for example ptr_constness_cast has
issues with 1.63.0) and the changes to support rust-analyzer.

Also, doctests for now are not supported.  Building and running them with
"rustdoc" is not hard, but there are some complications because they are
integration tests for all intents and purposes; and therefore they need
linker options to include non-Rust build products.  For now "cargo test
--doc" works, but that's not going to remain the case when for example
QOM doctests are added.  However it should be possible with some effort
to build them with Meson just like rust-qemu-api-integration, and run
them normally from "make check".

Paolo

RFC->v1:
new patch 1
patch 2: new commit message
         use symlink in OUT_DIR as suggested by Junjie
patch 3: mention that rustc_args may be needed for other crates in the future
patch 6: change unexpected_cfgs to deny
         allow running rustc_args.py with --workspace and without Cargo.toml
patch 8: adjust commit message
         better fix for ptr_constness_cast in rust/hw/char/pl011/src/device.rs
patch 9: add should_implement_trait and shadow_unrelated
         drop ptr_cast_constness until 1.65.0
patch 10: make cargo optional
          add rustdoc per rust/qemu-api/README.md
patch 12: move to static_checks.yml, remove doctests


Paolo Bonzini (12):
  rust: apply --cfg MESON to all crates
  rust: allow using build-root bindings.rs from cargo
  rust: build: move rustc_args.py invocation to qemu-api crate
  rust: build: restrict --cfg generation to only required symbols
  rust: build: generate lint flags from Cargo.toml
  rust: cargo: store desired warning levels in workspace Cargo.toml
  rust: build: move strict lints handling to rustc_args.py
  rust: fix a couple style issues from clippy
  rust: build: establish a baseline of lints across all crates
  rust: build: add "make clippy", "make rustfmt", "make rustdoc"
  rust: ci: add job that runs Rust tools
  rust: fix doc test syntax

 meson.build                                   |  57 +++---
 .gitlab-ci.d/static_checks.yml                |  23 +++
 rust/Cargo.toml                               |  79 ++++++++
 rust/hw/char/pl011/.gitignore                 |   2 -
 rust/hw/char/pl011/Cargo.toml                 |   3 +
 rust/hw/char/pl011/src/device.rs              |   8 +-
 rust/hw/char/pl011/src/lib.rs                 |  19 +-
 rust/hw/char/pl011/src/memory_ops.rs          |   4 +-
 rust/meson.build                              |  22 +++
 rust/qemu-api-macros/Cargo.toml               |   3 +
 rust/qemu-api/.gitignore                      |   2 +-
 rust/qemu-api/Cargo.toml                      |   5 +-
 rust/qemu-api/README.md                       |  10 +-
 rust/qemu-api/build.rs                        |  39 +++-
 rust/qemu-api/meson.build                     |   6 +-
 rust/qemu-api/src/bindings.rs                 |  29 +++
 rust/qemu-api/src/lib.rs                      |  22 ---
 rust/qemu-api/src/zeroable.rs                 |   6 +-
 rust/qemu-api/tests/tests.rs                  |   2 +-
 scripts/rust/rustc_args.py                    | 181 ++++++++++++++++--
 .../dockerfiles/fedora-rust-nightly.docker    |   4 +
 tests/lcitool/refresh                         |   4 +
 22 files changed, 419 insertions(+), 111 deletions(-)
 delete mode 100644 rust/hw/char/pl011/.gitignore
 create mode 100644 rust/qemu-api/src/bindings.rs