qt_build_utils/tool/
rcc.rs1use crate::{Initializer, QtInstallation, QtTool};
7
8use semver::Version;
9use std::{
10 ffi::{OsStr, OsString},
11 path::{Path, PathBuf},
12 process::Command,
13};
14
15pub struct QtToolRcc {
17 executable: PathBuf,
18 qt_version: Version,
19 custom_args: Vec<OsString>,
20}
21
22impl QtToolRcc {
23 pub fn new(qt_installation: &dyn QtInstallation) -> Self {
25 let executable = qt_installation
26 .try_find_tool(QtTool::Rcc)
27 .expect("Could not find rcc");
28 let qt_version = qt_installation.version();
29
30 Self {
31 executable,
32 qt_version,
33 custom_args: Vec::new(),
34 }
35 }
36
37 pub fn custom_args(mut self, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> Self {
39 self.custom_args = args
40 .into_iter()
41 .map(|s| s.as_ref().to_os_string())
42 .collect();
43 self
44 }
45
46 pub fn compile(&self, input_file: impl AsRef<Path>) -> Initializer {
54 let input_path = input_file.as_ref();
55 let output_folder = QtTool::Rcc.writable_path();
56 std::fs::create_dir_all(&output_folder).expect("Could not create qrc dir");
57 let mut output_path = output_folder.join(input_path.file_name().unwrap());
58 output_path.set_extension("cpp");
59 let name = input_path
60 .file_name()
61 .unwrap()
62 .to_string_lossy()
63 .replace('.', "_");
64
65 let mut args = vec![
66 OsString::from(input_path),
67 OsString::from("-o"),
68 OsString::from(&output_path),
69 OsString::from("--name"),
70 OsString::from(&name),
71 ];
72 args.extend(self.custom_args.iter().cloned());
73
74 let cmd = Command::new(&self.executable)
75 .args(args)
76 .output()
77 .unwrap_or_else(|_| panic!("rcc failed for {}", input_path.display()));
78
79 if !cmd.status.success() {
80 panic!(
81 "rcc failed for {}:\n{}",
82 input_path.display(),
83 String::from_utf8_lossy(&cmd.stderr)
84 );
85 }
86
87 let qt_6_5 = Version::new(6, 5, 0);
88 let init_header = if self.qt_version >= qt_6_5 {
89 "QtCore/QtResource"
91 } else {
92 "QtCore/QDir"
93 };
94 Initializer {
95 file: Some(output_path),
96 init_call: Some(format!("Q_INIT_RESOURCE({name});")),
97 init_declaration: Some(format!("#include <{init_header}>")),
98 }
99 }
100
101 pub fn list(&self, input_file: impl AsRef<Path>) -> Vec<PathBuf> {
103 let input_path = input_file.as_ref();
105 let cmd_list = Command::new(&self.executable)
106 .args(["--list", input_path.to_str().unwrap()])
107 .output()
108 .unwrap_or_else(|_| panic!("rcc --list failed for {}", input_path.display()));
109
110 if !cmd_list.status.success() {
111 panic!(
112 "rcc --list failed for {}:\n{}",
113 input_path.display(),
114 String::from_utf8_lossy(&cmd_list.stderr)
115 );
116 }
117
118 String::from_utf8_lossy(&cmd_list.stdout)
119 .split('\n')
120 .map(PathBuf::from)
121 .collect()
122 }
123}