Skip to content

Commit 6b1f379

Browse files
committed
0.14.0: rules-qt-xim-base declares xim:qt-base, qtbase and qttools with the QtQml library lupdate loads; the console Qt fixture uses it
1 parent b03a78c commit 6b1f379

5 files changed

Lines changed: 32 additions & 10 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ jobs:
16621662
# A console program: QtCore, which is what Linux is served for. QtGui
16631663
# loads libdbus, which the ecosystem does not publish, so the Widgets
16641664
# fixture runs on Windows only.
1665-
- name: rules-qt runs moc, rcc and lrelease, with the SDK from xim:qt
1665+
- name: rules-qt runs moc, rcc, lupdate and lrelease, with the SDK from xim:qt-base
16661666
run: bash .github/scripts/check-deps-and-qt.sh qt-consumer
16671667

16681668
# ── THE SAME RULE ON THE OTHER TWO PLATFORMS ────────────────────────────────
@@ -2337,7 +2337,7 @@ jobs:
23372337
- name: deps-cmake builds a CMake subproject as an action and links it
23382338
run: bash .github/scripts/check-deps-and-qt.sh cmake-consumer
23392339

2340-
- name: rules-qt runs moc, rcc and lrelease, with the SDK from xim:qt
2340+
- name: rules-qt runs moc, rcc, lupdate and lrelease, with the SDK from xim:qt-base
23412341
run: bash .github/scripts/check-deps-and-qt.sh qt-consumer
23422342

23432343
# Windows and macOS: QtGui's dependencies are the system's there. On Linux

‎README.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ engine's own module family and is not used here.
7878
| `rules-cuda` | `mcpp.rules.cuda` | 2026.9.6.6 | `[build] accel = "cuda…"`, a constrained glob for `*.cu`; the clang route with an LLVM toolchain, the nvcc route with a GCC one |
7979
| `rules-hip` | `mcpp.rules.hip` | 2026.9.6.6 | `[build] accel = "hip, cuda12.9+{sm_89}"`, a constrained glob for `*.hip`. On the NVIDIA platform HIP is a header layer over the CUDA runtime, so the compiler is the project's own clang and there is no ROCm on the machine |
8080
| `rules-metal` | `mcpp.rules.metal` | 2026.9.8.1 | the Metal toolchain of the macOS host's Xcode, located rather than installed: Xcode is not redistributable, so no payload is declared. `.metal` sources the project names on a macOS or iOS row become one `xcrun --sdk <sdk> metal` action per shader (`-MMD`, so an edited `#include` recompiles the shaders that include it) and one `xcrun --sdk <sdk> metallib` action per library, placed beside the program with `mcpp::deploy` under `metallib/`, which `dist-apple` maps into the bundle's resources. `compile(shaders)` compiles one source several times with definitions of its own, one library per `shader`; `options::library` links every shader into one library (`default` is the one `newDefaultLibrary` finds). Before planning anything the rule asks `xcrun --sdk <sdk> --show-sdk-path` and `--find metal` / `--find metallib`, and refuses naming the command that answered nothing, because a missing SDK and a missing compiler have different remedies (Xcode 26 installs the Metal toolchain as a separate component). A shader on any other row is refused naming the row. CI compiles the fixture on `macos-15` and checks each library's magic, and that a header edit recompiles only the shaders that include it |
81-
| `rules-qt` | `mcpp.rules.qt` | 2026.9.26.2 (mcpp#702) | a Qt 6 SDK: `rules-qt-xim` declares `xim:qt` 6.11.1 on the target axis, `rules-qt-xim-addons` adds `xim:qt-addons` (the additional libraries) as a second prefix, and `options::root` names an SDK from elsewhere. From 0.13.0. `moc` for every header under the package root that declares `Q_OBJECT`, `Q_GADGET` or `Q_NAMESPACE` and for a source that includes its own `<stem>.moc`; `uic` for `.ui`, `rcc` for `.qrc`, `lrelease` for `.ts` (named in `[build] sources` or in the options), each a `role = "source"` action with declared inputs. The modules are linked by full path, and the SDK's `bin/` (Windows) or `lib/` is a runtime search directory: the program's run path, `mcpp run`'s load path, `mcpp pack`'s closure, and on Windows the Qt DLLs the program imports placed beside it by the engine. The plugin directories `deploy_plugins` names are deployed beside the program. See [`deps-vcpkg`, `deps-cmake`, `deps-archive` and `rules-qt`](#deps-vcpkg-deps-cmake-deps-archive-and-rules-qt) |
81+
| `rules-qt` | `mcpp.rules.qt` | 2026.9.26.2 (mcpp#702) | a Qt 6 SDK: `rules-qt-xim` declares `xim:qt` 6.11.1 on the target axis, `rules-qt-xim-base` declares `xim:qt-base` instead (qtbase and qttools with the QtQml library lupdate loads, about a third of the download; 0.14.0), `rules-qt-xim-addons` adds `xim:qt-addons` (the additional libraries) as a second prefix, and `options::root` names an SDK from elsewhere. From 0.13.0. `moc` for every header under the package root that declares `Q_OBJECT`, `Q_GADGET` or `Q_NAMESPACE` and for a source that includes its own `<stem>.moc`; `uic` for `.ui`, `rcc` for `.qrc`, `lrelease` for `.ts` (named in `[build] sources` or in the options), each a `role = "source"` action with declared inputs. The modules are linked by full path, and the SDK's `bin/` (Windows) or `lib/` is a runtime search directory: the program's run path, `mcpp run`'s load path, `mcpp pack`'s closure, and on Windows the Qt DLLs the program imports placed beside it by the engine. The plugin directories `deploy_plugins` names are deployed beside the program. See [`deps-vcpkg`, `deps-cmake`, `deps-archive` and `rules-qt`](#deps-vcpkg-deps-cmake-deps-archive-and-rules-qt) |
8282
| `rules-slang` | `mcpp.rules.slang` | 2026.9.7.1 | `[build] accel = "vulkan1.2"`, a constrained glob for `*.slang`. Slang is a different language from GLSL rather than a second driver for it -- its own module system, generics, and targets beyond SPIR-V -- so it is a rule of its own. `.slang` is **not** in the engine's device-source table: this feature declares `device_extensions = [".slang"]` and `rule_module = "mcpp.rules.slang"`, and the engine routes it from there. That is the criterion for the whole arrangement -- a new device language costs no engine release. Since 0.7.0 it has the same `options::storage` axis as `rules-spirv` (header / object / sidecar), `options::extra_args` for the arguments the rule has no field for, and `options::per_file` for what one shader gets that the others do not -- a project with a `-fvk-use-gl-layout` and one shader needing `-emit-spirv-via-glsl` writes both without leaving one `compile()` call |
8383
| `rules-spirv` | `mcpp.rules.spirv` | 2026.9.6.6 | `[build] accel = "vulkan1.2"`, a constrained glob for the shader stages; compiles each shader through a `role = "source"` action and states which of the two compilers produced it |
8484
| `rules-swift` | `mcpp.rules.swift` | 2026.9.8.1 | the Swift compiler of the macOS host's Xcode or Command Line Tools, located rather than installed, as `rules-metal` locates its toolchain. From 0.12.0. The `.swift` sources a project names on a macOS or iOS row compile as one module named after the package: one whole-module `xcrun --sdk <sdk> swiftc -wmo -emit-object -target <triple>` action whose role is `object`, so the object joins every image of the package, and one `swiftc -typecheck -emit-objc-header-path` action whose role is `source`, whose directory `mcpp::include_dir` adds, so the package's C and C++ sources include `<module>-Swift.h`. `options::bridging_header` names a C header Swift sees without an import. The link receives the toolchain's `usr/lib/swift/<platform>` and the SDK's `usr/lib/swift` as search directories and `/usr/lib/swift` as a run path through `mcpp::link_flag`. Before planning anything the rule asks `xcrun --sdk <sdk> --show-sdk-path` and `--find swiftc`, and refuses naming the command that answered nothing; a Swift source on any other row is refused naming the row. Not supported: a Swift `import` of another package's module, and another package's C++ including this package's generated header, which both need an engine channel that publishes a package's interface directory to its dependents; and SwiftPM dependencies. CI builds `tests/swift-consumer` on `macos-15` -- a C++ program calling a `@_cdecl` Swift function that calls back into C -- and runs it |
@@ -1006,6 +1006,7 @@ int main() {
10061006
|---|---|
10071007
| `rules-qt` | `options::root`; nothing is downloaded |
10081008
| `rules-qt-xim` | `xim:qt` 6.11.1: the official base package without documentation (qtbase, qtsvg, qtdeclarative, qttools, qttranslations) |
1009+
| `rules-qt-xim-base` | `xim:qt-base` 6.11.1 in place of `xim:qt`: qtbase and qttools with the QtQml library `lupdate` loads, about a third of the download (56–73 MB); every module a widgets or console program links, without Qt Quick, qtsvg or Qt's own translations |
10091010
| `rules-qt-xim-addons` | adds `xim:qt-addons` 6.11.1, every additional library, as a second prefix |
10101011

10111012
| option | meaning |
@@ -1031,7 +1032,7 @@ A missing SDK, module or tool is a warning: the rule states what it can, and
10311032
the build is where the absence fails.
10321033

10331034
On Linux, Qt's official QtCore links glib, zstd and zlib and the shared
1034-
`libstdc++`. `rules-qt-xim` declares the first three on Linux, and the rule
1035+
`libstdc++`. `rules-qt-xim` and `rules-qt-xim-base` declare the first three on Linux, and the rule
10351036
declares their `lib/` directories as runtime search directories; the program
10361037
states `[build] cxx_runtime = "toolchain-coupled"` (mcpp's docs/20), so the
10371038
process has one C++ runtime. The statement is project-wide because mcpp reads a

‎mcpp.toml‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ implies = ["rules-qt"]
157157
[features.rules-qt-xim-addons]
158158
implies = ["rules-qt-xim"]
159159

160+
# `xim:qt-base`: qtbase and qttools with the QtQml library qttools' Linguist
161+
# tools load, without Qt Quick -- about a third of `xim:qt`'s download. For a
162+
# widgets or console program. 0.14.0.
163+
[features.rules-qt-xim-base]
164+
implies = ["rules-qt"]
165+
160166
# NOT device rules: these embed or declare things a project already has, so they
161167
# claim no extension and name no rule module. A consumer calls them from its own
162168
# `build.mcpp`.
@@ -495,6 +501,14 @@ implies = ["surface"]
495501
[target.'cfg(any(windows, linux, macos))'.feature-xlings.rules-qt-xim-addons]
496502
"xim:qt-addons" = "6.11.1"
497503

504+
[target.'cfg(any(windows, linux, macos))'.feature-xlings.rules-qt-xim-base]
505+
"xim:qt-base" = "6.11.1"
506+
507+
[target.'cfg(linux)'.feature-xlings.rules-qt-xim-base]
508+
"xim:glib" = ""
509+
"xim:zstd" = ""
510+
"xim:zlib" = ""
511+
498512
# ── The environment `dist-appimage` needs ──────────────────────────────────
499513
#
500514
# ONE PAYLOAD, AND IT CARRIES TWO FILES. `appimagetool` builds the image, and

‎rules/qt.cppm‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,11 @@ inline std::vector<std::filesystem::path> roots(const options& opt = {}) {
252252
};
253253
if (!opt.root.empty()) add(opt.root);
254254
else {
255-
add(mcpp::xpkg_dir("xim", "qt"));
255+
// `xim:qt` is the full base; `xim:qt-base` is its qtbase + qttools
256+
// subset (`rules-qt-xim-base`). A project that declares both uses the
257+
// full one.
258+
const std::string full = mcpp::xpkg_dir("xim", "qt");
259+
add(full.empty() ? std::string(mcpp::xpkg_dir("xim", "qt-base")) : full);
256260
add(mcpp::xpkg_dir("xim", "qt-addons"));
257261
}
258262
for (auto const& r : opt.extra_roots) add(r);
@@ -270,7 +274,7 @@ inline std::string root(const options& opt = {}) {
270274

271275
// The SDK's shared-library directories, and on Linux those of the libraries
272276
// Qt's official QtCore expects the distribution to provide (glib, zstd, zlib,
273-
// declared from xim by `rules-qt-xim`), as runtime search directories
277+
// declared from xim by `rules-qt-xim` and `rules-qt-xim-base`), as runtime search directories
274278
// (SPEC-007 R4.1). The engine renders them as the program's run path, puts
275279
// them on `mcpp run`'s load path -- which reaches a library's dependencies
276280
// where the program's run path does not, because QtCore carries a RUNPATH of
@@ -308,8 +312,9 @@ inline bool compile(options opt = {}) {
308312
if (sdks.empty()) {
309313
detail::warn(std::format(
310314
"{}: no Qt SDK: options::root is {} and xpkg_dir(\"xim\", \"qt\") answered \"{}\". "
311-
"Nothing Qt-specific is planned. The `rules-qt-xim` feature declares `xim:qt`, "
312-
"which `mcpp build` provisions; a Qt from elsewhere is named with options::root.",
315+
"Nothing Qt-specific is planned. The `rules-qt-xim` feature declares `xim:qt` and "
316+
"`rules-qt-xim-base` declares `xim:qt-base`, which `mcpp build` provisions; a Qt "
317+
"from elsewhere is named with options::root.",
313318
who, opt.root.empty() ? "empty" : "'" + opt.root + "' (no such directory)",
314319
std::string(mcpp::xpkg_dir("xim", "qt"))));
315320
return true;

‎tests/qt-consumer/mcpp.toml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Fixture: a Qt 6 program that exercises each of Qt's code generators and its
2-
# Linguist tool through `rules-qt`, with the SDK from `xim:qt`.
2+
# Linguist tools through `rules-qt`, with the SDK from `xim:qt-base` (qtbase,
3+
# qttools and the QtQml library lupdate loads); tests/qt-widgets-consumer
4+
# uses `xim:qt`.
35
#
46
# A console program on purpose: QtCore needs no display and no platform plugin,
57
# so the same program is built and RUN on every host in the matrix. What it
@@ -31,7 +33,7 @@ modules = true
3133
import_std = false
3234

3335
[build-dependencies.mcpp]
34-
plugins = { path = "../..", features = ["rules-qt-xim"], host-module = true }
36+
plugins = { path = "../..", features = ["rules-qt-xim-base"], host-module = true }
3537

3638
[build]
3739
# Qt's Linux libraries load the shared libstdc++ (`libstdc++.so.6`), so the

0 commit comments

Comments
 (0)