From 82efc0320beeb7bc4cb03e8025b3f38a9ee8f2c6 Mon Sep 17 00:00:00 2001 From: Alexander Kiselev Date: Wed, 18 Dec 2024 16:54:37 -0800 Subject: [PATCH] Add support for C++ QML QObjects in CxxQtBuilder - Introduce qml_qobjects field to CxxQtBuilder struct - Implement qml_qobject method for adding QML QObject files - Process QML QObjects in build method, including moc generation - Include generated metatypes.json for QML module support - Update rerun-if-changed cargo instructions for added files --- crates/cxx-qt-build/src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/crates/cxx-qt-build/src/lib.rs b/crates/cxx-qt-build/src/lib.rs index eebb5f789..7ceb6fadd 100644 --- a/crates/cxx-qt-build/src/lib.rs +++ b/crates/cxx-qt-build/src/lib.rs @@ -358,6 +358,7 @@ pub struct CxxQtBuilder { public_interface: Option, include_prefix: String, initializers: Vec, + qml_qobjects: Vec<(PathBuf, PathBuf)>, } impl CxxQtBuilder { @@ -398,6 +399,7 @@ impl CxxQtBuilder { initializers: vec![], public_interface: None, include_prefix: crate_name(), + qml_qobjects: vec![], } } @@ -532,6 +534,22 @@ impl CxxQtBuilder { self } + /// Specify a C++ header and source file containing a Q_OBJECT macro to run [moc](https://doc.qt.io/qt-6/moc.html) on. + /// Unlike [CxxQtBuilder::qobject_header], it includes the generated metatypes.json, so that C++ classes can be included + /// in QML modules. + pub fn qml_qobject( + mut self, + qobject_header: impl AsRef, + qobject_source: impl AsRef, + ) -> Self { + let qobject_header = qobject_header.as_ref().to_path_buf(); + let qobject_source = qobject_source.as_ref().to_path_buf(); + println!("cargo::rerun-if-changed={}", qobject_header.display()); + println!("cargo::rerun-if-changed={}", qobject_source.display()); + self.qml_qobjects.push((qobject_header, qobject_source)); + self + } + /// Use a closure to run additional customization on [CxxQtBuilder]'s internal [cc::Build] /// before calling [CxxQtBuilder::build]. This allows to add extra include paths, compiler flags, /// or anything else available via [cc::Build]'s API. For example, to add an include path for @@ -844,6 +862,22 @@ impl CxxQtBuilder { } } + for (qobject_header, qobject_source) in &self.qml_qobjects { + cc_builder.file(qobject_source); + if let Some(dir) = qobject_header.parent() { + moc_include_paths.insert(dir.to_path_buf()); + } + let moc_products = qtbuild.moc( + qobject_header, + MocArguments::default().uri(qml_module.uri.clone()), + ); + if let Some(dir) = moc_products.cpp.parent() { + moc_include_paths.insert(dir.to_path_buf()); + } + cc_builder.file(moc_products.cpp); + qml_metatypes_json.push(moc_products.metatypes_json); + } + let qml_module_registration_files = qtbuild.register_qml_module( &qml_metatypes_json, &qml_module.uri,