Skip to content

Commit

Permalink
run qmlcachegen on registered QML modules
Browse files Browse the repository at this point in the history
Fixes KDAB#242
  • Loading branch information
Be-ing committed Aug 8, 2023
1 parent 324fc7c commit 4c69d3a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
3 changes: 3 additions & 0 deletions crates/cxx-qt-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,9 @@ impl CxxQtBuilder {
self.cc_builder.file(qml_module_registration_files.plugin);
cc_builder_whole_archive.file(qml_module_registration_files.plugin_init);
cc_builder_whole_archive.file(qml_module_registration_files.rcc);
for qmlcachegen_file in qml_module_registration_files.qmlcachegen {
cc_builder_whole_archive.file(qmlcachegen_file);
}
self.cc_builder.define("QT_STATICPLUGIN", None);
cc_builder_whole_archive_files_added = true;
}
Expand Down
86 changes: 86 additions & 0 deletions crates/qt-build-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ pub struct QmlModuleRegistrationFiles {
/// must be linked with [+whole-archive](https://doc.rust-lang.org/rustc/command-line-arguments.html#linking-modifiers-whole-archive)
/// or the linker will discard the generated static variables because they are not referenced from `main`.
pub rcc: PathBuf,
/// Files generated by [qmlcachegen](https://doc.qt.io/qt-6/qtqml-qtquick-compiler-tech.html). Must be linked with `+whole-archive`.
pub qmlcachegen: Vec<PathBuf>,
/// File generated by [qmltyperegistrar](https://www.qt.io/blog/qml-type-registration-in-qt-5.15) CLI tool.
pub qmltyperegistrar: PathBuf,
/// File with generated [QQmlEngineExtensionPlugin](https://doc.qt.io/qt-6/qqmlengineextensionplugin.html) that calls the function generated by qmltyperegistrar.
Expand Down Expand Up @@ -672,6 +674,89 @@ prefer :/qt/qml/{qml_uri_dirs}/
.expect("Could note write qrc file");
}

// Run qmlcachegen
// qmlcachegen needs to be run once for each .qml file with --resource-path,
// then once for the module with --resource-name.
let mut qmlcachegen_file_paths = Vec::new();
if let Some(qmlcachegen_executable) = &self.qmlcachegen_executable {
let qmlcachegen_dir = format!("{out_dir}/qmlcachegen/{qml_uri_dirs}");
std::fs::create_dir_all(&qmlcachegen_dir)
.expect("Could not create qmlcachegen directory for QML module");

let common_args = vec![
"-i".to_string(),
qmldir_file_path.to_string(),
"--resource".to_string(),
qrc_path.clone(),
];

let mut qml_file_qrc_paths = Vec::new();
for file in qml_files {
let qrc_resource_path =
format!("/qt/qml/{qml_uri_dirs}/{}", file.as_ref().display());

let qml_compiled_file = format!(
"{qmlcachegen_dir}/{}.cpp",
file.as_ref().file_name().unwrap().to_string_lossy()
);
qmlcachegen_file_paths.push(PathBuf::from(&qml_compiled_file));

let specific_args = vec![
"--resource-path".to_string(),
qrc_resource_path.clone(),
"-o".to_string(),
qml_compiled_file,
std::fs::canonicalize(file)
.unwrap()
.to_string_lossy()
.to_string(),
];

let cmd = Command::new(qmlcachegen_executable)
.args(common_args.iter().chain(&specific_args))
.output()
.unwrap_or_else(|_| {
panic!(
"qmlcachegen failed for {} in QML module {uri}",
file.as_ref().display()
)
});
if !cmd.status.success() {
panic!(
"qmlcachegen failed for {} in QML module {uri}:\n{}",
file.as_ref().display(),
String::from_utf8_lossy(&cmd.stderr)
);
}
qml_file_qrc_paths.push(qrc_resource_path);
}

let qmlcachegen_loader = format!("{qmlcachegen_dir}/qmlcache_loader.cpp");
let specific_args = vec![
"--resource-name".to_string(),
format!("qmlcache_{qml_uri_underscores}"),
"-o".to_string(),
qmlcachegen_loader.clone(),
];

let cmd = Command::new(qmlcachegen_executable)
.args(
common_args
.iter()
.chain(&specific_args)
.chain(&qml_file_qrc_paths),
)
.output()
.unwrap_or_else(|_| panic!("qmlcachegen failed for QML module {uri}"));
if !cmd.status.success() {
panic!(
"qmlcachegen failed for QML module {uri}:\n{}",
String::from_utf8_lossy(&cmd.stderr)
);
}
qmlcachegen_file_paths.push(PathBuf::from(&qmlcachegen_loader));
}

// Run qmltyperegistrar
let qmltyperegistrar_output_path = PathBuf::from(&format!(
"{out_dir}/{qml_uri_underscores}_qmltyperegistration.cpp"
Expand Down Expand Up @@ -755,6 +840,7 @@ Q_IMPORT_PLUGIN({plugin_class_name});

QmlModuleRegistrationFiles {
rcc: self.qrc(&qrc_path),
qmlcachegen: qmlcachegen_file_paths,
qmltyperegistrar: qmltyperegistrar_output_path,
plugin: qml_plugin_cpp_path,
plugin_init: qml_plugin_init_path,
Expand Down

0 comments on commit 4c69d3a

Please sign in to comment.