Kiln
Commands, exit codes and the .kiln keys
Kiln
Reference for the kiln command and the .kiln build description. For the
workflow — starting a broker, pointing qbs at kiln, reading the queue — see
Build through the kiln queue.
Commands
| Command | What it does |
|---|---|
kiln compile -- <compiler> <args> |
Runs one compile as an admitted job. It looks exactly like the compiler: same output, same exit code |
kiln link -- <linker> <args> |
Runs one link as an admitted job. A GCC link with link-time optimization holds four slots and runs four optimization jobs |
kiln run -- <command> <args> |
Runs any heavy command, such as qbs build, as an admitted job |
kiln status |
What runs, what waits, and why the ceiling is where it is |
kiln serve |
The broker. --slots, --reserve-mb, --memory-budget-mb, --hard-floor-mb, --idle-ms, --recycle-mb and --cache-max-gb shape it; --cache-dir gives it a cache of its own, and --broker <name> serves on a name of its own beside the user's |
kiln explain [path] [key] |
The settings of the product at path, each with the file and line that set it, its sources, the folders it skips and the generators it needs. --variant picks the variant |
kiln deps [path] |
Each product's libraries, read from its includes, as the deps line its .kiln would carry |
kiln import-qbs [path] |
Each product's .qbs translated into its .kiln, with every construct it cannot translate named by file and line. It writes nothing |
kiln graph [path] |
Brings the checkout's kept graph up to date and prints what changed: files added, removed, changed and moved. --watch keeps running and updates the graph as the checkout changes, as the broker does |
kiln sources [path] |
Every product's sources, one line each: the product folder, the kind and the path. The lint check-kiln-sources.py holds them to what qbs compiles |
kiln synth <dest> [--times n] [path] |
Writes a synthetic tree, n times the checkout (default 10), with the same products, files, sizes, includes and moc markers, for measuring the graph at scale |
kiln keys |
The key table below, printed from the schema |
kiln commands [path] |
Every compile a build would run, as a compile database for an editor. --variant picks the variant |
kiln build [path...] |
Builds the product at each path, in one plan, or every product, through the queue. --install lays out the install tree after it, --installed builds only what the install tree holds, --dry-run says what would run, --os windows builds for Windows on another system with windows.sysroot (kiln-file §KN-K26), --os android for Android with android.ndk, and --arch arm64 for Linux on arm64 with linux.sysroot |
kiln test [path...] [-- args] |
Builds the suites at or under each path and runs each to its contract: its timeout, its expected counts, headless unless it needs a display. --prebuilt runs the suites that a qbs build made and builds nothing. With --os android, the suites run on an Android device inside the tests-runner package, eight to a package unless --batch says otherwise. The options are in kiln test |
kiln fetch <url> <what> <folder> |
Writes one commit of a remote, a branch, a tag or a commit, into a working tree, without the git command, and provisions its pinned trees |
kiln vendor [path] |
Writes the pinned trees the checkout builds from, such as LLVM's source, from the shared cache or by download checked against the pin |
kiln bootstrap <url> <what> <folder> --qmake <qmake> |
Fetches the commit, provisions its pinned trees, names the Qt in the folder's .kiln.local, then builds and installs what the install tree holds, in release |
kiln package deb|archive [path] |
Builds and installs what the install tree holds, then makes the Debian package and its -dbgsym, or the portable archive, in <build root>/package. --ship narrows the applications. Making a package needs Debian's packaging tools and the binutils |
kiln package zip|msix|setup [path] |
Builds and installs what the install tree holds for Windows, on this host, then makes the build farm's portable zip with its symbols zip beside it, the msix, or the Inno Setup installer, in <build root>/package. The DLLs and Qt plugins are read from the programs with libdeploy; the msix and the installer are packed by the Windows tools in the VM. Needs windows.sysroot with the runtime winvm runtime copies |
kiln package apk [path] |
Builds the application at the path for Android (--arch picks the ABI) and makes its package in <build root>/package, signed with the SDK's debug key unless android.keystore names another. The tests-runner carries the suites --suites names. Needs the Android SDK, the NDK and a JDK |
kiln package aab [path] |
The same application as the Android App Bundle Google Play takes, written by Google's bundletool (android.bundletool, or the newest bundletool-all-<version>.jar in the SDK) and signed with jarsigner. Needs the JDK's jarsigner beside what apk needs |
kiln apidocs |
Builds the apidocs tool for this host, then makes the API reference as the api-reference qbs product does: QDoc's pages into apidocs.html, the class pages counted against apidocs.minimum_pages, and their markdown into apidocs.classes. Prints the page count. Needs Qt's qdoc and its documentation |
explain, deps, import-qbs and synth answer from the kept graph: the
first call on a checkout scans it, about two seconds for this tree, and every
later call costs only what changed since, about 60 ms when nothing did. The
graph lives in one file per checkout under the user's cache folder
(~/.cache/kiln/graphs/ on Linux); --graph <file> names another place,
--memory keeps it in memory for the one run, and --no-graph reads the disk
instead, as the commands did before the graph existed. While a broker runs, it
keeps the graph of every checkout its jobs name current through a folder
watcher, and kiln status lists each graph it keeps.
Exit codes
| Code | Meaning |
|---|---|
| The tool's own | compile, link and run return the wrapped command's exit code unchanged |
| 0 | Done |
| 1 | The work was attempted and did not succeed |
| 2 | The command line was wrong; nothing was attempted |
| 3 | An input existed but was malformed, such as a .kiln file with an error |
| 4 | Something needed was absent, such as a checkout with no .kiln |
| 5 | An external resource failed |
The .kiln file
A folder can hold one .kiln file. For a product, kiln reads the built-in
defaults, the root .kiln, each .kiln between the root and the product, the
product's own, and last .kiln.local at the root, which is not committed. Each
overrides what came before.
# a comment
key = value # replace
key += value # append to a list
key -= value # remove from a list
[condition ...] # a section header, which may carry one assignment
Every line after a section header belongs to that section, until the next header. A line meant for every case goes above the sections.
| Condition | Matches |
|---|---|
variant= |
The variant being built |
os= |
linux, windows or android |
arch= |
x64 or arm64 |
feature= |
A feature that is present |
path= |
A product whose folder, relative to the checkout, matches the glob |
file= |
A source file of the product matching the glob |
option.<name>= |
The value the root gives a build option, such as option.enableLto=on (kiln-file §KN-K24c) |
profile= |
The run, when kiln test --profile <name> names this profile, or a build request's testProfile does. Only the root .kiln or .kiln.local declares one, and it sets only the run's keys: test.skip, test.select, test.cap, test.report, test.display, test.jobs, test.isolation. See Profiles |
In a glob, * and ? stay inside one folder, ** crosses folders, and **/
also matches no folder at all.
Keys
Generated from the schema by kiln keys. A key not listed here is an error, and
so is a value outside a key's accepted set.
| Key | Type | Accepted | Default | Where | Meaning |
|---|---|---|---|---|---|
type |
one of | lib app tool test test-shared none |
any | What this folder is. none holds data and is never compiled. test-shared is the shared test binary, which compiles every suite that says test.shared = on (test-system-revamp §TSR-B-7). |
|
deps |
list | any | The libraries this product depends on, written by a person and verified against the includes. | ||
template |
any of | kind roots identity features qt libraries branding |
kind roots identity features qt libraries branding |
any | Which of the tree's conventions the product takes: kind its kind's defines, roots every library's root as an include folder, identity the stable identity defines, features the feature defines, qt the tree's Qt modules, libraries the exports of every library the tree uses everywhere, branding the edition's generated header and, for a test, its resource file. Empty for a raw qbs item, which takes only what it names (§KN-K20). |
identity.defines |
list | any | The stable identity defines the description states, such as the variant's name, which a product takes when template holds identity; kiln adds the toolchain's (§KN-K18b). |
||
features.defines |
list | any | The defines of the features present, which a product takes when template holds features (§KN-K18c). |
||
qt.modules.tree |
list | any | The Qt modules the tree's templates give, which a product takes when template holds qt (§KN-K5). |
||
qt.modules |
list | any | The Qt modules the product compiles and links with beyond the tree's, as the installation's descriptions name them (widgets, core_private); each brings the modules it needs (§KN-K5). |
||
uses |
list | any | Libraries whose exports this product compiles with, beyond what its includes name: a vendored library's headers are not under its root (§KN-K19b). | ||
export.defines |
list | any | Definitions every product that uses this library compiles with (§KN-K19a). | ||
export.includes |
list | any | System include folders, relative to the checkout, every product that uses this library compiles with (§KN-K19a). | ||
export.to.all |
switch | on off |
on |
any | Whether every application and test takes this library's exports, as qbs's octomylib product type gave them. On for a library of the tree; a raw one says so itself (§KN-K19c). |
export.uses |
list | any | Libraries whose exports every product that uses this library takes too: a public header of this library includes theirs, as libspir's includes libspirvtools's SPIR-V headers (§KN-K19b). | ||
export.qt.modules |
list | any | Qt modules every product that uses this library compiles and links with (§KN-K19a). | ||
export.std |
one of | c++17 c++20 c++23 |
any | The least C++ version every product that uses this library compiles with: a product takes the highest its own compiler.std and its libraries ask for, as qbs does (§KN-K19a). |
|
export.link.libraries |
list | any | System libraries every program that uses this library links with (§KN-K19a). | ||
variant.defines |
list | any | Definitions every product of the variant compiles with, whatever its template: NDEBUG in release, as qbs gives a raw item too (§KN-BG11c). |
||
options.defines |
list | any | Definitions the tree's build options give (BuildOptions.qbs, which passes them as flags): every product takes them, a raw one that loads those options too, unless it compiles with qbs's own defaults, which the importer resets them for (§KN-BG11c). |
||
enabled |
switch | on off |
on |
any | Whether the product is built at all. Off for one whose .qbs condition is never true, which the importer writes, as qbs leaves the product out; kiln explain says why (§KN-F25). |
requires |
list | any | The features this product needs; without one of them it is skipped with one line. | ||
systems |
any of | linux windows android |
any | The systems this product is built for. Unset means every system; a product for some of them lists them. | |
install |
switch | on off |
off |
any | Whether the product is installed with the application. |
install.dir |
value | bin |
any | The folder under install.prefix the product's file is installed in, as qbs's installDir: a loader plugin's folder beside the programs, such as bin/vulkan/explicit_layer.d (§KN-K21a). |
|
install.files |
list | any | Files the build writes for the product, relative to its folder in the build tree, installed beside its own file: a loader plugin's manifest from configure.files (§KN-K21a). |
||
library.shared |
switch | on off |
off |
any | Whether the library is linked as a shared object a loader opens, as qbs's DynamicLibrary: lib<output.name>.so, <output.name>.dll on Windows. It links the libraries it uses as a program does, and no product links it (§KN-K21a). |
output.name |
value | any | The base name of the product's file, instead of the product's name, as qbs's targetName. | ||
layering.tier |
one of | foundation widgets |
any | The library's layering tier: what it may depend on is checked against it. | |
layering.core |
switch | on off |
off |
any | Whether the library's public headers include Qt Core and nothing else from Qt, so a host tool may use it. |
qbs.covers |
list | any | The fingerprints of the constructs of the product's .qbs that this file translates by hand, as kiln import-qbs names them. A construct with no cover, or a cover whose construct is gone, fails the build. |
||
sources.exclude |
list | any | Folder names the source glob skips. kiln explain lists every folder skipped. |
||
sources.files |
list | any | Globs, relative to the product folder, naming exactly the files it compiles, in order: a glob adds, !glob takes away, and the last that matches decides. Unset, it compiles every source the walk finds (§KN-K13a). |
||
sources.required |
list | any | Files, relative to the product folder, that must be in the checkout before anything is planned: committed outputs of a generator the build does not run, such as libllvm's tablegen tables. A missing one is an error naming it, since the checkout is incomplete (§KN-K13d). | ||
includes |
list | any | Include folders beyond the library roots, relative to the checkout: vendored headers, committed generated headers. | ||
includes.system |
list | any | Include folders, relative to the checkout, the product compiles with as system folders, so the warnings of the vendored headers in them are not its own. A folder also among its includes is a system folder. |
||
defines |
list | any | Preprocessor definitions, NAME or NAME=value. |
||
defines.paths |
list | any | Definitions that name a place, NAME=relative/path: the absolute path in the checkout, quoted, at build time. NAME=. is the checkout, NAME=@build the build directory (§KN-K18a). |
||
edition.defines |
list | any | Definitions that name a field of the edition, NAME=field, quoted at build time: package_prefix, the edition's reverse-DNS application id prefix (§KN-K12b). |
||
pantry.bundles |
list | any | The product's asset bundles, one quoted entry each of field=value words: name and source (a folder relative to the product), mount (by default /<name>), and any number of filter globs, member paths, and a list JSON file with its keys. Kiln writes each and compiles it with rcc under its name (§KN-K12c). |
||
branding.resource |
switch | on off |
off |
any | Whether the product compiles the edition's resource file, branding.qrc, under the name branding, which Q_INIT_RESOURCE(branding) names; libres does (kiln-file §KN-K12b). |
shaders.bake |
switch | on off |
on |
any | Whether the product's shader sources are baked with qsb into its resources. On for a product of the tree, whose library declares its shaders to qbs; off for a raw item, whose shader sources are a vendored tree's own, such as llama's Vulkan kernels (kiln-file §KN-K12d). |
help.content |
value | any | The published help the product carries: the folder of its markdown, relative to the checkout. Kiln renders it as helpbuild does, bundles it as help_resources under /help, and makes its images the product's own resources (§KN-K12e). | ||
configure.files |
list | any | Files written from a template into the product's folder in the build tree, one quoted entry each of in=<template>, relative to the product, out=<name>, and @NAME@=value words, each @NAME@ of the template replaced by its value; a template naming a @NAME@ the entry does not give is an error (§KN-K12h). |
||
pantry.live |
switch | on off |
off |
any | Whether a bundle's manifest records its source root, so the live layer can read the checkout; a debug build's, never a release's (asset-pantry §PN-3). |
opal.registry |
switch | on off |
off |
any | Whether a program defines the OPAL task-family dispatch from the libraries it links (§KN-K12f). Every program whose template holds libraries does; another says so, as qbs's opalregistry module, which a Tool loads by name. |
git.defines |
any of | volatile branch |
any | The identity defines beyond the stable ones every product has: volatile (the commit and whether the tree is dirty) and branch (§KN-K18b). |
|
features |
list | root | The feature names this project knows. Each is present when what its own section says it needs is: feature.qt, feature.tree and feature.systems; one that says none is always present (§KN-K7a). |
||
feature.qt |
list | root | In a feature's own section, the Qt modules it needs: it is present when the installation has every one. | ||
feature.tree |
list | root | In a feature's own section, the files of its vendored tree, relative to the checkout: it is present when every one exists. | ||
feature.systems |
any of | linux windows android |
root | In a feature's own section, the systems it exists on: on another it is absent, and permanently so. | |
features.required |
list | root | Features that must be present: one of them missing is an error, whatever features.strict says, as qbs's requireLlvm, requireLlama and requireRl make it. |
||
features.strict |
switch | on off |
off |
root | When on, a product whose feature is missing is an error instead of a skip. |
variants |
list | root | The variant names this project knows. A variant nobody declares is an error. | ||
variant.default |
value | root | The variant built when none is named. It must be one of variants. |
||
compiler.std |
one of | c++17 c++20 c++23 |
c++20 |
any | The C++ language version. |
compiler.c_std |
one of | default c99 c11 c17 gnu11 gnu17 |
default |
any | The C language version of the product's C sources; default is the compiler's own, as qbs leaves it when a product names none. |
compiler.optimization |
one of | O0 O1 O2 O3 Os Oz |
O0 |
any | The optimisation level. |
compiler.debuginfo |
one of | none line full |
full |
any | How much debug information to emit. |
compiler.split_dwarf |
switch | on off |
off |
any | Whether a C++ compile with full debug information writes it to a .dwo beside the object instead of into it, so a link does not copy it. C sources keep theirs in the object, as the tree's BuildOptions.qbs gives the flag with the C++ flags alone. |
compiler.lto |
one of | off thin full |
off |
any | Link-time optimisation. |
compiler.exceptions |
switch | on off |
off |
any | Whether C++ exceptions are enabled. |
compiler.rtti |
switch | on off |
off |
any | Whether run-time type information is enabled. |
compiler.warnings |
flags | any | Warning flags. Each must be known to the flag table. | ||
compiler.flags |
flags | any | Other compiler flags. Each must be known to the flag table. | ||
linker |
one of | bfd gold mold lld |
bfd |
any | The linker the compiler driver uses. |
linker.split_debug |
switch | on off |
off |
any | Whether a program's debug information is moved into <program>.debug beside it, the program keeping a link to it, as qbs's separateDebugInformation does; the install tree carries the file with the program when the program has debug information of its own. |
linker.flags |
list | any | Options passed to the linker itself, such as --gc-sections. |
||
linker.version_script |
value | any | The version script, relative to the product, that names the symbols a shared library exports; an edit to it links the library again (§KN-K21a). | ||
link.libraries |
list | any | System libraries outside Qt that a product links, such as dl or ws2_32, usually in an os= section. |
||
link.static_runtime |
switch | on off |
off |
any | Whether a program carries its own C++ runtime and libgcc, linked from their archives (-static-libstdc++ -static-libgcc), for a machine whose runtime may be older than the build's; Linux and Android (compiler-cli §KN-C9c). |
test.category |
one of | unit integration widget stress developer hardware interactive legacy perf live_audio live_net opal |
unit |
any | The test's category. legacy, interactive, hardware, perf, live_audio and live_net are left out by default. |
toolchain.headers.capture |
value | any | The host compiler, such as c++, whose headers a build that includes the product captures into the build tree for the in-process compiler, when the compiler or its include folders changed (§KN-K12g). |
||
test.install |
switch | on off |
off |
any | Whether the suite reads the install tree: kiln test builds every installed program in its batch and lays the tree out before it runs, as a whole qbs build leaves one (§KN-K15a). |
toolchain.clang.headers |
list | any | The vendored clang's builtin headers, folders relative to the product, which a build that includes the product copies into the build tree for the in-process compiler when they changed (§KN-K12g): clang's lib/Headers first, then the headers clang's own build generates (§KN-K27c). | ||
test.programs |
list | any | The tree's programs a suite runs, by product name: kiln test builds them with it, since the suite finds them beside itself rather than linking them (§KN-K15a). |
||
test.timeout |
number | 60 |
any | Seconds before the suite is ended as hung; 0 for never, as an interactive suite needs. kiln test also gives this value, plus 10 seconds, to QTest's per-function watchdog, QTEST_FUNCTION_TIMEOUT. |
|
test.headless |
switch | on off |
on |
any | Whether the suite runs without a display. |
test.real_platform |
switch | on off |
off |
any | Whether the suite needs a real window system rather than the offscreen one. |
test.intentionally_offscreen |
value | any | Why the suite runs on the OpenGL fallback on purpose, when a real platform is there. Without it, kiln test fails a suite that took the fallback beside a reachable display (test-system-revamp §TSR-R-6). |
||
test.shared |
switch | on off |
off |
any | Whether the suite is a member of the shared test binary, which links every member once and runs them as worker processes (test-system-revamp §TSR-B-6). A member must be headless and need no real platform. |
test.platform_sensitive |
switch | on off |
off |
any | Whether the suite's result can differ by platform: the code under test branches on the platform, or the suite uses paths, processes, IPC, an RHI backend, fonts or packaging. test.select = platform keeps only these suites, as the Windows leg does (test-system-revamp §TSR-S-3, §TSR-R-7). |
test.exclusive |
switch | on off |
off |
any | Whether the suite runs alone, after the parallel part of a kiln test --jobs run, for a reason other than a display: a fixed port, a heavy benchmark (test-system-revamp §TSR-R-5). |
test.guard |
switch | on off |
off |
any | Whether integration/lint/run-all.sh --with-tests runs this suite as a guard. |
test.expected_passed |
number | any | The number of passing cases a guard suite must report; any other number is a failure. | ||
test.expected_minimum_passed |
number | any | The fewest passing cases a guard suite may report; a suite that grows needs no edit. | ||
install.prefix |
value | usr/local |
root | The prefix the install tree lays the products out under, inside <build root>/install-root, as qbs.installPrefix: programs and the build's identity files in its bin. |
|
install.layer_bundle |
value | root | A foreign Vulkan validation layer for a build without its own: a folder laid out by integration/vulkan-validation/bundle-layer.py, relative to the checkout or absolute, whose files --install copies into bin/vulkan/explicit_layer.d. Ignored while the vulkanvalidation feature builds the tree's own layer (kiln-file §KN-K21b). |
||
output.dir |
value | root | Where the build tree is written. | ||
externals |
list | root | The external roots: installations outside the tree, Qt and the system, one quoted entry each of name=<name> dir=<folder>, with include=<folder> (any number) and lib=<folder> relative to it where they are not include and lib; the root gives qbs's default and .kiln.local a machine's (kiln-file §KN-K25a). |
||
external.uses |
list | any | The external roots this product compiles and links with: each one's include a system folder, and its lib searched by every program that links the product (kiln-file §KN-K25b). |
||
windows.vc_dir |
value | root | The MSVC tools folder a Windows build uses, ...\VC\Tools\MSVC\<version>, taken as it is; unset finds the newest through the Visual Studio setup interface, then the registry, never the environment (bootstrap §KN-B4c). A machine's setting, for .kiln.local. |
||
windows.icons |
value | root | The folder of the applications' window icons, relative to the checkout, <application>.svg each, as App.qbs's windowIconDir: a Windows application with one carries it as its icon resource, and a folder that is not there is an error (kiln-file §KN-K12i). |
||
windows.dxc |
value | root | The folder of the DirectX Shader Compiler runtime, dxcompiler.dll and dxil.dll, which every Windows program carries beside itself; unset, dxc/x64 in windows.sysroot, which winvm runtime fills, or the newest Windows SDK's on a Windows host (kiln-file §KN-K25d). A machine's setting. |
||
windows.require_dxc |
switch | on off |
on |
root | Whether a Windows build without the DirectX Shader Compiler runtime is an error; off builds without it, and its programs cannot render an SDF scene on Direct3D 12, as qbs's requireDxcRuntime (kiln-file §KN-K25d). |
windows.msix_publisher |
value | root | The publisher an MSIX package names, the subject of the certificate it is signed with, CN=...; unset, CN=OctoMY Local Dev, as the build farm's default (kiln-file §KN-K30d). A machine's setting. |
||
windows.signing_pfx |
value | root | The certificate the MSIX package and the installer are signed with, a .pfx; unset, they are not signed (kiln-file §KN-K30d). A machine's setting, for .kiln.local. |
||
windows.signing_password |
value | root | The password of windows.signing_pfx. A machine's setting, for .kiln.local. |
||
windows.sysroot |
value | root | The toolchain of a Windows build on another system: a folder in clang's /winsysroot layout, VC/Tools/MSVC/<version> and Windows Kits/10, which winvm sysroot copies out of a Windows machine. Every compile and link of such a build names it (kiln-file §KN-K26b). A machine's setting, for .kiln.local. |
||
linux.sysroot |
value | root | The system of a Linux build for another architecture: a Debian root of that architecture holding its C library, GCC's runtime objects and the -dev packages the tree links, as mmdebstrap --variant=extract makes one. Every compile and link of such a build names it as --sysroot= (kiln-file §KN-K27b). A machine's setting, for an [arch=...] section of .kiln.local. |
||
android.ndk |
value | root | The Android NDK an Android build compiles against: its folder, holding toolchains/llvm/prebuilt/<host>/sysroot with Bionic, libc++ and the startup objects, and the runtime libraries of its clang (kiln-file §KN-K28b). A machine's setting, for an [os=android] section of .kiln.local. |
||
android.api |
number | 28 |
root | The lowest Android API level an Android build runs on, the number its target names (aarch64-linux-android28): the one Qt's Android kit was built for, android-28 for Qt 6.11's (kiln-file §KN-K28a). |
|
android.sdk |
value | root | The Android SDK an Android package is made with: its folder, holding build-tools/<version> with aapt2, d8, zipalign and apksigner, and platforms/android-<android.target_api>/android.jar (kiln-file §KN-K29a). A machine's setting, for an [os=android] section of .kiln.local. |
||
android.build_tools |
value | root | The version of the SDK's build tools an Android package is made with; unset, the newest the SDK holds, as qbs picks them (kiln-file §KN-K29a). A machine's setting. | ||
apidocs.html |
value | root | Where kiln apidocs writes QDoc's pages, relative to the checkout: emptied first, so a renamed class leaves no page behind (kiln-file §KN-K22a). |
||
apidocs.classes |
value | root | Where kiln apidocs writes the markdown projection of the reference the in-app help reads, relative to the checkout (kiln-file §KN-K22a). |
||
apidocs.minimum_pages |
number | root | The class pages below which kiln apidocs fails: QDoc exits 0 on a smaller tree. Raised when a run earns it, never lowered to pass (kiln-file §KN-K22a). |
||
apidocs.defines |
list | root | What QDoc's parse defines, each passed as -D: every feature's define, so the classes behind a feature have pages (kiln-file §KN-K22a). |
||
android.bundletool |
value | root | The bundletool jar kiln package aab writes an App Bundle with; unset, the newest bundletool-all-<version>.jar in android.sdk, where qbs's Android module looks for it (kiln-file §KN-K29g). A machine's setting. |
||
android.target_api |
number | 35 |
root | The Android API level a package targets and compiles its Java against, as AndroidOptions.qbs's Android.sdk.platform and targetVersion say (kiln-file §KN-K29a). | |
android.java |
list | root | Folders of Java sources every Android package compiles, relative to the checkout: libserial's bridge, which App.qbs gives every application (kiln-file §KN-K29b). | ||
android.device |
value | root | The serial of the device kiln test --os android runs the suites on, as adb devices lists it; unset, the one device adb sees (kiln-file §KN-K29e). A machine's setting, for .kiln.local. |
||
android.keystore |
value | root | The keystore an Android package is signed with; unset, the SDK's debug key, ~/.android/debug.keystore, as qbs's codesign module signs (kiln-file §KN-K29b). A machine's setting, for .kiln.local. |
||
android.keystore_password |
value | root | The password of android.keystore; the debug key's, android, when that is unset. A machine's setting. |
||
android.key_alias |
value | root | The key in android.keystore the package is signed with; the debug key's, androiddebugkey, when that is unset. A machine's setting. |
||
android.key_password |
value | root | The password of android.key_alias; the debug key's, android, when android.keystore is unset. A machine's setting. |
||
run.checkout |
value | root | The checkout's folder on the system a build's programs run on, when that is another one: the places a program is built with (defines.paths, a suite's project root) name it instead of this checkout (kiln-file §KN-K26e). A machine's setting, for .kiln.local. |
||
run.output |
value | root | output.dir as the system a build's programs run on names it, for the places under the build folder (kiln-file §KN-K26e). A machine's setting, for .kiln.local. |
||
options.schema |
value | root | The file that declares the build options, relative to the checkout: integration/build-parameters.json, which qbs reads too. Each option it declares is set by option.<name> and tested by a section's option.<name>= condition (kiln-file §KN-K24). |
||
edition.dir |
value | root | The edition the build brands its products with, the folder of its edition.json, relative to the checkout; unset for the loud no-edition build (edition-data §ED-A1, kiln-file §KN-K12b). |
||
test.skip |
list | root | The test categories a build of every product leaves out, as qbs's TestConfig module leaves them out: tests that are broken, interactive, need hardware, benchmark or play sound. A test named on the command line is built whatever its category (kiln-file §KN-K15). | ||
test.select |
list | all |
root | Which suites a run of kiln test keeps: all, guard for the guard suites, categories, or suites by name; each kind of value narrows the run, and a suite named here runs whatever its category. Usually set in a [profile=<name>] section; --category and --guard-only win over it (test-system-revamp §TSR-R-3). |
|
test.isolation |
switch | on off |
off |
root | Whether a run of kiln test runs each member of the shared binary twice, in its shard and then alone in a process of its own, and fails a member whose two verdicts differ: state that one class leaves for another (test-system-revamp §TSR-B-5). The nightly profile sets it. |
test.jobs |
value | 1 |
root | How many suites a run of kiln test runs at the same time: a count, or auto for half the cores. Each suite is still its own process, and a suite that needs a display or declares test.exclusive runs alone afterwards. --jobs wins over it (test-system-revamp §TSR-R-5). |
|
test.cap |
number | 900 |
root | Seconds a suite that declares no timeout of its own may run before it is ended; 0 waits. --max-timeout wins over it (test-system-revamp §TSR-R-3). |
|
test.report |
any of | json junit |
root | The result files a run of kiln test writes into its report folder: json for tests.json, junit for tests.junit.xml. --report names the folder (test-system-revamp §TSR-R-4). |
|
test.display |
one of | auto on off |
auto |
root | Which suites run on the display: auto the suites with test.real_platform, on every suite, off none. --display wins over it (test-system-revamp §TSR-R-3). |
package.version |
value | 0.0.0-dev |
root | The release version the build stamps into the products that print their identity, as OC_PACKAGE_VERSION; a release build sets it, a developer's is the default (kiln-file §KN-K18b). |
|
package.name |
value | octomy |
root | The Debian package's name (§KN-K23a). | |
package.base |
value | octomy |
root | The package base every path a package owns carries: /usr/lib/<base>, /usr/bin/<base>-<app>, the file names of the packages, so editions install side by side (§KN-K23a). |
|
package.maintainer |
value | root | The package's maintainer, a name and an address in angle brackets. | ||
package.homepage |
value | root | The project's home page, in the control file and the metainfo. | ||
package.source_url |
value | root | Where the source is, in the copyright file's Source:. |
||
package.copyright |
value | root | The copyright file's Copyright: line: years and holder. |
||
package.tagline |
value | root | The words after the brand in the control file's summary line, <brand> - <tagline>; {brand} is the edition's brand. |
||
package.description |
list | root | The control file's long description, one quoted line each; an empty entry is a paragraph break; {brand} is the edition's brand. |
||
package.legacy |
list | root | Edition packages from before the side-by-side layout, which the package Breaks when older than package.side_by_side_since. |
||
package.side_by_side_since |
value | root | The first version of the side-by-side layout; an older legacy package is broken by this one. | ||
package.alternatives_priority |
number | 50 |
root | The auto-mode priority of this edition's bare command names in update-alternatives. | |
package.section |
value | misc |
root | The Debian section. | |
package.priority |
value | optional |
root | The Debian priority. | |
package.license |
value | root | The project's license as an SPDX identifier, for AppStream; the copyright file gets its DEP-5 name. | ||
package.metadata_license |
value | CC0-1.0 |
root | The license of the AppStream metainfo files themselves. | |
package.ship |
list | root | The applications a package ships; kiln package --ship narrows it for one run. |
||
package.plugin_categories |
list | root | The Qt plugin categories the Debian package carries; empty lets bundle_qt.sh derive them from the Qt modules the binaries link. A category left out is a plugin the application cannot load. | ||
package.fallback_depends |
list | root | The Depends used only where dpkg-shlibdeps names nothing; a Debian Qt package is never taken from it. | ||
package.title |
value | any | An application's menu name after the brand, <brand> <title>; an application without one gets no launcher and no metainfo. |
||
package.comment |
value | any | An application's menu tooltip and AppStream summary. | ||
package.categories |
value | any | An application's freedesktop menu categories, each followed by ;. |
||
package.about |
list | any | An application's AppStream description, one quoted paragraph each; the first is a software centre's introduction. | ||
qt.qmake |
value | root | The qmake of the Qt installation this machine builds with; qmake -query gives the rest (§KN-BG11a). |
||
vendor.trees |
list | root | The pinned trees the checkout builds from, one quoted entry each of name=<pin section> pin=<pin file> tree=<folder>, relative to the checkout, which kiln vendor and kiln fetch materialise (§KN-K13c). |
||
cache.dir |
value | root | Where the vendored-source cache lives. | ||
build.jobs |
number | root | The most jobs a build hands the queue at once, as qbs's -j; unset, 64. The broker's --slots says how many run (kiln-file §KN-K22). |
kiln test
kiln test [path...] [-- args] runs test suites, each in its own process,
under its contract. A path selects the suites at or under it, and a suite that
a path names runs whatever its category. What follows -- goes to every suite.
The guide is Run tests.
Options
| Option | What it does |
|---|---|
--prebuilt <dir> |
Runs the programs that this build folder holds, which qbs or kiln built, and builds nothing. A suite of a built category with no program there is NOT BUILT, and that fails the run. Two programs for one suite run neither, and the suite fails. A member of the shared binary runs in testsLogical, never in its own program |
--profile <name> |
Runs one kind of run: the root's [profile=<name>] section sets the run's keys. An option given here wins over the profile. A name that is no profile fails the run with exit code 3. none runs no suite |
--options <file> |
Reads a build request, build-request.json. Its testProfile picks the profile, and --profile wins over it. See The build request |
--list-profiles |
Prints the profile names of the root .kiln and .kiln.local, one per line, and runs nothing |
--report <dir> |
Writes tests.json and tests.junit.xml into this folder, or the files that test.report names, with every suite's log in <dir>/logs |
--log-dir <dir> |
Writes what each suite printed to <dir>/<suite>.log |
--jobs <n> |
Runs this many suites at the same time, or auto for half the cores. A suite that needs a display or is exclusive runs alone, after them. Wins over test.jobs |
--shuffle <seed> |
Runs the suites in a random order from this seed, a number from 0 to 4294967295. The same seed gives the same order on every host, and tests.json keeps it |
--audit |
Reads the suites against the test standard and runs none of them. It prints one line per finding, AUDIT <suite> <check> <rule>: <detail>, and a count. With --report, it writes audit.json. An audit fails nothing |
--category <names> |
Runs only the suites of these categories, comma-separated. Replaces the profile's selection |
--guard-only |
Runs only the guard suites (test.guard). Replaces the profile's selection |
--display |
Runs every suite on the display rather than headless. Wins over test.display |
--max-timeout <seconds> |
The seconds a suite with no timeout of its own may run. Default 900; 0 waits. Wins over test.cap |
--headless-only |
Leaves out every suite that needs a display, as qbs's headlessTestsOnly does |
--batch <n> |
Builds and runs this many suites at a time, so that the programs of a sweep never all exist at once. With --os android, the number of suites in one tests-runner package, eight by default. Not with --prebuilt |
--os android |
Runs the suites on an Android device (android.device) inside the tests-runner package, instead of on this host |
--discard |
Deletes each suite's program once it has run. Not with --prebuilt |
--arch <architecture> |
The architecture to build for, instead of the host's |
Each suite gets one line on stdout when it ends: PASS, FAIL, TIMEOUT,
NOT BUILT or SKIPPED, the suite, the reason and the seconds. The last line
counts the suites that kept their contract, failed, timed out, were not built,
were skipped by category and were left out by the selection. The exit code is 0
when every selected suite kept its contract and 1 otherwise; 2 for a wrong
command line, and 3 for an input that kiln cannot use, such as an unknown
profile or an unreadable build request.
The environment of a suite
Each suite runs from the checkout root, in the environment of kiln test,
with these changes. A QTEST_ or QT_AUDIO_BACKEND variable that is already
set in that environment stays as it is.
| Variable | Value |
|---|---|
QTEST_DISABLE_STACK_DUMP |
1. QTest's crash handler starts a debugger, which deadlocks in a suite with threads, and a crash then looks like a TIMEOUT |
QTEST_FUNCTION_TIMEOUT |
The suite's budget plus 10 seconds, in milliseconds. The budget is test.timeout, or the cap when the timeout is 0. When there is no cap either, the value is 2147483647. Without it, QTest stops each test function after 300 seconds. A worker of testsLogical runs many members in one process, and QTest reads the variable once per process, so the worker gets the largest budget of its members. kiln test still stops each member at its own budget |
QT_AUDIO_BACKEND |
pulseaudio. On Linux, Qt 6.10.1's PipeWire audio backend crashes about one first audio device enumeration in 20 (~NodeEventListener removes its hook without the thread-loop lock). With this value, Qt uses PulseAudio. Windows and macOS do not read it. A suite built on libtest also sets it itself, in TestArgs, so a direct run gets it too, and there it wins over the environment: --param audio-backend=pipewire selects PipeWire again |
PATH |
On Windows, Qt's bin folder comes first, so that the suite finds the Qt DLLs |
Profiles
A profile is a [profile=<name>] section of the root .kiln or of
.kiln.local. It sets only the keys of a run, never a product's settings. A run
without --profile uses the keys outside every profile section.
[profile=ci]
test.cap = 900
test.report = json junit
[profile=gate]
test.select = guard
[profile=windows]
test.select = platform
[profile=nightly]
test.cap = 1800
test.isolation = on
[profile=gpu]
test.display = on
test.select = testConstructViewportProducer
test.select += testViewportParity
The gpu profile names more suites than this extract shows. test.skip is set
once at the root, and every profile takes it.
| Key | Values | Default | Meaning |
|---|---|---|---|
test.skip |
categories | the root's value | The categories that the run leaves out. Each suite of one is SKIPPED |
test.select |
all, guard, platform, categories, suite names |
all |
The suites that the run keeps. guard keeps the guard suites, platform the suites with test.platform_sensitive. Each kind of value narrows the run. A suite named here runs whatever its category. A name that is no suite fails the run with exit code 3 |
test.cap |
seconds | 900 |
The time a suite that declares no timeout of its own may run. 0 waits |
test.jobs |
a count, or auto |
1 |
The suites that run at the same time. auto is half the cores, at least 1 |
test.report |
json, junit |
none | The result files to write. Without --report, they go into test-results/ of the build folder |
test.display |
auto, on, off |
auto |
Which suites run on the display. auto gives the display to the suites with test.real_platform |
test.isolation |
on, off |
off |
Runs each member of the shared binary twice, in its shard and then alone, and fails a member whose two verdicts differ |
Test suite keys
kiln import-qbs writes these keys from the properties of a suite's
test.qbs. Each one is a row of Keys.
Test.qbs property |
Key |
|---|---|
category |
test.category |
timeout |
test.timeout |
headless |
test.headless |
requiresRealPlatform |
test.real_platform |
intentionallyOffscreen |
test.intentionally_offscreen |
shared |
test.shared |
exclusive |
test.exclusive |
platformSensitive |
test.platform_sensitive |
guardTest |
test.guard |
expectedPassed |
test.expected_passed |
expectedMinimumPassed |
test.expected_minimum_passed |
test.shared = onmakes the suite a member of the shared test binary,test/shared/testsLogical, whose.kilntype istest-shared. A member must be headless and need no real platform.test.exclusive = onruns the suite alone, after the parallel part of a--jobsrun.test.intentionally_offscreen = <reason>exempts the suite from the backend check. Without it,kiln testfails a suite that took the OpenGL fallback while a real platform was reachable, and the reason is printed when it applies.test.platform_sensitive = onputs the suite in theplatformselection, which thewindowsprofile runs.
The build request
The build farm's form offers the build options that
integration/build-parameters.json declares. qbs reads the same file, derives
project.buildOptionSchema from it, and writes build-options.json into the
install tree's bin folder. The option testProfile picks the test run after
the build:
"testProfile": {
"type": "string",
"default": "ci",
"label": "Test Profile",
"category": "build",
"projectNative": true,
"choices": ["ci", "gate", "windows", "nightly", "gpu", "none"],
"summary": "Kind of test run after the build"
}
Its choices are the profiles of the root .kiln and none, which runs no
suite. The root .kiln sets it as option.testProfile = ci, and qbs takes it
as project.testProfile. The build itself does not read it.
The farm writes the values that its form chose into build-request.json: one
JSON object, with the option names of the schema as keys.
{
"enableSanitizers": false,
"testProfile": "nightly"
}
kiln test --options build-request.json reads only testProfile, and takes no
profile when the key is absent. Every other key is a build option, which
kiln test does not read. A file that is not a JSON object, or a testProfile
that is not a string, fails the run with exit code 3.
The tests.json record
tests.json is one JSON object: the run, then one entry per suite.
{
"schema": 1,
"commit": "5515671",
"profile": "ci",
"started": "2026-10-06T03:01:14Z",
"seconds": 2.29,
"shuffle": 1,
"totals": { "suites": 7, "passed": 1, "failed": 3, "timedOut": 1, "notBuilt": 1, "skipped": 1 },
"suites": [
{
"name": "testFail",
"verdict": "FAIL",
"reason": "1 failed (exit 1)",
"seconds": 0.002,
"passed": 3,
"failed": 1,
"skipped": 0,
"category": "unit",
"log": "logs/testFail.log",
"binary": "testFail",
"failedCases": [
{
"case": "testFail::fails1()",
"file": "src/tools/suite-fixture/main.cpp",
"line": 100,
"message": "'false' returned FALSE. (case 1 of the fixture)"
}
]
}
]
}
| Field | Meaning |
|---|---|
schema |
The version of this format, 1 |
commit |
The short commit of the checkout, with -dirty when it had changes |
profile |
The profile of the run, or empty |
started |
The start of the run, in UTC, ISO 8601 |
seconds |
The time of the whole run |
shuffle |
The --shuffle seed. Present only in a shuffled run |
totals |
The number of suites, and how many of them have each verdict |
suites[].name |
The suite |
suites[].verdict |
PASS, FAIL, TIMEOUT, NOT BUILT or SKIPPED |
suites[].reason |
Why, in words, as the suite's line says |
suites[].seconds |
The time of the suite |
suites[].passed, failed, skipped |
The counts of QTest's Totals: line |
suites[].category |
The suite's category |
suites[].log |
The suite's log, relative to the report folder. Empty when it did not run |
suites[].binary |
The program that the suite ran in: its own, or testsLogical. Empty when it did not run |
suites[].failedCases |
One entry per FAIL! or XPASS line: case, file, line and message |
tests.junit.xml comes from the same run. It holds one <testsuite> per suite
and one <testcase> per QTest slot, with classname set to the suite and
name to the case with its data tag. A suite with no verdict of its own cases
(a crash, a timeout, no program, every case skipped, or SKIPPED) gets one more
case, (suite), with the verdict as an <error> or a <skipped>. A report that
cannot be written fails the report, not the run.
test/fixtures/runner/tests.json and test/fixtures/runner/tests.junit.xml
are a real record with every verdict, written by kiln test.