Skip to content

Commit 34b7af4

Browse files
authored
fix(qt): rcc tracks the files a .qrc references (#42)
`qrc_files` read `node::text` of the `<file>` element, which the XML reader never sets: an element's characters live in its unnamed text children, as the writer itself reads them. Every `.qrc`-referenced file was therefore left out of the `rcc` action's inputs, so a changed resource -- an embedded zip, say -- did not regenerate the resource source. The text children are now joined and trimmed, which is what a path split by an intervening comment and padded with whitespace needs. A `plugin-logic` case drives the real Qt rule and asserts both resource files appear in the emitted `qt:rcc:app` action: one plain path, one aliased path whose text the reader splits. Measured on this machine with the released engine: 22 of 23 cases without the fix, with both resource assertions failing, and 23 of 23 with it.
1 parent 6dc3490 commit 34b7af4

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎rules/qt.cppm‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,12 @@ inline std::vector<std::string> qrc_files(const std::filesystem::path& qrc) {
256256
if (!mcpp::plugins::xml::parse(read_file(qrc), doc, error)) return out;
257257
std::function<void(const mcpp::plugins::xml::node&)> walk = [&](const mcpp::plugins::xml::node& n) {
258258
if (n.name == "file") {
259-
std::string text = mcpp::plugins::xml::trim_copy(n.text);
259+
// The XML reader stores element text in unnamed child nodes.
260+
std::string text;
261+
for (auto const& child : n.children) {
262+
if (child.name.empty()) text += child.text;
263+
}
264+
text = mcpp::plugins::xml::trim_copy(text);
260265
if (!text.empty()) out.push_back(generic(qrc.parent_path() / text));
261266
}
262267
for (auto const& c : n.children) walk(c);

‎tests/plugin-logic/build.mcpp‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,34 @@ int main(int argc, char** argv) {
446446
"moc reads no header another build system wrote");
447447
} },
448448

449+
{ "qt: rcc tracks the resource paths stored in XML text children",
450+
with_qt(t::row::linux_gcc())
451+
.file("qt/bin/rcc").file("qt/bin/rcc.exe")
452+
.file("pkg/res/app.qrc",
453+
"<RCC><qresource prefix=\"/\">\n"
454+
" <file>assets/greeting.txt</file>\n"
455+
" <file alias=\"sample.zip\"> \n"
456+
" data/Sample<!-- split text -->Project.zip \n"
457+
" </file>\n"
458+
"</qresource></RCC>\n")
459+
.file("pkg/res/assets/greeting.txt", "hello\n")
460+
.file("pkg/res/data/SampleProject.zip", "resource contents\n"),
461+
[] {
462+
mcpp::rules::qt::options o;
463+
o.root = "../qt";
464+
o.modules = {"Core"};
465+
o.resources = {"res/app.qrc"};
466+
return mcpp::rules::qt::compile(o) ? 0 : 1;
467+
},
468+
[](const t::result& r, t::checker& c) {
469+
c.expect(r.exit_code == 0, "the member succeeds");
470+
const auto a = r.line("mcpp:action=", {"qt:rcc:app"});
471+
c.expect(a.find("pkg/res/assets/greeting.txt") != std::string::npos,
472+
"rcc tracks a resource relative to the qrc directory");
473+
c.expect(a.find("pkg/res/data/SampleProject.zip") != std::string::npos,
474+
"rcc tracks the aliased source after joining and trimming text children");
475+
} },
476+
449477
// ── compatibility ───────────────────────────────────────────────────
450478
{ "compat: program_compilers keeps its 0.16.0 answer and says until when",
451479
t::row::linux_libcxx().file("llvm/bin/clang").file("llvm/bin/clang++"),

0 commit comments

Comments
 (0)