qt_build_utils/tool/
qmlcachegen.rs1use crate::{QmlUri, QtInstallation, QtTool};
7use std::{
8 path::{Path, PathBuf},
9 process::Command,
10};
11
12#[derive(Clone)]
14pub struct QmlCacheArguments {
15 pub uri: QmlUri,
17 pub qmldir_path: PathBuf,
19 pub qmldir_qrc_path: PathBuf,
21}
22
23pub struct QmlCacheProducts {
25 pub qml_cache_path: PathBuf,
27 pub qml_resource_path: String,
29}
30
31pub struct QtToolQmlCacheGen {
33 executable: PathBuf,
34}
35
36impl QtToolQmlCacheGen {
37 pub fn new(qt_installation: &dyn QtInstallation) -> Self {
39 let executable = qt_installation
40 .try_find_tool(QtTool::QmlCacheGen)
41 .expect("Could not find qmlcachegen");
42
43 Self { executable }
44 }
45
46 pub fn compile(
48 &self,
49 common_args: QmlCacheArguments,
50 file: impl AsRef<Path>,
51 ) -> QmlCacheProducts {
52 let uri = common_args.uri;
53 let qml_uri_dirs = uri.as_dirs();
54
55 let qmlcachegen_dir = QtTool::QmlCacheGen.writable_path().join(&qml_uri_dirs);
56 std::fs::create_dir_all(&qmlcachegen_dir)
57 .expect("Could not create qmlcachegen directory for QML module");
58
59 let common_args = [
60 "-i".to_owned(),
61 common_args.qmldir_path.to_string_lossy().into_owned(),
62 "--resource".to_owned(),
63 common_args.qmldir_qrc_path.to_string_lossy().into_owned(),
64 ];
65
66 let qml_cache_path = qmlcachegen_dir.join(format!(
67 "{}.cpp",
68 file.as_ref().file_name().unwrap().to_string_lossy()
69 ));
70
71 let qml_resource_path = format!("/qt/qml/{qml_uri_dirs}/{}", file.as_ref().display());
72
73 let specific_args = vec![
74 "--resource-path".to_owned(),
75 qml_resource_path.clone(),
76 "-o".to_owned(),
77 qml_cache_path.to_string_lossy().into_owned(),
78 std::fs::canonicalize(&file)
79 .unwrap()
80 .to_string_lossy()
81 .into_owned(),
82 ];
83
84 let cmd = Command::new(&self.executable)
85 .args(common_args.iter().chain(&specific_args))
86 .output()
87 .unwrap_or_else(|_| {
88 panic!(
89 "qmlcachegen failed for {} in QML module {uri}",
90 file.as_ref().display()
91 )
92 });
93 if !cmd.status.success() {
94 panic!(
95 "qmlcachegen failed for {} in QML module {uri}:\n{}",
96 file.as_ref().display(),
97 String::from_utf8_lossy(&cmd.stderr)
98 );
99 }
100
101 QmlCacheProducts {
102 qml_cache_path,
103 qml_resource_path,
104 }
105 }
106
107 pub fn compile_loader(
109 &self,
110 common_args: QmlCacheArguments,
111 qml_resource_paths: &[String],
112 ) -> PathBuf {
113 let uri = common_args.uri;
114 let qml_uri_dirs = uri.as_dirs();
115 let qml_uri_underscores = uri.as_underscores();
116
117 let qmlcachegen_dir = QtTool::QmlCacheGen.writable_path().join(qml_uri_dirs);
118 std::fs::create_dir_all(&qmlcachegen_dir)
119 .expect("Could not create qmlcachegen directory for QML module");
120
121 let common_args = [
122 "-i".to_owned(),
123 common_args.qmldir_path.to_string_lossy().into_owned(),
124 "--resource".to_owned(),
125 common_args.qmldir_qrc_path.to_string_lossy().into_owned(),
126 ];
127
128 let qmlcachegen_loader = qmlcachegen_dir.join("qmlcache_loader.cpp");
129 let specific_args = vec![
130 "--resource-name".to_owned(),
131 format!("qmlcache_{qml_uri_underscores}"),
132 "-o".to_owned(),
133 qmlcachegen_loader.to_string_lossy().into_owned(),
134 ];
135
136 let cmd = Command::new(&self.executable)
137 .args(
138 common_args
139 .iter()
140 .chain(&specific_args)
141 .chain(qml_resource_paths),
142 )
143 .output()
144 .unwrap_or_else(|_| panic!("qmlcachegen failed for QML module {uri}"));
145 if !cmd.status.success() {
146 panic!(
147 "qmlcachegen failed for QML module {uri}:\n{}",
148 String::from_utf8_lossy(&cmd.stderr)
149 );
150 }
151
152 qmlcachegen_loader
153 }
154}