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 = on makes the suite a member of the shared test binary, test/shared/testsLogical, whose .kiln type is test-shared. A member must be headless and need no real platform.
  • test.exclusive = on runs the suite alone, after the parallel part of a --jobs run.
  • test.intentionally_offscreen = <reason> exempts the suite from the backend check. Without it, kiln test fails a suite that took the OpenGL fallback while a real platform was reachable, and the reason is printed when it applies.
  • test.platform_sensitive = on puts the suite in the platform selection, which the windows profile 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.

In this section
Topics
reference development kiln build queue build description