Skip to content

Commit

Permalink
Add cxx_qt::init_crate! and init_qml_module!
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonMatthesKDAB committed Feb 5, 2025
1 parent e50ae96 commit f9b6aa1
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
1 change: 1 addition & 0 deletions crates/cxx-qt-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ proc-macro = true
cxx-qt-gen.workspace = true
proc-macro2.workspace = true
syn.workspace = true
quote.workspace = true

[dev-dependencies]
cxx.workspace = true
Expand Down
30 changes: 30 additions & 0 deletions crates/cxx-qt-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,36 @@ pub fn qobject(_args: TokenStream, _input: TokenStream) -> TokenStream {
unreachable!("qobject should not be used as a macro by itself. Instead it should be used within a cxx_qt::bridge definition")
}

/// Force a crate to be initialized
#[proc_macro]
pub fn init_crate(args: TokenStream) -> TokenStream {
let crate_name = syn::parse_macro_input!(args as syn::Ident);
let function_name = quote::format_ident!("cxx_qt_init_crate_{crate_name}");
quote::quote! {
extern "C" {
fn #function_name() -> bool;
}
unsafe { #function_name(); }
}
.into()
}

/// Force a QML module with the given URI to be initialized
#[proc_macro]
pub fn init_qml_module(args: TokenStream) -> TokenStream {
let module_uri = syn::parse_macro_input!(args as syn::LitStr);
let module_name = syn::Ident::new(&module_uri.value().replace('.', "_"), module_uri.span());

let function_name = quote::format_ident!("cxx_qt_init_qml_module_{module_name}");
quote::quote! {
extern "C" {
fn #function_name() -> bool;
}
unsafe { #function_name(); }
}
.into()
}

// Take the module and C++ namespace and generate the rust code
fn extract_and_generate(module: ItemMod) -> TokenStream {
Parser::from(module)
Expand Down
2 changes: 2 additions & 0 deletions crates/cxx-qt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub mod signalhandler;
mod threading;

pub use cxx_qt_macro::bridge;
pub use cxx_qt_macro::init_crate;
pub use cxx_qt_macro::init_qml_module;
pub use cxx_qt_macro::qobject;

pub use connection::{ConnectionType, QMetaObjectConnection};
Expand Down
28 changes: 13 additions & 15 deletions examples/meta_project/rust/main/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,12 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

extern crate qml_meta_project;
// mod main_object;
// extern crate sub1;
// extern crate sub2;

use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QUrl};

fn main() {
// extern "C" {
// fn cxx_qt_init_crate_qml_meta_project() -> bool;
// }

// extern "C" {
// fn cxx_qt_init_qml_module_com_kdab_cxx_qt_demo() -> bool;
// }

// unsafe {
// cxx_qt_init_crate_qml_meta_project();
// cxx_qt_init_qml_module_com_kdab_cxx_qt_demo();
// }
cxx_qt::init_crate!(qml_meta_project);
cxx_qt::init_qml_module!("com.kdab.cxx_qt.demo");

// Create the application and engine
let mut app = QGuiApplication::new();
Expand All @@ -48,3 +35,14 @@ fn main() {
app.exec();
}
}

#[cfg(test)]
mod tests {
// In the test cfg there needs to be at least one test that calls the crate initialization.
// Otherwise linking will fail!
#[test]
fn init_dependencies() {
cxx_qt::init_crate!(qml_meta_project);
cxx_qt::init_qml_module!("com.kdab.cxx_qt.demo");
}
}

0 comments on commit f9b6aa1

Please sign in to comment.