mcpp.rules.qt runs Qt's code generators (moc, uic, rcc) and Linguist tools (lupdate, lrelease, lconvert) as build actions, links the Qt modules and places their runtime beside the program. The rule declares no SDK and pins no version: the project names the Qt it builds with, in build.mcpp or in its own [xlings] table. Module mcpp.rules.qt; engine floor 2026.9.27.1 (mcpp#704, mcpp#715) from 0.16.0, 2026.9.26.2 (mcpp#702) before; from 0.13.0.
[build-dependencies.mcpp]
plugins = { version = "0.17.0", features = ["rules-qt"], host-module = true }
# The SDK and its version are the project's declaration.
[target.'cfg(any(windows, linux, macos))'.xlings.workspace]
"xim:qt-base" = "6.11.1"
[build]
sources = ["src/*.cpp", "res/*.qrc", "i18n/*.ts", "ui/*.ui"]// build.mcpp
import mcpp.rules.qt;
int main() {
mcpp::rules::qt::options o;
o.modules = { "Core", "Gui", "Widgets", "Network" };
o.deploy_plugins = { "platforms", "styles", "imageformats" };
o.i18n.tr_function_alias = { "translate+=appTr" };
return mcpp::rules::qt::compile(o) ? 0 : 1;
}The first of three levels that names an SDK decides, and the rule records which as the fact rules-qt.sdk (0.15.0):
| level | how | scope |
|---|---|---|
| 1. build program | options::root, options::extra_roots |
any value build.mcpp computes |
| 2. environment | QT_ROOT_DIR, the variable install-qt-action and aqtinstall set; a change re-plans the build |
one machine |
| 3. declared payload | xim:qt, else xim:qt-base, with xim:qt-addons as a second prefix, at the version the project's [xlings] table states |
one project, provisioned by mcpp build |
| payload | contents |
|---|---|
xim:qt-base |
qtbase, qttools with the QtQml library lupdate loads, and qttranslations; about a third of xim:qt's download |
xim:qt |
qtbase, qtsvg, qtdeclarative, qttools, qttranslations |
xim:qt-addons |
the additional libraries, beside xim:qt |
Each payload carries its runtime closure: the loader and the libraries Qt loads on Linux, and the VC++ runtime on Windows x64. 0.15.0 removed the features rules-qt-xim, rules-qt-xim-base and rules-qt-xim-addons, which declared a payload at a fixed version. A feature states a mechanism; the SDK a program links is the project's choice. A project that used one of those features declares the payload instead, as above.
A project that does not use a payload comments out its declaration, because mcpp build provisions every declared payload whether or not a higher level names another SDK. It then names its SDK with QT_ROOT_DIR or with options::root in build.mcpp:
[target.'cfg(any(windows, linux, macos))'.xlings.workspace]
# "xim:qt-base" = "6.11.1"mcpp::rules::qt::options o;
o.root = "D:/Qt/6.11.1/msvc2022_64"; // or leave empty and set QT_ROOT_DIRA package that enables rules-qt only to import mcpp.rules.qt, and has no build.mcpp and no .ui, .qrc or .ts of its own, gets no synthesised build program, so nothing reports a missing SDK for it (mcpp 2026.9.27.1, mcpp#715; 0.15.2 silenced the report in the plugin, 0.16.0 leaves it to the engine).
| option | meaning |
|---|---|
modules |
Core, QtCore and Qt6Core name one module; each is linked by full path and defines QT_<MODULE>_LIB |
private_modules |
modules whose private headers are included |
moc, moc_headers |
moc_scan::project_headers (default) scans the package's headers by content; moc_scan::listed takes moc_headers only |
forms, resources |
.ui and .qrc files beside those in [build] sources |
i18n |
.ts files beside those in [build] sources; update_sources runs lupdate as an action whose output is the .ts it rewrites; tr_function_alias; deploy_to (default translations); out_dir (default <out dir>/qt/translations); qt_languages: the linked modules' catalogs combined by lconvert into qt_<language>.qm, the file windeployqt writes |
deploy_plugins |
plugin directories placed beside the program; default platforms |
deploy_software_gl |
Windows: opengl32sw.dll and d3dcompiler_47.dll beside the program |
root, extra_roots |
level 1 of the SDK lookup |
roots() and root() return the SDK the lookup chose, for a program that hands it on (a CMake subproject's CMAKE_PREFIX_PATH).
mocruns for every header under the package root that declaresQ_OBJECT,Q_GADGETorQ_NAMESPACE, and for a source that includes its own<stem>.moc;uicfor.ui,rccfor.qrc,lreleasefor.ts. Each is arole = "source"action with declared inputs; the outputs are under<out dir>/qt/.- The SDK's
bin/(Windows) orlib/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 placed beside the program. The plugin directoriesdeploy_pluginsnames are deployed beside the program. - Under an MSVC compiler the rule adds
/Zc:__cplusplusand/permissive-; on Linux,-fPIC. On macOS the modules are frameworks underlib/, compiled with-F<root>/liband linked by their binaries' full paths. A resource compiled into a static library is registered withQ_INIT_RESOURCE(<stem>). - A missing SDK, module or tool is a warning: the plan states what it can, and the build is where the absence fails.
A program packed by mcpp pack starts on a machine that has only its operating system:
| platform | Qt loads | provided by |
|---|---|---|
| Linux | glib, zstd, zlib, libdbus, fontconfig, freetype, X11, xkbcommon, EGL/GL, the xcb libraries | the xim:qt and xim:qt-base payloads: they declare these packages with xim:glibc, so xlings patches every file of the payload to the ecosystem's loader and a RUNPATH over them (openxlings/xim-pkgindex#884); Widgets programs pass mcpp's runtime closure check and run under that loader |
| Windows | system DLLs, and the VC++ runtime (MSVCP140, VCRUNTIME140, VCRUNTIME140_1) |
the payloads place the redistributable VC++ runtime in bin/ (windows-x86_64), so it reaches the program's directory with Qt's DLLs |
| macOS | system frameworks and libc++ | the system |
The rule names none of these libraries (0.15.0; 0.13.0 and 0.14.0 declared glib, zstd and zlib on Linux and served QtCore only). A Qt from elsewhere carries what its installer arranged. On Linux, QtNetwork additionally loads libgssapi_krb5 and libbrotlidec, which the ecosystem does not publish yet.
Qt's official Linux build uses the shared libstdc++, so a Linux program states cxx_runtime = "toolchain-coupled" (mcpp's docs/20) in its Linux host rows, [target.x86_64-linux-gnu] and [target.aarch64-linux-gnu], and builds with a gcc toolchain; under a libc++ toolchain the rule warns. A plain mcpp build applies the host's row since mcpp 2026.9.27.1 (mcpp#704); with an older engine the statement goes in [build], which applies it on every platform.