Skip to content

Commit 25e5c11

Browse files
authored
0.13.1: lupdate names the .ts it rewrites as its output instead of claiming the file's directory (#30)
1 parent 3a6f1c2 commit 25e5c11

8 files changed

Lines changed: 42 additions & 29 deletions

File tree

‎.github/scripts/check-deps-and-qt.sh‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,25 @@ qt_consumer() {
132132
cd "$ROOT/tests/qt-consumer"
133133
rm -rf target
134134
mkdir -p target/ci
135-
"$MCPP" build 2>&1 | tee target/ci/build.log
135+
"$MCPP" build -v 2>&1 | tee target/ci/build.log
136+
# lupdate writes the `.ts` in the package root and lrelease reads it after;
137+
# neither claims the package's directory as a construction output.
138+
local lu lr
139+
lu=$(grep -n '/lupdate[^ ]* ' target/ci/build.log | head -1 | cut -d: -f1)
140+
lr=$(grep -n '/lrelease[^ ]* ' target/ci/build.log | head -1 | cut -d: -f1)
141+
[ -n "$lu" ] && [ -n "$lr" ] && [ "$lu" -lt "$lr" ] || fail "lupdate did not run before lrelease"
142+
! grep -q 'output_dir' target/ci/build.log || fail "the build reports a construction directory over the package's sources"
143+
echo "ok: lupdate updated the .ts before lrelease read it"
136144
"$MCPP" run | tee target/ci/run.log
137145
grep -qE "^qt-consumer: signal 42, resource 'greetings from rcc', translation 'hallo', Qt 6\." target/ci/run.log ||
138146
fail "moc, rcc or lrelease did not reach the program"
139147
find target -name 'qt_consumer_de.qm' | grep -q . || fail "no .qm was produced"
140148
echo "ok: moc (header and inline), rcc and lrelease reached the program"
149+
"$MCPP" build --profile dev -v > target/ci/second-build.log 2>&1 ||
150+
{ cat target/ci/second-build.log; fail "the second build failed"; }
151+
! grep -qE '/(lupdate|lrelease)[^ ]* ' target/ci/second-build.log ||
152+
fail "a second build with nothing changed re-ran lupdate or lrelease"
153+
echo "ok: a second build with nothing changed ran neither lupdate nor lrelease"
141154
}
142155

143156
qt_widgets_consumer() {

‎README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ CI measures the rest:
852852

853853
```toml
854854
[build-dependencies.mcpp]
855-
plugins = { version = "0.13.0", features = ["deps-vcpkg"], host-module = true, tools = ["mcpp-deps"] }
855+
plugins = { version = "0.13.1", features = ["deps-vcpkg"], host-module = true, tools = ["mcpp-deps"] }
856856
```
857857

858858
```cpp
@@ -944,7 +944,7 @@ default unless `cache_args` names another.
944944

945945
```toml
946946
[build-dependencies.mcpp]
947-
plugins = { version = "0.13.0", features = ["rules-qt-xim"], host-module = true }
947+
plugins = { version = "0.13.1", features = ["rules-qt-xim"], host-module = true }
948948

949949
[build]
950950
sources = ["src/*.cpp", "res/*.qrc", "i18n/*.ts", "ui/*.ui"]
@@ -974,7 +974,7 @@ int main() {
974974
| `private_modules` | modules whose private headers are included |
975975
| `moc`, `moc_headers` | `moc_scan::project_headers` (default) scans the package's headers by content; `moc_scan::listed` takes `moc_headers` only |
976976
| `forms`, `resources` | `.ui` and `.qrc` files beside those in `[build] sources` |
977-
| `i18n` | `.ts` files beside those in `[build] sources`; `update_sources` runs `lupdate` as a `prepare` action, whose output directory is the `.ts` files', before `lrelease`; `tr_function_alias`; `deploy_to` (default `translations`); `out_dir`, where `lrelease` writes (default `<out dir>/qt/translations`) |
977+
| `i18n` | `.ts` files beside those in `[build] sources`; `update_sources` runs `lupdate` before `lrelease`, as an action whose output is the `.ts` file it rewrites; `tr_function_alias`; `deploy_to` (default `translations`); `out_dir`, where `lrelease` writes (default `<out dir>/qt/translations`) |
978978
| `deploy_plugins` | plugin directories placed beside the program; default `platforms` |
979979
| `deploy_software_gl` | Windows: `opengl32sw.dll` and `d3dcompiler_47.dll` beside the program |
980980
| `root`, `extra_roots` | an SDK, and further prefixes |

‎mcpp.toml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "plugins"
33
namespace = "mcpp"
4-
version = "0.13.0"
4+
version = "0.13.1"
55
description = "Official mcpp build plugins: rule packages under mcpp.rules.*, build-time utilities under mcpp.tools.*, each member selected by a feature"
66
license = "Apache-2.0"
77
authors = ["mcpp-community"]
@@ -653,7 +653,7 @@ main = "tools/embed_main.cpp"
653653
# it by a release.
654654
#
655655
# [build-dependencies.mcpp]
656-
# plugins = { version = "0.13.0", features = ["deps-vcpkg"],
656+
# plugins = { version = "0.13.1", features = ["deps-vcpkg"],
657657
# host-module = true, tools = ["mcpp-deps"] }
658658
[targets.mcpp-deps]
659659
kind = "bin"

‎rules/qt.cppm‎

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434
// declares nothing, so the plan succeeds and the build is where it fails.
3535
//
3636
// `lupdate` REWRITES SOURCES, so it is off unless `translations::update_sources`
37-
// asks for it; then it is a `prepare` action whose stamp `lrelease` waits for,
38-
// the order Qt's Visual Studio integration runs them in.
37+
// asks for it; then it is an action whose output is the `.ts` file itself, and
38+
// `lrelease` reads that file, the order Qt's Visual Studio integration runs
39+
// them in.
3940

4041
module;
4142
#include <cctype>
@@ -447,7 +448,7 @@ inline bool compile(options opt = {}) {
447448
const std::string desc = "MOC " + in.filename().string();
448449
mcpp::action a;
449450
a.id = id.c_str();
450-
a.role = "source";
451+
a.role = mcpp::roles::source;
451452
a.description = desc.c_str();
452453
a.depfile = dep.c_str();
453454
a.arg(moc.c_str()).arg(src.c_str()).arg("-o").arg(out.c_str())
@@ -477,7 +478,7 @@ inline bool compile(options opt = {}) {
477478
const std::string desc = "UIC " + fs::path(f).filename().string();
478479
mcpp::action a;
479480
a.id = id.c_str();
480-
a.role = "source";
481+
a.role = mcpp::roles::source;
481482
a.description = desc.c_str();
482483
a.arg(uic.c_str()).arg(in.c_str()).arg("-o").arg(out.c_str())
483484
.input(in.c_str()).output(out.c_str()).submit();
@@ -505,7 +506,7 @@ inline bool compile(options opt = {}) {
505506
mcpp::rerun_if_changed(in.c_str());
506507
mcpp::action a;
507508
a.id = id.c_str();
508-
a.role = "source";
509+
a.role = mcpp::roles::source;
509510
a.description = desc.c_str();
510511
a.arg(rcc.c_str()).arg("--name").arg(stem.c_str()).arg(in.c_str()).arg("-o").arg(out.c_str())
511512
.input(in.c_str());
@@ -545,37 +546,29 @@ inline bool compile(options opt = {}) {
545546
const fs::path qmDir = opt.i18n.out_dir.empty() ? gen / "translations"
546547
: detail::absolute_from_root(opt.i18n.out_dir);
547548
const std::string qm = generic(qmDir / (stem + ".qm"));
548-
std::string stamp;
549549
if (opt.i18n.update_sources) {
550-
stamp = generic(gen / (stem + ".lupdate.stamp"));
551550
const std::string id = "qt:lupdate:" + stem;
552551
const std::string desc = "LUPDATE " + file.filename().string();
553552
mcpp::action u;
554553
u.id = id.c_str();
555-
// Construction, not validation (SPEC-007 R3.4): lupdate
556-
// rewrites the `.ts` files in their directory, which lrelease
557-
// reads, so it is a `prepare` whose output directory is theirs.
558-
u.role = mcpp::roles::prepare;
554+
// The file lupdate writes is named before it runs, so the action
555+
// names it as its output (SPEC-007 R3.2) and needs neither a
556+
// stamp nor a `prepare` directory. `lrelease` takes the same file
557+
// as its input, which orders the two.
558+
u.role = mcpp::roles::source;
559559
u.description = desc.c_str();
560560
u.arg(lupdate.c_str()).arg("-silent").arg("-extensions").arg("cpp,h,hpp,ixx,cppm");
561561
for (auto const& a : opt.i18n.tr_function_alias) u.arg("-tr-function-alias").arg(a.c_str());
562562
for (auto const& s : sources) u.arg(s.c_str()).input(s.c_str());
563-
// The stamp is written by mcpp when lupdate succeeds (a
564-
// prepare's command need not write its own); `lrelease` takes it as an
565-
// input, so it reads the `.ts` lupdate has rewritten.
566-
// `output_dir` keeps the pointer it is given, unlike `arg()`,
567-
// so the string is a local that outlives `submit()`.
568-
const std::string tsDir = generic(file.parent_path());
569-
u.arg("-ts").arg(in.c_str()).output(stamp.c_str()).output_dir(tsDir.c_str()).submit();
563+
u.arg("-ts").arg(in.c_str()).output(in.c_str()).submit();
570564
}
571565
const std::string id = "qt:lrelease:" + stem;
572566
const std::string desc = "LRELEASE " + file.filename().string();
573567
mcpp::action r;
574568
r.id = id.c_str();
575-
r.role = "source";
569+
r.role = mcpp::roles::source;
576570
r.description = desc.c_str();
577571
r.arg(lrelease.c_str()).arg("-silent").arg(in.c_str()).arg("-qm").arg(qm.c_str()).input(in.c_str());
578-
if (!stamp.empty()) r.input(stamp.c_str());
579572
r.output(qm.c_str()).submit();
580573
mcpp::deploy(qm.c_str(), opt.i18n.deploy_to.c_str());
581574
}

‎src/plugins.cppm‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export namespace mcpp::plugins {
4949
//
5050
// One package, one version: the number lives in mcpp.toml, and the CI step
5151
// `the collection states its own version` compares the two.
52-
inline constexpr std::string_view version = "0.13.0";
52+
inline constexpr std::string_view version = "0.13.1";
5353

5454
} // namespace mcpp::plugins
5555

‎tests/qt-consumer/build.mcpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@ int main() {
77
mcpp::rules::qt::options o;
88
o.modules = { "Core" };
99
o.deploy_plugins = {};
10+
// lupdate brings the `.ts` up to date with src/ before lrelease reads it.
11+
// The committed file is lupdate's own output, so a build leaves it as is.
12+
o.i18n.update_sources = true;
1013
return mcpp::rules::qt::compile(o) ? 0 : 1;
1114
}

‎tests/qt-consumer/mcpp.toml‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
# src/counter.h declares a Q_OBJECT class -> moc
99
# src/main.cpp includes "main.moc" -> moc, inline
1010
# res/app.qrc names res/greeting.txt -> rcc
11-
# i18n/qt_consumer_de.ts -> lrelease, deployed
11+
# qt_consumer_de.ts updated from src/ by lupdate -> lrelease, deployed
1212
# under translations/
1313
#
14+
# The `.ts` sits in the package root, as it does in GalTranslPP, so lupdate
15+
# writes one file there and claims no directory.
16+
#
1417
# and the program prints what each produced: a signal delivered to a slot, a
1518
# resource read through `:/`, and a string translated by the `.qm` it loaded
1619
# from beside itself. `widgets/` is the second fixture, for Qt Widgets, `.ui`
@@ -39,7 +42,7 @@ plugins = { path = "../..", features = ["rules-qt-xim"], host-module = true }
3942
# on the MSVC ABI the static CRT; a PE image resolves its imports per DLL, so
4043
# Qt's DLLs keep their own CRT.
4144
cxx_runtime = "toolchain-coupled"
42-
sources = ["src/*.cpp", "res/*.qrc", "i18n/*.ts"]
45+
sources = ["src/*.cpp", "res/*.qrc", "*.ts"]
4346

4447
[targets.qt-consumer]
4548
kind = "bin"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<context>
55
<name>main</name>
66
<message>
7+
<location filename="src/main.cpp" line="43"/>
78
<source>hello</source>
89
<translation>hallo</translation>
910
</message>

0 commit comments

Comments
 (0)