]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
rust: move binding generation to bindings/
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Wed, 3 Dec 2025 15:46:16 +0000 (16:46 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 27 Jan 2026 07:57:52 +0000 (08:57 +0100)
Move raw FFI bindings generation to separate crates.  This makes it
possible to reuse bindgen declarations for a header file in its
dependencies (this was not the case before this change), while keeping
multiple -sys crates to avoid rebuilding all the code whenever
something changes.

Because the -sys crates are generated in dependency order, this also
enforces that the crates are organized in something that resembles
the dependencies between C headers.

The meson.build for rust-safe crates becomes simpler, and it should be
possible in the future to let Meson's cargo support handle most of it.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
[General cleanup and Python script. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
80 files changed:
docs/devel/rust.rst
meson.build
rust/Cargo.lock
rust/bindings/build.rs [moved from rust/util/build.rs with 55% similarity]
rust/bindings/chardev-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/chardev-sys/build.rs [new symlink]
rust/bindings/chardev-sys/lib.rs [moved from rust/chardev/src/bindings.rs with 84% similarity]
rust/bindings/chardev-sys/meson.build [new file with mode: 0644]
rust/bindings/chardev-sys/wrapper.h [new file with mode: 0644]
rust/bindings/generate_bindgen_args.py [new file with mode: 0644]
rust/bindings/hwcore-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/hwcore-sys/build.rs [new symlink]
rust/bindings/hwcore-sys/lib.rs [moved from rust/hw/core/src/bindings.rs with 71% similarity]
rust/bindings/hwcore-sys/meson.build [new file with mode: 0644]
rust/bindings/hwcore-sys/wrapper.h [new file with mode: 0644]
rust/bindings/meson.build [new file with mode: 0644]
rust/bindings/migration-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/migration-sys/build.rs [new symlink]
rust/bindings/migration-sys/lib.rs [new file with mode: 0644]
rust/bindings/migration-sys/meson.build [new file with mode: 0644]
rust/bindings/migration-sys/wrapper.h [new file with mode: 0644]
rust/bindings/qom-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/qom-sys/build.rs [new symlink]
rust/bindings/qom-sys/lib.rs [moved from rust/qom/src/bindings.rs with 85% similarity]
rust/bindings/qom-sys/meson.build [new file with mode: 0644]
rust/bindings/qom-sys/wrapper.h [new file with mode: 0644]
rust/bindings/system-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/system-sys/build.rs [new symlink]
rust/bindings/system-sys/lib.rs [moved from rust/system/src/bindings.rs with 88% similarity]
rust/bindings/system-sys/meson.build [new file with mode: 0644]
rust/bindings/system-sys/wrapper.h [new file with mode: 0644]
rust/bindings/util-sys/Cargo.toml [new file with mode: 0644]
rust/bindings/util-sys/build.rs [new symlink]
rust/bindings/util-sys/lib.rs [moved from rust/util/src/bindings.rs with 88% similarity]
rust/bindings/util-sys/meson.build [new file with mode: 0644]
rust/bindings/util-sys/wrapper.h [new file with mode: 0644]
rust/bql/Cargo.toml
rust/bql/build.rs [deleted symlink]
rust/bql/meson.build
rust/bql/src/bindings.rs [deleted file]
rust/bql/src/lib.rs
rust/bql/wrapper.h [deleted file]
rust/chardev/Cargo.toml
rust/chardev/build.rs [deleted symlink]
rust/chardev/meson.build
rust/chardev/src/lib.rs
rust/chardev/wrapper.h [deleted file]
rust/hw/char/pl011/build.rs
rust/hw/char/pl011/meson.build
rust/hw/char/pl011/src/bindings.rs
rust/hw/core/Cargo.toml
rust/hw/core/build.rs [deleted symlink]
rust/hw/core/meson.build
rust/hw/core/src/lib.rs
rust/hw/core/src/qdev.rs
rust/hw/core/src/sysbus.rs
rust/hw/core/wrapper.h [deleted file]
rust/meson.build
rust/migration/Cargo.toml
rust/migration/build.rs [deleted symlink]
rust/migration/meson.build
rust/migration/src/bindings.rs [deleted file]
rust/migration/src/lib.rs
rust/migration/src/vmstate.rs
rust/migration/wrapper.h [deleted file]
rust/qom/Cargo.toml
rust/qom/build.rs [deleted symlink]
rust/qom/meson.build
rust/qom/src/lib.rs
rust/qom/wrapper.h [deleted file]
rust/system/Cargo.toml
rust/system/build.rs [deleted symlink]
rust/system/meson.build
rust/system/src/lib.rs
rust/system/src/memory.rs
rust/system/wrapper.h [deleted file]
rust/util/Cargo.toml
rust/util/meson.build
rust/util/src/lib.rs
rust/util/wrapper.h [deleted file]

index 79c26d9d165cd221a2b8897935acf32b2ad40d5a..67ea84539a2a2d25ce33e6e6e05899faa751d082 100644 (file)
@@ -339,6 +339,63 @@ Here are some things to keep in mind when working on the QEMU Rust crate.
   or a macro) where it can be documented and tested.  If needed, include
   toy versions of the code in the documentation.
 
+FFI Binding Generation
+''''''''''''''''''''''
+
+QEMU's Rust integration uses multiple ``*-sys`` crates that contain raw FFI
+bindings to different QEMU subsystems. These crates mirror the dependency
+structure that meson.build uses for C code, and which is reflected in
+``static_library()`` declarations. For example:
+
+* util-sys: Basic utilities (no dependencies)
+* qom-sys: QEMU Object Model (depends on util-sys)
+* chardev-sys: Character devices (depends on qom-sys, util-sys)
+* hwcore-sys: Hardware core (depends on qom-sys, util-sys)
+* migration-sys: Migration (depends on util-sys)
+* system-sys: System-level APIs (depends on all others)
+
+Having multiple crates avoids massive rebuilds of all Rust code when C headers
+are changed. On the other hand, bindgen is not aware of how headers are split
+across crates, and therefore it would generate declarations for dependencies
+again. These duplicate declarations are not only large, they create distinct
+types and therefore they are incompatible with each other.
+
+Bindgen Configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+Bindgen options such as symbol blocklists or how to configure enums can be
+defined in each crate's ``Cargo.toml`` via a ``[package.metadata.bindgen]`` section.
+For example::
+
+    [package.metadata.bindgen]
+    header = "wrapper.h"                    # Main header file for this crate
+    rustified-enum = ["QEMUClockType"]      # Enums to generate as Rust enums
+    bitfield-enum = ["VMStateFlags"]        # Enums to treat as bitfields
+    blocklist-function = [                  # Functions to exclude
+        "vmstate_register_ram",
+        "vmstate_unregister_ram"
+    ]
+    additional-files = [                    # Extra files to allowlist
+        "include/system/memory_ldst.*"
+    ]
+
+All bindgen options are supported in the metadata section. The complete list
+can be found in ``rust/bindings/generate_bindgen_args.py``.
+
+Dependency Management
+~~~~~~~~~~~~~~~~~~~~~
+
+By examining the dependency chain before bindgen creates the code for
+the ``*-sys`` crates, the build system ensures that header files included in
+one crate are blocked from appearing in dependent crates, thus avoiding
+duplicate definitions. Dependent crates can import the definition via
+"use" statements.
+
+This dependency-aware binding generation is handled automatically by
+``rust/bindings/generate_bindgen_args.py``, which processes the Cargo.toml
+files in dependency order and generates appropriate ``--allowlist-file`` and
+``--blocklist-file`` arguments for bindgen.
+
 Writing procedural macros
 '''''''''''''''''''''''''
 
index a84f14258b01603dad0bcb9bb8204aede2ffe33a..668f1aa919c109a82905a47872943bbd375f035e 100644 (file)
@@ -4169,9 +4169,8 @@ if have_rust
     '--with-derive-default',
     '--no-layout-tests',
     '--no-prepend-enum-name',
-    '--allowlist-file', meson.project_source_root() + '/include/.*',
-    '--allowlist-file', meson.project_build_root() + '/.*',
     '--blocklist-file', glib_pc.get_variable('includedir') + '/glib-2.0/.*',
+    '--blocklist-file', meson.project_source_root() + '/include/qemu/typedefs.h',
     '--blocklist-type', '.*_([a-z]*autoptr)$',
     ]
   if not rustfmt.found()
index 78452c3db9b47c93ad03359ef71b70fd07406854..801ac5f4f51dd63dd1993f62baf00153996e13fd 100644 (file)
@@ -59,6 +59,7 @@ name = "bql"
 version = "0.1.0"
 dependencies = [
  "glib-sys",
+ "util-sys",
 ]
 
 [[package]]
@@ -76,6 +77,7 @@ name = "chardev"
 version = "0.1.0"
 dependencies = [
  "bql",
+ "chardev-sys",
  "common",
  "glib-sys",
  "migration",
@@ -83,6 +85,16 @@ dependencies = [
  "util",
 ]
 
+[[package]]
+name = "chardev-sys"
+version = "0.1.0"
+dependencies = [
+ "common",
+ "glib-sys",
+ "qom-sys",
+ "util-sys",
+]
+
 [[package]]
 name = "common"
 version = "0.1.0"
@@ -156,6 +168,7 @@ dependencies = [
  "chardev",
  "common",
  "glib-sys",
+ "hwcore-sys",
  "migration",
  "qemu_macros",
  "qom",
@@ -163,6 +176,19 @@ dependencies = [
  "util",
 ]
 
+[[package]]
+name = "hwcore-sys"
+version = "0.1.0"
+dependencies = [
+ "chardev-sys",
+ "common",
+ "glib-sys",
+ "migration-sys",
+ "qom-sys",
+ "system-sys",
+ "util-sys",
+]
+
 [[package]]
 name = "indexmap"
 version = "2.11.4"
@@ -201,10 +227,20 @@ dependencies = [
  "bql",
  "common",
  "glib-sys",
+ "migration-sys",
  "qemu_macros",
  "util",
 ]
 
+[[package]]
+name = "migration-sys"
+version = "0.1.0"
+dependencies = [
+ "common",
+ "glib-sys",
+ "util-sys",
+]
+
 [[package]]
 name = "pkg-config"
 version = "0.3.32"
@@ -287,9 +323,18 @@ dependencies = [
  "glib-sys",
  "migration",
  "qemu_macros",
+ "qom-sys",
  "util",
 ]
 
+[[package]]
+name = "qom-sys"
+version = "0.1.0"
+dependencies = [
+ "glib-sys",
+ "util-sys",
+]
+
 [[package]]
 name = "quote"
 version = "1.0.36"
@@ -306,6 +351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
 dependencies = [
  "serde_core",
+ "serde_derive",
 ]
 
 [[package]]
@@ -358,9 +404,12 @@ dependencies = [
 name = "system"
 version = "0.1.0"
 dependencies = [
+ "bql",
  "common",
  "glib-sys",
+ "migration",
  "qom",
+ "system-sys",
  "util",
 ]
 
@@ -377,6 +426,17 @@ dependencies = [
  "version-compare",
 ]
 
+[[package]]
+name = "system-sys"
+version = "0.1.0"
+dependencies = [
+ "common",
+ "glib-sys",
+ "migration-sys",
+ "qom-sys",
+ "util-sys",
+]
+
 [[package]]
 name = "target-lexicon"
 version = "0.13.2"
@@ -454,6 +514,14 @@ dependencies = [
  "foreign",
  "glib-sys",
  "libc",
+ "util-sys",
+]
+
+[[package]]
+name = "util-sys"
+version = "0.1.0"
+dependencies = [
+ "glib-sys",
 ]
 
 [[package]]
similarity index 55%
rename from rust/util/build.rs
rename to rust/bindings/build.rs
index 5654d1d5624d9f6662a59e3d52872ba810c924f6..a466958d71349eb2f61eac417f9a120b07b4213d 100644 (file)
@@ -10,25 +10,25 @@ use std::{env, fs::remove_file, io::Result, path::Path};
 
 fn main() -> Result<()> {
     let manifest_dir = env!("CARGO_MANIFEST_DIR");
-    let file = if let Ok(root) = env::var("MESON_BUILD_ROOT") {
-        let sub = get_rust_subdir(manifest_dir).unwrap();
-        format!("{root}/{sub}/bindings.inc.rs")
-    } else {
-        // Placing bindings.inc.rs in the source directory is supported
-        // but not documented or encouraged.
-        format!("{manifest_dir}/src/bindings.inc.rs")
-    };
+    let root = env::var("MESON_BUILD_ROOT").expect(concat!(
+        "\n",
+        "    MESON_BUILD_ROOT not found.  Maybe you wanted one of\n",
+        "    `make clippy`, `make rustfmt`, `make rustdoc`?\n",
+        "\n",
+        "    For other uses of `cargo`, start a subshell with\n",
+        "    `pyvenv/bin/meson devenv`, or point MESON_BUILD_ROOT to\n",
+        "    the top of the build tree."
+    ));
 
+    let sub = get_rust_subdir(manifest_dir).unwrap();
+    let file = format!("{root}/{sub}/bindings.inc.rs");
     let file = Path::new(&file);
-    if !Path::new(&file).exists() {
+
+    if !file.exists() {
         panic!(concat!(
             "\n",
-            "    No generated C bindings found! Maybe you wanted one of\n",
-            "    `make clippy`, `make rustfmt`, `make rustdoc`?\n",
-            "\n",
-            "    For other uses of `cargo`, start a subshell with\n",
-            "    `pyvenv/bin/meson devenv`, or point MESON_BUILD_ROOT to\n",
-            "    the top of the build tree."
+            "    No generated C bindings found! Run `make` first; or maybe you\n",
+            "    wanted one of `make clippy`, `make rustfmt`, `make rustdoc`?\n",
         ));
     }
 
diff --git a/rust/bindings/chardev-sys/Cargo.toml b/rust/bindings/chardev-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..6aa0025
--- /dev/null
@@ -0,0 +1,28 @@
+[package]
+name = "chardev-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/chardev"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+common = { path = "../../common" }
+qom-sys = { path = "../qom-sys" }
+util-sys = { path = "../util-sys" }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
+rustified-enum = ["QEMUChrEvent"]
diff --git a/rust/bindings/chardev-sys/build.rs b/rust/bindings/chardev-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
similarity index 84%
rename from rust/chardev/src/bindings.rs
rename to rust/bindings/chardev-sys/lib.rs
index 360b30d6a34310353d5e044a011b2f57f4db1ce4..903f6fc492ae17371d3bb2536974dda68a25a631 100644 (file)
 )]
 
 use common::Zeroable;
-use glib_sys::{
-    gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GMainContext, GPollFD,
-    GPtrArray, GSList, GSource, GSourceFunc,
-};
+use glib_sys::{gboolean, guint, GIOCondition, GMainContext, GSource, GSourceFunc};
+use qom_sys::{Object, ObjectClass};
+use util_sys::{Error, IOCanReadHandler, IOReadHandler, QemuOpts};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
diff --git a/rust/bindings/chardev-sys/meson.build b/rust/bindings/chardev-sys/meson.build
new file mode 100644 (file)
index 0000000..458075b
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_chardev_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['chardev-sys'].split(),
+  kwargs: bindgen_kwargs)
+_chardev_sys_rs = static_library(
+  'chardev_sys',
+  structured_sources(['lib.rs', _bindgen_chardev_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [glib_sys_rs, common_rs, qom_sys_rs, util_sys_rs],
+)
+
+chardev_sys_rs = declare_dependency(link_with: [_chardev_sys_rs])
diff --git a/rust/bindings/chardev-sys/wrapper.h b/rust/bindings/chardev-sys/wrapper.h
new file mode 100644 (file)
index 0000000..b8ddc36
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+#include "qemu/osdep.h"
+
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
+#include "chardev/char-serial.h"
diff --git a/rust/bindings/generate_bindgen_args.py b/rust/bindings/generate_bindgen_args.py
new file mode 100644 (file)
index 0000000..8e526d7
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""
+Generate bindgen arguments from Cargo.toml metadata for QEMU's Rust FFI bindings.
+
+Author: Paolo Bonzini <pbonzini@redhat.com>
+
+Copyright (C) 2025 Red Hat, Inc.
+
+This script processes Cargo.toml file for QEMU's bindings crates (util-sys,
+chardev-sys, qom-sys, etc.); it generates bindgen command lines that allow
+easy customization and that export the right headers in each bindings crate.
+
+For detailed information, see docs/devel/rust.rst.
+"""
+
+import os
+import re
+import sys
+import argparse
+from pathlib import Path
+from dataclasses import dataclass
+from typing import Iterable, List, Dict, Any
+
+try:
+    import tomllib
+except ImportError:
+    import tomli as tomllib  # type: ignore
+
+INCLUDE_RE = re.compile(r'^#include\s+"([^"]+)"')
+OPTIONS = [
+    "bitfield-enum",
+    "newtype-enum",
+    "newtype-global-enum",
+    "rustified-enum",
+    "rustified-non-exhaustive-enum",
+    "constified-enum",
+    "constified-enum-module",
+    "normal-alias",
+    "new-type-alias",
+    "new-type-alias-deref",
+    "bindgen-wrapper-union",
+    "manually-drop-union",
+    "blocklist-type",
+    "blocklist-function",
+    "blocklist-item",
+    "blocklist-file",
+    "blocklist-var",
+    "opaque-type",
+    "no-partialeq",
+    "no-copy",
+    "no-debug",
+    "no-default",
+    "no-hash",
+    "must-use-type",
+    "with-derive-custom",
+    "with-derive-custom-struct",
+    "with-derive-custom-enum",
+    "with-derive-custom-union",
+    "with-attribute-custom",
+    "with-attribute-custom-struct",
+    "with-attribute-custom-enum",
+    "with-attribute-custom-union",
+]
+
+
+@dataclass
+class BindgenInfo:
+    cmd_args: List[str]
+    inputs: List[str]
+
+
+def extract_includes(lines: Iterable[str]) -> List[str]:
+    """Extract #include directives from a file."""
+    includes: List[str] = []
+    for line in lines:
+        match = INCLUDE_RE.match(line.strip())
+        if match:
+            includes.append(match.group(1))
+    return includes
+
+
+def build_bindgen_args(metadata: Dict[str, Any]) -> List[str]:
+    """Build command line arguments from [package.metadata.bindgen]."""
+    args: List[str] = []
+    for key, values in metadata.items():
+        if key in OPTIONS:
+            flag = f"--{key}"
+            assert isinstance(values, list)
+            for value in values:
+                args.append(flag)
+                args.append(value)
+
+    return args
+
+
+def main() -> int:
+    parser = argparse.ArgumentParser(
+        description="Generate bindgen arguments from Cargo.toml metadata"
+    )
+    parser.add_argument(
+        "directories", nargs="+", help="Directories containing Cargo.toml files"
+    )
+    parser.add_argument(
+        "-I",
+        "--include-root",
+        default=None,
+        help="Base path for --allowlist-file/--blocklist-file",
+    )
+    parser.add_argument("--source-dir", default=os.getcwd(), help="Source directory")
+    parser.add_argument("-o", "--output", required=True, help="Output file")
+    parser.add_argument("--dep-file", help="Dependency file to write")
+    args = parser.parse_args()
+
+    prev_allowlist_files: Dict[str, object] = {}
+    bindgen_infos: Dict[str, BindgenInfo] = {}
+
+    os.chdir(args.source_dir)
+    include_root = args.include_root or args.source_dir
+    for directory in args.directories:
+        cargo_path = Path(directory) / "Cargo.toml"
+        inputs = [str(Path(args.source_dir) / cargo_path)]
+
+        with open(cargo_path, "rb") as f:
+            cargo_toml = tomllib.load(f)
+
+        metadata = cargo_toml.get("package", {}).get("metadata", {}).get("bindgen", {})
+        input_file = Path(directory) / metadata["header"]
+        inputs.append(str(Path(args.source_dir) / input_file))
+
+        cmd_args = build_bindgen_args(metadata)
+
+        # Each include file is allowed for this file and blocked in the
+        # next ones
+        for blocklist_path in prev_allowlist_files:
+            cmd_args.extend(["--blocklist-file", blocklist_path])
+        with open(input_file, "r", encoding="utf-8", errors="ignore") as f:
+            includes = extract_includes(f)
+        for allowlist_file in includes + metadata.get("additional-files", []):
+            allowlist_path = Path(include_root) / allowlist_file
+            cmd_args.extend(["--allowlist-file", str(allowlist_path)])
+            prev_allowlist_files.setdefault(str(allowlist_path), True)
+
+        bindgen_infos[directory] = BindgenInfo(cmd_args=cmd_args, inputs=inputs)
+
+    # now write the output
+    with open(args.output, "w") as f:
+        for directory, info in bindgen_infos.items():
+            args_sh = " ".join(info.cmd_args)
+            f.write(f"{directory}={args_sh}\n")
+
+    if args.dep_file:
+        with open(args.dep_file, "w") as f:
+            deps: List[str] = []
+            for info in bindgen_infos.values():
+                deps += info.inputs
+            f.write(f"{os.path.basename(args.output)}: {' '.join(deps)}\n")
+
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
diff --git a/rust/bindings/hwcore-sys/Cargo.toml b/rust/bindings/hwcore-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..c20024e
--- /dev/null
@@ -0,0 +1,32 @@
+[package]
+name = "hwcore-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/hwcore"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+common = { path = "../../common" }
+chardev-sys = { path = "../chardev-sys" }
+qom-sys = { path = "../qom-sys" }
+migration-sys = { path = "../migration-sys" }
+util-sys = { path = "../util-sys" }
+system-sys = { path = "../system-sys" }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
+rustified-enum = ["DeviceCategory", "GpioPolarity", "MachineInitPhase", "ResetType"]
+bitfield-enum = ["ClockEvent"]
diff --git a/rust/bindings/hwcore-sys/build.rs b/rust/bindings/hwcore-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
similarity index 71%
rename from rust/hw/core/src/bindings.rs
rename to rust/bindings/hwcore-sys/lib.rs
index db872d38bc7ccd9e50a8beeebc4afe75151f6ec9..8cef4a796193b18e2e14348d4a3a56a1fb175f19 100644 (file)
     clippy::too_many_arguments
 )]
 
-use chardev::bindings::Chardev;
+use chardev_sys::Chardev;
 use common::Zeroable;
-use glib_sys::{GHashTable, GHashTableIter, GList, GPtrArray, GSList};
-use migration::bindings::VMStateDescription;
-use qom::bindings::ObjectClass;
-use system::bindings::MemoryRegion;
-use util::bindings::Error;
+use glib_sys::GSList;
+use migration_sys::VMStateDescription;
+use qom_sys::{
+    InterfaceClass, Object, ObjectClass, ObjectProperty, ObjectPropertyAccessor,
+    ObjectPropertyRelease,
+};
+use util_sys::{Error, QDict, QList};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
@@ -35,8 +37,5 @@ include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
 unsafe impl Send for Property {}
 unsafe impl Sync for Property {}
 
-unsafe impl Send for TypeInfo {}
-unsafe impl Sync for TypeInfo {}
-
 unsafe impl Zeroable for Property__bindgen_ty_1 {}
 unsafe impl Zeroable for Property {}
diff --git a/rust/bindings/hwcore-sys/meson.build b/rust/bindings/hwcore-sys/meson.build
new file mode 100644 (file)
index 0000000..3d51947
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_hwcore_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['hwcore-sys'].split(),
+  kwargs: bindgen_kwargs)
+_hwcore_sys_rs = static_library(
+  'hwcore_sys',
+  structured_sources(['lib.rs', _bindgen_hwcore_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [common_rs, glib_sys_rs, qom_sys_rs, util_sys_rs, migration_sys_rs, chardev_sys_rs],
+)
+
+hwcore_sys_rs = declare_dependency(link_with: [_hwcore_sys_rs])
diff --git a/rust/bindings/hwcore-sys/wrapper.h b/rust/bindings/hwcore-sys/wrapper.h
new file mode 100644 (file)
index 0000000..7c7c3c3
--- /dev/null
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+/*
+ * We block include/qemu/typedefs.h from bindgen, add here symbols
+ * that are needed as opaque types by other functions.
+ */
+typedef struct Clock Clock;
+typedef struct DeviceState DeviceState;
+typedef struct IRQState *qemu_irq;
+typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
+
+/* Once bindings exist, these could move to a different *-sys crate.  */
+typedef struct BlockBackend BlockBackend;
+typedef struct Monitor Monitor;
+typedef struct NetClientState NetClientState;
+
+#include "qemu/osdep.h"
+
+#include "hw/core/clock.h"
+#include "hw/core/irq.h"
+#include "hw/core/qdev-clock.h"
+#include "hw/core/qdev.h"
+#include "hw/core/qdev-properties-system.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/resettable.h"
diff --git a/rust/bindings/meson.build b/rust/bindings/meson.build
new file mode 100644 (file)
index 0000000..c279873
--- /dev/null
@@ -0,0 +1,37 @@
+# Generate bindgen arguments from Cargo.toml metadata
+# Sort these in dependency order, same as the subdir()
+# invocations below.
+bindgen_dirs = [
+  'util-sys',
+  'migration-sys',
+  'qom-sys',
+  'chardev-sys',
+  'hwcore-sys',
+  'system-sys',
+]
+bindgen_args_file = configure_file(
+  command: [files('generate_bindgen_args.py'),
+            '-I', meson.project_source_root() / 'include',
+            '--source-dir', meson.current_source_dir(),
+            '-o', '@OUTPUT@', '--dep-file', '@DEPFILE@'] + bindgen_dirs,
+  output: 'bindgen_args.mak',
+  depfile: 'bindgen_args.d'
+)
+
+# now generate all bindgen files
+bindgen_args_data = keyval.load(bindgen_args_file)
+bindgen_kwargs = {
+  'input': 'wrapper.h',
+  'dependencies': common_ss.all_dependencies(),
+  'output': 'bindings.inc.rs',
+  'include_directories': bindings_incdir,
+  'bindgen_version': ['>=0.60.0'],
+  'c_args': bindgen_c_args,
+}
+
+subdir('util-sys')
+subdir('migration-sys')
+subdir('qom-sys')
+subdir('chardev-sys')
+subdir('hwcore-sys')
+subdir('system-sys')
diff --git a/rust/bindings/migration-sys/Cargo.toml b/rust/bindings/migration-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..88d7742
--- /dev/null
@@ -0,0 +1,28 @@
+[package]
+name = "migration-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/migration"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+common = { path = "../../common" }
+util-sys = { path = "../util-sys" }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
+bitfield-enum = ["MigrationPolicy", "MigrationPriority", "VMStateFlags"]
+blocklist-function = ["vmstate_register_ram", "vmstate_register_ram_global", "vmstate_unregister_ram"]
diff --git a/rust/bindings/migration-sys/build.rs b/rust/bindings/migration-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
diff --git a/rust/bindings/migration-sys/lib.rs b/rust/bindings/migration-sys/lib.rs
new file mode 100644 (file)
index 0000000..7ee30a3
--- /dev/null
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#![allow(
+    dead_code,
+    improper_ctypes_definitions,
+    improper_ctypes,
+    non_camel_case_types,
+    non_snake_case,
+    non_upper_case_globals,
+    unnecessary_transmutes,
+    unsafe_op_in_unsafe_fn,
+    clippy::pedantic,
+    clippy::restriction,
+    clippy::style,
+    clippy::missing_const_for_fn,
+    clippy::ptr_offset_with_cast,
+    clippy::useless_transmute,
+    clippy::missing_safety_doc,
+    clippy::too_many_arguments
+)]
+
+use common::Zeroable;
+use util_sys::{Error, JSONWriter, QEMUFile};
+
+#[cfg(MESON)]
+include!("bindings.inc.rs");
+
+#[cfg(not(MESON))]
+include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
+
+unsafe impl Send for VMStateDescription {}
+unsafe impl Sync for VMStateDescription {}
+
+unsafe impl Send for VMStateField {}
+unsafe impl Sync for VMStateField {}
+
+unsafe impl Send for VMStateInfo {}
+unsafe impl Sync for VMStateInfo {}
+
+// bindgen does not derive Default here
+#[allow(clippy::derivable_impls)]
+impl Default for VMStateFlags {
+    fn default() -> Self {
+        Self(0)
+    }
+}
+
+unsafe impl Zeroable for VMStateFlags {}
+unsafe impl Zeroable for VMStateField {}
+unsafe impl Zeroable for VMStateDescription {}
+
+// The following higher-level helpers could be in "migration"
+// crate when Rust has const trait impl.
+
+pub trait VMStateFlagsExt {
+    const VMS_VARRAY_FLAGS: VMStateFlags;
+}
+
+impl VMStateFlagsExt for VMStateFlags {
+    const VMS_VARRAY_FLAGS: VMStateFlags = VMStateFlags(
+        VMStateFlags::VMS_VARRAY_INT32.0
+            | VMStateFlags::VMS_VARRAY_UINT8.0
+            | VMStateFlags::VMS_VARRAY_UINT16.0
+            | VMStateFlags::VMS_VARRAY_UINT32.0,
+    );
+}
+
+// Add a couple builder-style methods to VMStateField, allowing
+// easy derivation of VMStateField constants from other types.
+impl VMStateField {
+    #[must_use]
+    pub const fn with_version_id(mut self, version_id: i32) -> Self {
+        assert!(version_id >= 0);
+        self.version_id = version_id;
+        self
+    }
+
+    #[must_use]
+    pub const fn with_array_flag(mut self, num: usize) -> Self {
+        assert!(num <= 0x7FFF_FFFFusize);
+        assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) == 0);
+        assert!((self.flags.0 & VMStateFlags::VMS_VARRAY_FLAGS.0) == 0);
+        if (self.flags.0 & VMStateFlags::VMS_POINTER.0) != 0 {
+            self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_POINTER.0);
+            self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0);
+            // VMS_ARRAY_OF_POINTER flag stores the size of pointer.
+            // FIXME: *const, *mut, NonNull and Box<> have the same size as usize.
+            //        Resize if more smart pointers are supported.
+            self.size = std::mem::size_of::<usize>();
+        }
+        self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_SINGLE.0);
+        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY.0);
+        self.num = num as i32;
+        self
+    }
+
+    #[must_use]
+    pub const fn with_pointer_flag(mut self) -> Self {
+        assert!((self.flags.0 & VMStateFlags::VMS_POINTER.0) == 0);
+        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_POINTER.0);
+        self
+    }
+
+    #[must_use]
+    pub const fn with_varray_flag_unchecked(mut self, flag: VMStateFlags) -> Self {
+        self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0);
+        self.flags = VMStateFlags(self.flags.0 | flag.0);
+        self.num = 0; // varray uses num_offset instead of num.
+        self
+    }
+
+    #[must_use]
+    #[allow(unused_mut)]
+    pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> Self {
+        assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0);
+        self.with_varray_flag_unchecked(flag)
+    }
+
+    #[must_use]
+    pub const fn with_varray_multiply(mut self, num: u32) -> Self {
+        assert!(num <= 0x7FFF_FFFFu32);
+        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_MULTIPLY_ELEMENTS.0);
+        self.num = num as i32;
+        self
+    }
+}
diff --git a/rust/bindings/migration-sys/meson.build b/rust/bindings/migration-sys/meson.build
new file mode 100644 (file)
index 0000000..9243acb
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_migration_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['migration-sys'].split(),
+  kwargs: bindgen_kwargs)
+_migration_sys_rs = static_library(
+  'migration_sys',
+  structured_sources(['lib.rs', _bindgen_migration_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [glib_sys_rs, common_rs, util_sys_rs],
+)
+
+migration_sys_rs = declare_dependency(link_with: [_migration_sys_rs])
diff --git a/rust/bindings/migration-sys/wrapper.h b/rust/bindings/migration-sys/wrapper.h
new file mode 100644 (file)
index 0000000..076ad79
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+#include "qemu/osdep.h"
+
+#include "migration/vmstate.h"
diff --git a/rust/bindings/qom-sys/Cargo.toml b/rust/bindings/qom-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..621bd46
--- /dev/null
@@ -0,0 +1,25 @@
+[package]
+name = "qom-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/qom"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+util-sys = { path = "../util-sys" }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
diff --git a/rust/bindings/qom-sys/build.rs b/rust/bindings/qom-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
similarity index 85%
rename from rust/qom/src/bindings.rs
rename to rust/bindings/qom-sys/lib.rs
index e61259ec2ef274d217162e588fb6060a008f6f80..464b92903444a2f4432a74a6c9763c5acc2c49a7 100644 (file)
 )]
 
 use glib_sys::{GHashTable, GHashTableIter, GPtrArray, GSList};
+use util_sys::{Error, QDict, QObject, Visitor};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
 
 #[cfg(not(MESON))]
 include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
+
+unsafe impl Send for TypeInfo {}
+unsafe impl Sync for TypeInfo {}
diff --git a/rust/bindings/qom-sys/meson.build b/rust/bindings/qom-sys/meson.build
new file mode 100644 (file)
index 0000000..8f8ae7d
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_qom_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['qom-sys'].split(),
+  kwargs: bindgen_kwargs)
+_qom_sys_rs = static_library(
+  'qom_sys',
+  structured_sources(['lib.rs', _bindgen_qom_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [glib_sys_rs, util_sys_rs],
+)
+
+qom_sys_rs = declare_dependency(link_with: [_qom_sys_rs])
diff --git a/rust/bindings/qom-sys/wrapper.h b/rust/bindings/qom-sys/wrapper.h
new file mode 100644 (file)
index 0000000..18a5ea6
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+/*
+ * We block include/qemu/typedefs.h from bindgen, add here symbols
+ * that are needed as opaque types by other functions.
+ */
+typedef struct Object Object;
+typedef struct ObjectClass ObjectClass;
+
+#include "qemu/osdep.h"
+
+#include "qom/object.h"
diff --git a/rust/bindings/system-sys/Cargo.toml b/rust/bindings/system-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..7e52713
--- /dev/null
@@ -0,0 +1,30 @@
+[package]
+name = "system-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/system"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+common = { path = "../../common" }
+migration-sys = { path = "../migration-sys" }
+util-sys = { path = "../util-sys" }
+qom-sys = { path = "../qom-sys" }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
+rustified-enum = ["device_endian"]
+additional-files = ["system/memory.*"]
diff --git a/rust/bindings/system-sys/build.rs b/rust/bindings/system-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
similarity index 88%
rename from rust/system/src/bindings.rs
rename to rust/bindings/system-sys/lib.rs
index 7164c5219a5a602b54ddbc1706eb5095c2918340..022fe65dd8337812c8aeb8bd3e68b53552441e09 100644 (file)
@@ -19,7 +19,9 @@
 )]
 
 use common::Zeroable;
-use glib_sys::{guint, GHashTable, GHashTableIter, GList, GPollFD, GPtrArray, GSList};
+use hwcore_sys::{qemu_irq, DeviceClass, DeviceState};
+use qom_sys::{InterfaceClass, Object, ObjectClass};
+use util_sys::{Error, EventNotifier, QEMUBH};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
diff --git a/rust/bindings/system-sys/meson.build b/rust/bindings/system-sys/meson.build
new file mode 100644 (file)
index 0000000..aa5e880
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_system_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['system-sys'].split(),
+  kwargs: bindgen_kwargs)
+_system_sys_rs = static_library(
+  'system_sys',
+  structured_sources(['lib.rs', _bindgen_system_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [common_rs, glib_sys_rs, hwcore_sys_rs, migration_sys_rs, qom_sys_rs, util_sys_rs],
+)
+
+system_sys_rs = declare_dependency(link_with: [_system_sys_rs])
diff --git a/rust/bindings/system-sys/wrapper.h b/rust/bindings/system-sys/wrapper.h
new file mode 100644 (file)
index 0000000..0a8bf06
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+/*
+ * We block include/qemu/typedefs.h from bindgen, add here symbols
+ * that are needed as opaque types by other functions.
+ */
+typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
+typedef struct MemoryRegion MemoryRegion;
+typedef struct RAMBlock RAMBlock;
+
+#include "qemu/osdep.h"
+
+#include "exec/hwaddr.h"
+#include "system/address-spaces.h"
+#include "system/memory.h"
+#include "hw/core/sysbus.h"
diff --git a/rust/bindings/util-sys/Cargo.toml b/rust/bindings/util-sys/Cargo.toml
new file mode 100644 (file)
index 0000000..929a08a
--- /dev/null
@@ -0,0 +1,25 @@
+[package]
+name = "util-sys"
+version = "0.1.0"
+description = "Rust sys bindings for QEMU/util"
+publish = false
+
+authors.workspace = true
+edition.workspace = true
+homepage.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+glib-sys = { workspace = true }
+
+[lints]
+workspace = true
+
+[package.metadata.bindgen]
+header = "wrapper.h"
+rustified-enum = ["module_init_type", "QEMUClockType"]
diff --git a/rust/bindings/util-sys/build.rs b/rust/bindings/util-sys/build.rs
new file mode 120000 (symlink)
index 0000000..1023803
--- /dev/null
@@ -0,0 +1 @@
+../build.rs
\ No newline at end of file
similarity index 88%
rename from rust/util/src/bindings.rs
rename to rust/bindings/util-sys/lib.rs
index 3514a66f5fa08d4131953488b1419755b7d53a21..0212e941843b8043ba6d74ec32e893bd231dcb41 100644 (file)
@@ -18,7 +18,7 @@
     clippy::too_many_arguments
 )]
 
-use glib_sys::{guint, GPollFD, GString};
+use glib_sys::{guint, GArray, GHashTable, GPollFD, GSList, GSource, GString};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
diff --git a/rust/bindings/util-sys/meson.build b/rust/bindings/util-sys/meson.build
new file mode 100644 (file)
index 0000000..c37f50a
--- /dev/null
@@ -0,0 +1,12 @@
+_bindgen_util_rs = rust.bindgen(
+  args: bindgen_args_common + bindgen_args_data['util-sys'].split(),
+  kwargs: bindgen_kwargs)
+_util_sys_rs = static_library(
+  'util_sys',
+  structured_sources(['lib.rs', _bindgen_util_rs]),
+  override_options: ['rust_std=2021', 'build.rust_std=2021'],
+  rust_abi: 'rust',
+  dependencies: [glib_sys_rs],
+)
+
+util_sys_rs = declare_dependency(link_with: [_util_sys_rs])
diff --git a/rust/bindings/util-sys/wrapper.h b/rust/bindings/util-sys/wrapper.h
new file mode 100644 (file)
index 0000000..e9c433e
--- /dev/null
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * This header file is meant to be used as input to the `bindgen` application
+ * in order to generate C FFI compatible Rust bindings.
+ */
+
+/*
+ * We block include/qemu/typedefs.h from bindgen, add here symbols
+ * that are needed as opaque types by other functions.
+ */
+typedef struct QEMUBH QEMUBH;
+typedef struct QEMUFile QEMUFile;
+typedef struct QemuOpts QemuOpts;
+typedef struct JSONWriter JSONWriter;
+typedef struct Visitor Visitor;
+
+#include "qemu/osdep.h"
+
+#include "qapi/error.h"
+#include "qapi/error-internal.h"
+#include "qemu/event_notifier.h"
+#include "qemu/main-loop.h"
+#include "qemu/aio.h"
+#include "qemu/log-for-trace.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/timer.h"
+#include "qapi/visitor.h"
+#include "qobject/qbool.h"
+#include "qobject/qdict.h"
+#include "qobject/qjson.h"
+#include "qobject/qlist.h"
+#include "qobject/qnull.h"
+#include "qobject/qnum.h"
+#include "qobject/qobject.h"
+#include "qobject/qstring.h"
+#include "qobject/json-writer.h"
index 8fd81311028485ab7ebf8988e3a127e7a55cc368..a27099e0587c31b84e7a58672ef3f0c4adea387c 100644 (file)
@@ -14,6 +14,7 @@ rust-version.workspace = true
 
 [dependencies]
 glib-sys.workspace = true
+util-sys = { path = "../bindings/util-sys" }
 
 [features]
 default = ["debug_cell"]
diff --git a/rust/bql/build.rs b/rust/bql/build.rs
deleted file mode 120000 (symlink)
index 71a3167..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../util/build.rs
\ No newline at end of file
index 728c9e4dacf9e6d6ef8b49e09f8836b24ffb2a66..de295d2983eb6bb6450ce7266b6bb10b19993823 100644 (file)
@@ -6,37 +6,11 @@ if get_option('debug_mutex')
   _bql_cfg += ['--cfg', 'feature="debug_cell"']
 endif
 
-#
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_bql_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common,
-  c_args: bindgen_c_args,
-)
-
 _bql_rs = static_library(
   'bql',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/cell.rs',
-      'src/prelude.rs',
-    ],
-    {'.': _bql_bindings_inc_rs}
-  ),
+  'src/lib.rs',
   rust_args: _bql_cfg,
-  dependencies: [glib_sys_rs],
+  dependencies: [glib_sys_rs, util_sys_rs],
 )
 
 bql_rs = declare_dependency(link_with: [_bql_rs],
diff --git a/rust/bql/src/bindings.rs b/rust/bql/src/bindings.rs
deleted file mode 100644 (file)
index c656cf1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-#![allow(
-    dead_code,
-    improper_ctypes_definitions,
-    improper_ctypes,
-    non_camel_case_types,
-    non_snake_case,
-    non_upper_case_globals,
-    unnecessary_transmutes,
-    unsafe_op_in_unsafe_fn,
-    clippy::pedantic,
-    clippy::restriction,
-    clippy::style,
-    clippy::missing_const_for_fn,
-    clippy::ptr_offset_with_cast,
-    clippy::useless_transmute,
-    clippy::missing_safety_doc,
-    clippy::too_many_arguments
-)]
-
-use glib_sys::{guint, GArray, GHashTable, GHashTableIter, GPollFD, GPtrArray, GSList, GSource};
-
-#[cfg(MESON)]
-include!("bindings.inc.rs");
-
-#[cfg(not(MESON))]
-include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
index d2fea5db1ac15b79aedb9fb2ad844d3a2a2345c0..3aa3d46d76cd8497e32c9502a98257eb9afa881d 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-mod bindings;
-use bindings::{bql_block_unlock, bql_locked, rust_bql_mock_lock};
+use util_sys::{bql_block_unlock, bql_locked, rust_bql_mock_lock};
 
 mod cell;
 pub use cell::*;
diff --git a/rust/bql/wrapper.h b/rust/bql/wrapper.h
deleted file mode 100644 (file)
index 2ef9a96..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "qemu/main-loop.h"
index f105189dccbb3cc44172c02e594c349e56190537..208d44d0cdff15603277c48cf87abef19c560985 100644 (file)
@@ -14,6 +14,7 @@ rust-version.workspace = true
 
 [dependencies]
 glib-sys = { workspace = true }
+chardev-sys = { path = "../bindings/chardev-sys" }
 common = { path = "../common" }
 bql = { path = "../bql" }
 migration = { path = "../migration" }
diff --git a/rust/chardev/build.rs b/rust/chardev/build.rs
deleted file mode 120000 (symlink)
index 71a3167..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../util/build.rs
\ No newline at end of file
index 2e4f4670bd844b59f5399c3fd6e514929dac45e4..7b267fd23ae124e88234adf05d2d5e88b6300fd8 100644 (file)
@@ -1,41 +1,8 @@
-c_enums = [
-  'QEMUChrEvent',
-]
-_chardev_bindgen_args = []
-foreach enum : c_enums
-  _chardev_bindgen_args += ['--rustified-enum', enum]
-endforeach
-
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_chardev_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common + _chardev_bindgen_args,
-  c_args: bindgen_c_args,
-)
-
 _chardev_rs = static_library(
   'chardev',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/chardev.rs',
-      'src/prelude.rs',
-    ],
-    {'.': _chardev_bindings_inc_rs}
-  ),
+  'src/lib.rs',
   link_with: [_bql_rs, _migration_rs, _qom_rs, _util_rs],
-  dependencies: [glib_sys_rs, common_rs, qemu_macros],
+  dependencies: [glib_sys_rs, common_rs, qemu_macros, chardev_sys_rs],
 )
 
 chardev_rs = declare_dependency(link_with: [_chardev_rs], dependencies: [chardev, qemuutil])
index 93a287259323b9c0b0ab8bdb9bfbbd2c98cd2621..9f1a3a9c1c52d2fb2a6ddee75b4da32ebaeca83b 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-pub mod bindings;
+pub use chardev_sys as bindings;
 
 mod chardev;
 pub use chardev::*;
diff --git a/rust/chardev/wrapper.h b/rust/chardev/wrapper.h
deleted file mode 100644 (file)
index 65ede6e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "chardev/char-fe.h"
-#include "chardev/char-serial.h"
index 5f5060db356689b6c71c034b117fff4626447825..e326242685217e92147bdc566d03c9fe64f9e391 120000 (symlink)
@@ -1 +1 @@
-../../../util/build.rs
\ No newline at end of file
+../../../bindings/build.rs
\ No newline at end of file
index 9c0e8290e9aaef89abc02f117c9ea66481517c3e..1a1a09e5083a829f4a89bc57e37b5be89dea55f7 100644 (file)
@@ -1,18 +1,11 @@
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
 _libpl011_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common,
-  c_args: bindgen_c_args,
+  args: bindgen_args_common + [
+    '--allowlist-file', meson.project_source_root() / 'include/hw/char/pl011.h',
+    '--blocklist-file',
+      meson.project_source_root() /
+      'include/(block\|chardev/|exec/|hw/core/|qemu/|qom/|system/).*',
+  ],
+  kwargs: bindgen_kwargs,
 )
 
 _libpl011_rs = static_library(
index 68b9b22bbc3776507011763b59217acad4939ec7..8e2f8863b18d5959e0d62767c47c0f022221b093 100644 (file)
 
 //! `bindgen`-generated declarations.
 
-use glib_sys::{
-    gboolean, guint, GArray, GHashTable, GHashTableIter, GIOCondition, GList, GMainContext,
-    GPollFD, GPtrArray, GSList, GSource, GSourceFunc,
-};
+use chardev::bindings::{CharFrontend, Chardev};
+use hwcore::bindings::{qemu_irq, Clock, DeviceState};
+use system::bindings::{hwaddr, MemoryRegion, SysBusDevice};
 
 #[cfg(MESON)]
 include!("bindings.inc.rs");
index ecfb56471843d8a5e19f9d467c7d3b9c530a06e3..8cc514da20236ac06ca73d3574be14f676be31b5 100644 (file)
@@ -14,6 +14,7 @@ rust-version.workspace = true
 
 [dependencies]
 glib-sys.workspace = true
+hwcore-sys = { path = "../../bindings/hwcore-sys" }
 qemu_macros = { path = "../../qemu-macros" }
 common = { path = "../../common" }
 bql = { path = "../../bql" }
diff --git a/rust/hw/core/build.rs b/rust/hw/core/build.rs
deleted file mode 120000 (symlink)
index 2a79ee3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../util/build.rs
\ No newline at end of file
index 942ee9cdacfd03dc8c161de63f35333c2688455b..28ea00cdb4f5346c524f82b02a2e001114a2dbf3 100644 (file)
@@ -1,66 +1,10 @@
-_hwcore_bindgen_args = []
-c_enums = [
-  'DeviceCategory',
-  'GpioPolarity',
-  'MachineInitPhase',
-  'ResetType',
-]
-foreach enum : c_enums
-  _hwcore_bindgen_args += ['--rustified-enum', enum]
-endforeach
-
-blocked_type = [
-  'Chardev',
-  'Error',
-  'ObjectClass',
-  'MemoryRegion',
-  'VMStateDescription',
-]
-foreach type: blocked_type
-  _hwcore_bindgen_args += ['--blocklist-type', type]
-endforeach
-
-c_bitfields = [
-  'ClockEvent',
-]
-foreach enum : c_bitfields
-  _hwcore_bindgen_args += ['--bitfield-enum', enum]
-endforeach
-
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_hwcore_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common + _hwcore_bindgen_args,
-  c_args: bindgen_c_args,
-)
-
 _hwcore_rs = static_library(
   'hwcore',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/irq.rs',
-      'src/prelude.rs',
-      'src/qdev.rs',
-      'src/sysbus.rs',
-    ],
-    {'.': _hwcore_bindings_inc_rs}
-  ),
+  'src/lib.rs',
   override_options: ['rust_std=2021', 'build.rust_std=2021'],
   rust_abi: 'rust',
   link_with: [_bql_rs, _chardev_rs, _migration_rs, _qom_rs, _system_rs, _util_rs],
-  dependencies: [glib_sys_rs, qemu_macros, common_rs],
+  dependencies: [glib_sys_rs, qemu_macros, common_rs, hwcore_sys_rs],
 )
 
 hwcore_rs = declare_dependency(link_with: [_hwcore_rs],
index 491743d2b9da66a134af51ede177b530da502683..76689fe7db110202986fa18ce88a46b54bc4c025 100644 (file)
@@ -1,10 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
+pub use hwcore_sys as bindings;
 pub use qemu_macros::Device;
 pub use qom;
 
-pub mod bindings;
-
 mod irq;
 pub use irq::*;
 
index f6037fbdcaeaecc3018a9532f8bf050862893dbe..145e20a984faed5a12c7858c95a551365846229f 100644 (file)
@@ -66,7 +66,7 @@ pub trait ResettablePhasesImpl {
 /// can be downcasted to type `T`. We also expect the device is
 /// readable/writeable from one thread at any time.
 unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
-    obj: *mut bindings::Object,
+    obj: *mut qom::bindings::Object,
     typ: ResetType,
 ) {
     let state = NonNull::new(obj).unwrap().cast::<T>();
@@ -79,7 +79,7 @@ unsafe extern "C" fn rust_resettable_enter_fn<T: ResettablePhasesImpl>(
 /// can be downcasted to type `T`. We also expect the device is
 /// readable/writeable from one thread at any time.
 unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
-    obj: *mut bindings::Object,
+    obj: *mut qom::bindings::Object,
     typ: ResetType,
 ) {
     let state = NonNull::new(obj).unwrap().cast::<T>();
@@ -92,7 +92,7 @@ unsafe extern "C" fn rust_resettable_hold_fn<T: ResettablePhasesImpl>(
 /// can be downcasted to type `T`. We also expect the device is
 /// readable/writeable from one thread at any time.
 unsafe extern "C" fn rust_resettable_exit_fn<T: ResettablePhasesImpl>(
-    obj: *mut bindings::Object,
+    obj: *mut qom::bindings::Object,
     typ: ResetType,
 ) {
     let state = NonNull::new(obj).unwrap().cast::<T>();
index 81fab3f1910541be4fccf5b13c3d40a28284b2f4..7db09a82c63ad54c89096a033460b5ab48e0ac1a 100644 (file)
@@ -6,22 +6,21 @@
 
 use std::ffi::CStr;
 
-pub use bindings::SysBusDeviceClass;
 use common::Opaque;
 use qom::prelude::*;
 use system::MemoryRegion;
+pub use system_sys::SysBusDeviceClass;
 use util::{Error, Result};
 
 use crate::{
-    bindings,
     irq::{IRQState, InterruptSource},
     qdev::{DeviceClassExt, DeviceImpl, DeviceState},
 };
 
-/// A safe wrapper around [`bindings::SysBusDevice`].
+/// A safe wrapper around [`system_sys::SysBusDevice`].
 #[repr(transparent)]
 #[derive(Debug, common::Wrapper)]
-pub struct SysBusDevice(Opaque<bindings::SysBusDevice>);
+pub struct SysBusDevice(Opaque<system_sys::SysBusDevice>);
 
 unsafe impl Send for SysBusDevice {}
 unsafe impl Sync for SysBusDevice {}
@@ -29,7 +28,7 @@ unsafe impl Sync for SysBusDevice {}
 unsafe impl ObjectType for SysBusDevice {
     type Class = SysBusDeviceClass;
     const TYPE_NAME: &'static CStr =
-        unsafe { CStr::from_bytes_with_nul_unchecked(bindings::TYPE_SYS_BUS_DEVICE) };
+        unsafe { CStr::from_bytes_with_nul_unchecked(system_sys::TYPE_SYS_BUS_DEVICE) };
 }
 
 qom_isa!(SysBusDevice: DeviceState, Object);
@@ -62,7 +61,7 @@ where
     fn init_mmio(&self, iomem: &MemoryRegion) {
         assert!(bql::is_locked());
         unsafe {
-            bindings::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr());
+            system_sys::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr());
         }
     }
 
@@ -73,7 +72,7 @@ where
     fn init_irq(&self, irq: &InterruptSource) {
         assert!(bql::is_locked());
         unsafe {
-            bindings::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr());
+            system_sys::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr());
         }
     }
 
@@ -82,7 +81,7 @@ where
         assert!(bql::is_locked());
         // SAFETY: the BQL ensures that no one else writes to sbd.mmio[], and
         // the SysBusDevice must be initialized to get an IsA<SysBusDevice>.
-        let sbd = unsafe { &*self.upcast().as_ptr() };
+        let sbd = unsafe { &*self.upcast().as_mut_ptr() };
         let id: usize = id.try_into().unwrap();
         if sbd.mmio[id].memory.is_null() {
             None
@@ -96,7 +95,7 @@ where
         assert!(bql::is_locked());
         let id: i32 = id.try_into().unwrap();
         unsafe {
-            bindings::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr);
+            system_sys::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr);
         }
     }
 
@@ -108,7 +107,7 @@ where
         let id: i32 = id.try_into().unwrap();
         let irq: &IRQState = irq;
         unsafe {
-            bindings::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr());
+            system_sys::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr());
         }
     }
 
@@ -116,7 +115,7 @@ where
         assert!(bql::is_locked());
         unsafe {
             Error::with_errp(|errp| {
-                bindings::sysbus_realize(self.upcast().as_mut_ptr(), errp);
+                system_sys::sysbus_realize(self.upcast().as_mut_ptr(), errp);
             })
         }
     }
diff --git a/rust/hw/core/wrapper.h b/rust/hw/core/wrapper.h
deleted file mode 100644 (file)
index 8278738..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "hw/core/sysbus.h"
-#include "hw/core/clock.h"
-#include "hw/core/qdev-clock.h"
-#include "hw/core/qdev-properties.h"
-#include "hw/core/qdev-properties-system.h"
-#include "hw/core/irq.h"
index bacb787910298565b5a22e10627a9bd07f5865d7..3a3e10d7b9761d1f58b10040089dca6cd8776c25 100644 (file)
@@ -35,6 +35,7 @@ genrs = []
 subdir('qemu-macros')
 
 subdir('common')
+subdir('bindings')
 subdir('bits')
 
 subdir('util')
index 415457496d6470065f206d34f0093774afd4d562..cf10601b44a060e640096534d5df0cd93429327f 100644 (file)
@@ -17,6 +17,7 @@ bql = { path = "../bql" }
 common = { path = "../common" }
 qemu_macros = { path = "../qemu-macros" }
 util = { path = "../util" }
+migration-sys = { path = "../bindings/migration-sys" }
 glib-sys.workspace = true
 
 [lints]
diff --git a/rust/migration/build.rs b/rust/migration/build.rs
deleted file mode 120000 (symlink)
index 71a3167..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../util/build.rs
\ No newline at end of file
index 76d86b0ac0fafea5afec3ad8c686318b891071e0..96266897770588f219b25d55c041c99d2f112949 100644 (file)
@@ -1,44 +1,8 @@
-_migration_bindgen_args = []
-c_bitfields = [
-  'MigrationPolicy',
-  'MigrationPriority',
-  'VMStateFlags',
-]
-foreach enum : c_bitfields
-  _migration_bindgen_args += ['--bitfield-enum', enum]
-endforeach
-#
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_migration_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common + _migration_bindgen_args,
-  c_args: bindgen_c_args,
-)
-
 _migration_rs = static_library(
   'migration',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/migratable.rs',
-      'src/prelude.rs',
-      'src/vmstate.rs',
-    ],
-    {'.' : _migration_bindings_inc_rs},
-  ),
+  'src/lib.rs',
   link_with: [_util_rs, _bql_rs],
-  dependencies: [common_rs, glib_sys_rs, qemu_macros],
+  dependencies: [common_rs, glib_sys_rs, qemu_macros, migration_sys_rs],
 )
 
 migration_rs = declare_dependency(link_with: [_migration_rs],
diff --git a/rust/migration/src/bindings.rs b/rust/migration/src/bindings.rs
deleted file mode 100644 (file)
index e9c0583..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-#![allow(
-    dead_code,
-    improper_ctypes_definitions,
-    improper_ctypes,
-    non_camel_case_types,
-    non_snake_case,
-    non_upper_case_globals,
-    unnecessary_transmutes,
-    unsafe_op_in_unsafe_fn,
-    clippy::pedantic,
-    clippy::restriction,
-    clippy::style,
-    clippy::missing_const_for_fn,
-    clippy::ptr_offset_with_cast,
-    clippy::useless_transmute,
-    clippy::missing_safety_doc,
-    clippy::too_many_arguments
-)]
-
-use common::Zeroable;
-use glib_sys::{GHashTable, GHashTableIter, GPtrArray, GSList};
-
-#[cfg(MESON)]
-include!("bindings.inc.rs");
-
-#[cfg(not(MESON))]
-include!(concat!(env!("OUT_DIR"), "/bindings.inc.rs"));
-
-unsafe impl Send for VMStateDescription {}
-unsafe impl Sync for VMStateDescription {}
-
-unsafe impl Send for VMStateField {}
-unsafe impl Sync for VMStateField {}
-
-unsafe impl Send for VMStateInfo {}
-unsafe impl Sync for VMStateInfo {}
-
-// bindgen does not derive Default here
-#[allow(clippy::derivable_impls)]
-impl Default for VMStateFlags {
-    fn default() -> Self {
-        Self(0)
-    }
-}
-
-unsafe impl Zeroable for VMStateFlags {}
-unsafe impl Zeroable for VMStateField {}
-unsafe impl Zeroable for VMStateDescription {}
index 32e182e716a9a2b120ca0a1bc7a753c39c213521..6d819cc15543db8879e6b37cc1eb8218a54ff1fe 100644 (file)
@@ -1,7 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-pub mod bindings;
-
+pub use migration_sys as bindings;
 pub use qemu_macros::ToMigrationState;
 
 pub mod migratable;
index 595e7e9cd752563905ee2fce6b69c1ed9838985b..edc7c7026568665d0f3100a53f3c65e70e1bef6f 100644 (file)
@@ -165,79 +165,6 @@ macro_rules! vmstate_of {
     };
 }
 
-pub trait VMStateFlagsExt {
-    const VMS_VARRAY_FLAGS: VMStateFlags;
-}
-
-impl VMStateFlagsExt for VMStateFlags {
-    const VMS_VARRAY_FLAGS: VMStateFlags = VMStateFlags(
-        VMStateFlags::VMS_VARRAY_INT32.0
-            | VMStateFlags::VMS_VARRAY_UINT8.0
-            | VMStateFlags::VMS_VARRAY_UINT16.0
-            | VMStateFlags::VMS_VARRAY_UINT32.0,
-    );
-}
-
-// Add a couple builder-style methods to VMStateField, allowing
-// easy derivation of VMStateField constants from other types.
-impl VMStateField {
-    #[must_use]
-    pub const fn with_version_id(mut self, version_id: i32) -> Self {
-        assert!(version_id >= 0);
-        self.version_id = version_id;
-        self
-    }
-
-    #[must_use]
-    pub const fn with_array_flag(mut self, num: usize) -> Self {
-        assert!(num <= 0x7FFF_FFFFusize);
-        assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) == 0);
-        assert!((self.flags.0 & VMStateFlags::VMS_VARRAY_FLAGS.0) == 0);
-        if (self.flags.0 & VMStateFlags::VMS_POINTER.0) != 0 {
-            self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_POINTER.0);
-            self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY_OF_POINTER.0);
-            // VMS_ARRAY_OF_POINTER flag stores the size of pointer.
-            // FIXME: *const, *mut, NonNull and Box<> have the same size as usize.
-            //        Resize if more smart pointers are supported.
-            self.size = std::mem::size_of::<usize>();
-        }
-        self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_SINGLE.0);
-        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_ARRAY.0);
-        self.num = num as i32;
-        self
-    }
-
-    #[must_use]
-    pub const fn with_pointer_flag(mut self) -> Self {
-        assert!((self.flags.0 & VMStateFlags::VMS_POINTER.0) == 0);
-        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_POINTER.0);
-        self
-    }
-
-    #[must_use]
-    pub const fn with_varray_flag_unchecked(mut self, flag: VMStateFlags) -> Self {
-        self.flags = VMStateFlags(self.flags.0 & !VMStateFlags::VMS_ARRAY.0);
-        self.flags = VMStateFlags(self.flags.0 | flag.0);
-        self.num = 0; // varray uses num_offset instead of num.
-        self
-    }
-
-    #[must_use]
-    #[allow(unused_mut)]
-    pub const fn with_varray_flag(mut self, flag: VMStateFlags) -> Self {
-        assert!((self.flags.0 & VMStateFlags::VMS_ARRAY.0) != 0);
-        self.with_varray_flag_unchecked(flag)
-    }
-
-    #[must_use]
-    pub const fn with_varray_multiply(mut self, num: u32) -> Self {
-        assert!(num <= 0x7FFF_FFFFu32);
-        self.flags = VMStateFlags(self.flags.0 | VMStateFlags::VMS_MULTIPLY_ELEMENTS.0);
-        self.num = num as i32;
-        self
-    }
-}
-
 /// This macro can be used (by just passing it a type) to forward the `VMState`
 /// trait to the first field of a tuple.  This is a workaround for lack of
 /// support of nested [`offset_of`](core::mem::offset_of) until Rust 1.82.0.
diff --git a/rust/migration/wrapper.h b/rust/migration/wrapper.h
deleted file mode 100644 (file)
index daf316a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2024 Linaro Ltd.
- *
- * Authors: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-#include "migration/vmstate.h"
index 4be3c2541b612e07a31422dd23378f555ba89fe2..aed8af5474aec7842ef8d74d68f5e4b39895df5a 100644 (file)
@@ -18,6 +18,7 @@ bql = { path = "../bql" }
 migration = { path = "../migration" }
 qemu_macros = { path = "../qemu-macros" }
 util = { path = "../util" }
+qom-sys = { path = "../bindings/qom-sys" }
 glib-sys.workspace = true
 
 [lints]
diff --git a/rust/qom/build.rs b/rust/qom/build.rs
deleted file mode 120000 (symlink)
index 71a3167..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../util/build.rs
\ No newline at end of file
index dda26c3f981d9cfe8e5db8f4dea7c75b4b7b7655..9865da280cf766e22d439199c9facba6891a1eb7 100644 (file)
@@ -1,33 +1,8 @@
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_qom_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common,
-  c_args: bindgen_c_args,
-)
-
 _qom_rs = static_library(
   'qom',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/prelude.rs',
-      'src/qom.rs',
-    ],
-    {'.': _qom_bindings_inc_rs}
-  ),
+  'src/lib.rs',
   link_with: [_bql_rs, _migration_rs],
-  dependencies: [common_rs, glib_sys_rs, qemu_macros],
+  dependencies: [common_rs, glib_sys_rs, qemu_macros, qom_sys_rs],
 )
 
 qom_rs = declare_dependency(link_with: [_qom_rs], dependencies: [qemu_macros, qom, qemuutil])
index 24c44fc2afb50652f4945607c79fba75f2039f48..1bed1cfe233f5e0ef6f28efd550c79c544efdde7 100644 (file)
@@ -1,8 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 pub use qemu_macros::Object;
-
-pub mod bindings;
+pub use qom_sys as bindings;
 
 // preserve one-item-per-"use" syntax, it is clearer
 // for prelude-like modules
diff --git a/rust/qom/wrapper.h b/rust/qom/wrapper.h
deleted file mode 100644 (file)
index 3b71bcd..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "qom/object.h"
index 186ea00bfff9ce791aa0695817235e7530264a06..f7fde9782eae80199fba3b1eaef113e1d6acdac0 100644 (file)
@@ -14,6 +14,9 @@ rust-version.workspace = true
 
 [dependencies]
 common = { path = "../common" }
+system-sys = { path = "../bindings/system-sys" }
+bql = { path = "../bql" }
+migration = { path = "../migration" }
 qom = { path = "../qom" }
 util = { path = "../util" }
 glib-sys.workspace = true
diff --git a/rust/system/build.rs b/rust/system/build.rs
deleted file mode 120000 (symlink)
index 71a3167..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../util/build.rs
\ No newline at end of file
index e9f36ed8554d4d00f2a0752cf6b4b715398473ec..4cbd63cbbd705276191124f82b16c044ebf4363c 100644 (file)
@@ -1,41 +1,8 @@
-c_enums = [
-  'device_endian',
-]
-_system_bindgen_args = []
-foreach enum : c_enums
-  _system_bindgen_args += ['--rustified-enum', enum]
-endforeach
-
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_system_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common + _system_bindgen_args,
-  c_args: bindgen_c_args,
-)
-
 _system_rs = static_library(
   'system',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/memory.rs',
-      'src/prelude.rs',
-    ],
-    {'.': _system_bindings_inc_rs}
-  ),
+  'src/lib.rs',
   link_with: [_bql_rs, _migration_rs, _qom_rs, _util_rs],
-  dependencies: [glib_sys_rs, common_rs, qemu_macros],
+  dependencies: [glib_sys_rs, common_rs, qemu_macros, system_sys_rs],
 )
 
 system_rs = declare_dependency(link_with: [_system_rs],
index 5fb83b65d8d89ba10b8df76928c74e39e63a41b4..10741e0ee0a021ff2e02be1ae8b8954804a732db 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-pub mod bindings;
+pub use system_sys as bindings;
 
 mod memory;
 pub use memory::*;
index 4e06c16a0b5b3aeb9d40c46062b1166668a0bb14..4c258201bad78fb722b5738deb82e7aeb51320dd 100644 (file)
@@ -132,7 +132,7 @@ unsafe impl Sync for MemoryRegion {}
 impl MemoryRegion {
     unsafe fn do_init_io(
         slot: *mut bindings::MemoryRegion,
-        owner: *mut bindings::Object,
+        owner: *mut qom::bindings::Object,
         ops: &'static bindings::MemoryRegionOps,
         name: &'static str,
         size: u64,
diff --git a/rust/system/wrapper.h b/rust/system/wrapper.h
deleted file mode 100644 (file)
index 48abde8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "system/system.h"
-#include "system/memory.h"
-#include "system/address-spaces.h"
index 85f914365450d85cd4209fcc20396ff2dbf2c468..2ad5940dacaaddff525221a6882931e478a5640e 100644 (file)
@@ -18,6 +18,7 @@ foreign = { workspace = true }
 glib-sys = { workspace = true }
 libc = { workspace = true }
 common = { path = "../common" }
+util-sys = { path = "../bindings/util-sys" }
 
 [lints]
 workspace = true
index 98629394afb80922874ac81aef22af4551ce7cdb..6d175ae0b0fbfc750d5dcc4c72468849f924952f 100644 (file)
@@ -1,45 +1,7 @@
-_util_bindgen_args = []
-c_enums = [
-  'module_init_type',
-  'QEMUClockType',
-]
-foreach enum : c_enums
-  _util_bindgen_args += ['--rustified-enum', enum]
-endforeach
-
-#
-# TODO: Remove this comment when the clang/libclang mismatch issue is solved.
-#
-# Rust bindings generation with `bindgen` might fail in some cases where the
-# detected `libclang` does not match the expected `clang` version/target. In
-# this case you must pass the path to `clang` and `libclang` to your build
-# command invocation using the environment variables CLANG_PATH and
-# LIBCLANG_PATH
-_util_bindings_inc_rs = rust.bindgen(
-  input: 'wrapper.h',
-  dependencies: common_ss.all_dependencies(),
-  output: 'bindings.inc.rs',
-  include_directories: bindings_incdir,
-  bindgen_version: ['>=0.60.0'],
-  args: bindgen_args_common + _util_bindgen_args,
-  c_args: bindgen_c_args,
-)
-
 _util_rs = static_library(
   'util',
-  structured_sources(
-    [
-      'src/lib.rs',
-      'src/bindings.rs',
-      'src/error.rs',
-      'src/log.rs',
-      'src/module.rs',
-      'src/prelude.rs',
-      'src/timer.rs',
-    ],
-    {'.': _util_bindings_inc_rs}
-  ),
-  dependencies: [anyhow_rs, libc_rs, foreign_rs, glib_sys_rs, common_rs],
+  'src/lib.rs',
+  dependencies: [anyhow_rs, libc_rs, foreign_rs, glib_sys_rs, common_rs, util_sys_rs],
 )
 
 util_rs = declare_dependency(link_with: [_util_rs], dependencies: [qemuutil, qom])
index 7d2de3ed811e51df37073178ef2f43417e642b18..436c67e139ed72a9c29753f3837b01aa7948f27b 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-pub mod bindings;
+pub use util_sys as bindings;
+
 pub mod error;
 pub mod log;
 pub mod module;
diff --git a/rust/util/wrapper.h b/rust/util/wrapper.h
deleted file mode 100644 (file)
index b9ed68a..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/*
- * This header file is meant to be used as input to the `bindgen` application
- * in order to generate C FFI compatible Rust bindings.
- */
-
-#ifndef __CLANG_STDATOMIC_H
-#define __CLANG_STDATOMIC_H
-/*
- * Fix potential missing stdatomic.h error in case bindgen does not insert the
- * correct libclang header paths on its own. We do not use stdatomic.h symbols
- * in QEMU code, so it's fine to declare dummy types instead.
- */
-typedef enum memory_order {
-  memory_order_relaxed,
-  memory_order_consume,
-  memory_order_acquire,
-  memory_order_release,
-  memory_order_acq_rel,
-  memory_order_seq_cst,
-} memory_order;
-#endif /* __CLANG_STDATOMIC_H */
-
-#include "qemu/osdep.h"
-
-#include "qapi/error.h"
-#include "qapi/error-internal.h"
-#include "qemu/log-for-trace.h"
-#include "qemu/log.h"
-#include "qemu/module.h"
-#include "qemu/timer.h"