From: Marc-André Lureau <marcandre.lur...@redhat.com> Hi,
Among the QEMU developers, there is a desire to use Rust. (see previous thread from Stefan "Why QEMU should move from C to Rust", the rust-vmm related projects and other experiments). Thanks to our QAPI type system and the associate code generator, it is relatively straightforward to create Rust bindings for the generated C types (also called sys/ffi binding) and functions. (rust-bindgen could probably do a similar job, but it would probably bring other issues). This provides an important internal API already. Slightly more complicated is to expose a Rust API for those, and provide convenient conversions C<->Rust. Taking inspiration from glib-rs binding, I implemented a simplified version of the FromGlib/ToGlib traits, with simpler ownership model, sufficient for QAPI needs. The usage is relatively simple: - from_qemu_none(ptr: *const sys::P) -> T Return a Rust type T for a const ffi pointer P. - from_qemu_full(ptr: *mut sys::P) -> T Return a Rust type T for a ffi pointer P, taking ownership. - T::to_qemu_none() -> Stash<P> Returns a borrowed ffi pointer P (using a Stash to destroy "glue" storage data, if any). - T::to_qemu_full() -> P Returns a ffi pointer P. (P resources are leaked/passed to C/ffi) With those traits, it's relatively easy to implement the QMP callbacks. With enough interest, we could eventually add new commands in Rust, and start rewriting QGA in Rust, as it is a simple service. See qga/qmp/ for some examples. QEMU would be the next obvious target. My biggest pain-point right now is the handling of 'if' conditions. I tried different approaches, but none of them are satisfying. I am planning to tackle this next again, along with full QEMU API schema support and hopefully some t= est integration. v2: - split the original patch in smaller patches and more digestable form - dropped the DBus interface experiment from this series - various build-sys improvements, new configure options --with-rust(-target) - various attempts at better meson integration, finally satisfied enough wit= h the current solution, which handles getting link flags from Rust sanely. (more meson stuff to come to handle config-host/features mapping etc). - rebased, QGA QMP now uses unions, added support for it. - start a common crate (which re-surfaced issues with foreign types and trai= ts, worked around with a NewPtr wrapper) - explicit errors when ifcond are presents (after various unsucessful attemp= ts, I will try to tackle it in v3) - mingw cross compilation support - some attempts to add it to CI - actually implement {get,set}-vcpus - vendor the external crates Marc-Andr=C3=A9 Lureau (15): mingw: fix error __USE_MINGW_ANSI_STDIO redefined scripts/qapi: teach c_param_type() to return const argument type build-sys: add --with-rust{-target} & basic build infrastructure build-sys: add a cargo-wrapper script qga/rust: build and link an empty static library rust: provide a common crate for QEMU scripts/qapi: add Rust sys bindings generation qga/rust: generate QGA QAPI sys bindings scripts/qapi: add generation of Rust bindings for types qga/rust: build Rust types qga: add qmp! macro helper qga: implement get-host-name in Rust qga: implement {get,set}-vcpus in Rust travis: add Rust rust: use vendored-sources .cargo/config | 5 + .gitmodules | 3 + .travis.yml | 18 +- Cargo.toml | 5 + configure | 26 ++ include/qemu/osdep.h | 10 - meson.build | 29 ++- migration/dirtyrate.c | 3 +- qga/Cargo.toml | 20 ++ qga/commands-posix.c | 159 ------------- qga/commands-win32.c | 76 ------ qga/commands.c | 34 +-- qga/lib.rs | 5 + qga/meson.build | 30 ++- qga/qapi.rs | 6 + qga/qapi_sys.rs | 5 + qga/qmp/hostname.rs | 9 + qga/qmp/mod.rs | 61 +++++ qga/qmp/vcpus.rs | 161 +++++++++++++ rust/common/Cargo.toml | 11 + rust/common/src/error.rs | 109 +++++++++ rust/common/src/lib.rs | 10 + rust/common/src/qemu.rs | 30 +++ rust/common/src/sys.rs | 58 +++++ rust/common/src/translate.rs | 309 ++++++++++++++++++++++++ rust/vendored | 1 + scripts/cargo_wrapper.py | 102 ++++++++ scripts/qapi-gen.py | 18 +- scripts/qapi/rs.py | 204 ++++++++++++++++ scripts/qapi/rs_sys.py | 254 ++++++++++++++++++++ scripts/qapi/rs_types.py | 447 +++++++++++++++++++++++++++++++++++ scripts/qapi/schema.py | 14 +- tests/test-bitmap.c | 1 - tests/test-qga.c | 4 + util/oslib-posix.c | 35 --- util/oslib-win32.c | 13 - 36 files changed, 1962 insertions(+), 323 deletions(-) create mode 100644 .cargo/config create mode 100644 Cargo.toml create mode 100644 qga/Cargo.toml create mode 100644 qga/lib.rs create mode 100644 qga/qapi.rs create mode 100644 qga/qapi_sys.rs create mode 100644 qga/qmp/hostname.rs create mode 100644 qga/qmp/mod.rs create mode 100644 qga/qmp/vcpus.rs create mode 100644 rust/common/Cargo.toml create mode 100644 rust/common/src/error.rs create mode 100644 rust/common/src/lib.rs create mode 100644 rust/common/src/qemu.rs create mode 100644 rust/common/src/sys.rs create mode 100644 rust/common/src/translate.rs create mode 160000 rust/vendored create mode 100644 scripts/cargo_wrapper.py create mode 100644 scripts/qapi/rs.py create mode 100644 scripts/qapi/rs_sys.py create mode 100644 scripts/qapi/rs_types.py --=20 2.28.0