Kiln
Commands, exit codes and the .kiln keys
Reference for the kiln command and the .kiln build description. Kiln is
the default build path. For the workflow — the first steps on a machine,
following a build, reading the queue, wrapping a qbs build — see
Build through the kiln queue, and
start at its Start here.
Commands
kiln check [path]— Whether kiln is ready to build the checkout atpath(default: the current folder's) on this machine, and the next command. One line per check,ok,fixorinfo, with the subject and what it found, and on afixline what corrects it. The checks, in this order:kiln, this program is the one the broker runs (thebinaryof the door file);broker, the broker answers, or none runs and the first build starts one;.kiln.local, it exists and git ignores it;qt.qmake, it names a Qt that meets the floor ofintegration/toolchain-requirements.json, and the fix names the newest Qt installation under~/Qtor/opt/Qt(C:/Qton Windows);output.dir, it is set, or the default build folder has room for a cold build;vendored trees, every pinned tree a product reads is there (kiln vendor);host,infountilkiln host checkexists. The last line isnext: <command>: the first fix, orkiln build.--jsongives the same as the fieldsschema,checksandnext. It writes no file, starts no broker and installs nothing. Exit 0 when every line isokorinfo, 1 when one isfixor the folder is in no checkout, 2 for a wrong command line.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 asqbs build, as an admitted job.kiln status— What runs, what waits, and why the ceiling is where it is. A job that a door started has alaneline with its host, account and commit, and a held queue and the desk share each have a line of their own.kiln progress [<id> | <path>]— One booking ofkiln buildorkiln test, read from its records with no connection to the broker: its state, its steps against the plan, the suites, the failures grouped by location, the estimate, the cache, missing features, the next steps and a cursor.--json,--fields <list>,--since <cursor>,--all,--unread,--ack,--no-ack,--waitwith--until <condition>and--timeout <seconds>,--variant. See Booking records.kiln remote <node> <verb>— Drives the shared builder of the inventory row<node>over ssh. See kiln remote.kiln door --root <folder>— The builder's end ofkiln remote, started by ssh. Not for a person. See kiln remote.kiln exclusive [--broker <name>] -- <verb> [args]— Runskiln <verb>with the whole queue: the broker admits no job of another checkout while it runs, and starts it when their jobs end. The hold ends with the verb. Exit 5 when no broker listens.kiln techniques— Each way kiln reuses work, its state (off, shadow, sampled, trusted), what it did on the running broker, and its evidence beside the gate;--jsonprints the same as numbers. Without a broker it reads the cache's files.kiln cache promote <technique>— Moves a technique one state up when its evidence meets the gate; otherwise it names every condition that is missing and exits 1.kiln cache demote <technique>— Moves a technique to Shadow, or to Off with--to off. It recalls nothing.kiln cache policy— The cache's retention policy and its parameters, which every broker of the user reads from the cache's index;--jsonas numbers.kiln cache policy set [<policy>] [<parameter>=<value>...]— Sets the policy (lru,value,shape-lru) and parameters:halfLifeHours(0.1 to 8760),floorShare(0 to 0.5),graceHours(0 to 8760),rootExpiryDays(0.5 to 365),boundGbanddiskFloorGb(0 to 100000),compressionLevel(0 to 9). A value out of range is refused with exit 2 and changes nothing.kiln cache simulate— Replays the index's log from an empty cache once for each--policy <name>[:<parameter>=<value>,...]and each--bound-gb <n>, both given as often as wanted (default: the live ones), from--since <date>. Prints the hits, misses and compile time saved, per build shape and in total;--jsonas numbers.kiln divergence show [<id>]— Lists the divergences the oracle kept, or prints one, where its two outputs differ and its command, and marks it read.kiln divergence replay <id>— Compiles a divergence's command clean again, without touching any output, and compares it with both kept sides.kiln replay <from>..<to>— Builds the commits of a range along first parents, each written over the one before into--replay-dir, through a broker of its own with an empty cache and the technique of--technique(defaultobjects) in Shadow.--last <n>with--to <commit>names the range by count,--productsthe folders to build (default every one undersrc),--disk-floor-gbwhere it stops (default 60). Each commit is a line ofreplay.jsonland its build's whole output islogs/<n>.log; the run joins the technique's evidence. A build refused for how it was asked or for what the machine lacks (exit 2 or 4) stops the replay, since every later commit would be refused too. Exit 1 when it found a divergence.kiln census <from>..<to>—kiln replay's history and options, with every technique as it is and each build traced: each compile counted against the input whose change made it run, with its phases and whether its object kept its bytes.census.jsonin--replay-dirholds it all; the text gives the totals and the causes, most compiles first.kiln bench— Two sets of techniques,--a(defaultnone) and--b(defaulttrusted), on the same work:--change <from>..<to>(each commit after the first, timed),--coldor--warm,--runsalternated runs each (3 or more). Both arms share one checkout and output folder under--bench-dir; each run has a broker of its own with the arm's cache. The text gives each arm's median and spread and whether the saving is above the noise;report.jsonevery run. Exit 1 when the arms made different files.kiln tune— Changes the running broker's queue:--slots <n>,--memory-budget-mb <mib>or--no-budget,--pauseor--resume, or--resetto the values it started with.--pause --announce "<text>" [--ttl <d>]also posts a hold on the announcement board;--resumenames each hold that still refuses the lanes. With no option it shows the state and changes nothing;--jsonprints the state as numbers. It sends oneTunemessage and never starts a broker. A lower value ends no job. Exit 2 for a value out of range, which changes nothing; 5 when no broker listens; 1 for a broker older than the command.kiln announce add|list|read|done— The announcement board of the builder's account: short messages for its lanes, each with an expiry.add "<text>"posts one, to every lane or with--to <lane>,...;--ttltakes90m,4hor2d(default 24h, at most 7d);--holdmakes it a hold, which refuses the lanes' new remote work (default 4h, at most 24h).list [--all] [--json]shows each active message, newest first, with the lanes that read it, saw it and have not seen it.read [--as <reader>] [--no-ack] [--wait] [--timeout <s>] [--json]prints the unread messages, oldest first, and marks them read.done <id>retires one. It needs no broker. Exit 2 for a bad command line, a text over 2000 bytes or 12 lines, or an expiry out of range; 4 for an unknown id; 5 for a full board (64 active messages, 8 per lane) or a board that cannot be written; 6 whenread --waittimed out with nothing new. See Read the builder's announcements.kiln serve— The broker.--slots,--reserve-mb,--memory-budget-mb,--hard-floor-mb,--idle-ms,--recycle-mb,--cache-max-gband--cache-disk-floor-gbshape it, the last two in place of the cache policy's bound and disk floor for this broker;--slotstakes 1 to the processor count plus one and--memory-budget-mb0 or 2048 and more, the rangeskiln tunetakes, and a value outside them stops it with exit 2;--cache-dirgives it a cache of its own, and--broker <name>serves on a name of its own beside the user's. It reads the machine filebroker.kilnin the account's kiln state folder when it exists:broker.slots,broker.memory_budget_mb,broker.idle_ms(0 keeps it running when idle), and the desk sharebroker.desk_slots,broker.desk_memory_budget_mbandbroker.desk_idle_s, which apply while someone used the keyboard or the mouse in the lastbroker.desk_idle_sseconds. A flag wins over the file's full value; a bad line stops it with exit 3.kiln explain [path] [key]— The settings of the product atpath, each with the file and line that set it, its sources, the folders it skips and the generators it needs.--variantpicks the variant.kiln deps [path]— Each product's libraries, read from its includes, as thedepsline its.kilnwould carry.kiln deps --stale <build root>— Reads each<object>.obj.jsonunder the build root, the filesclread to make the object, and prints aSTALEline for each product with an object older than one of them. Exit 1 when it found one, 4 when it found no list.kiln compileasksclfor the lists: it appends/sourceDependencies <object>.json, or the object folder with/MP, and reads/Foalso from a response file.kiln clean --report [path]— The build storage of this machine: each subfolder ofclean.roots, and each lane'sdefault,releaseanddebug, of 1 GiB or more on disk. Each row has its lane, size on disk, last write and state:MINE,stale(its lane moved more than 500 commits since the last write),lane,claimed(a symbolic link points into it) orother. It never lists aclean.keepfolder.--jsonprints the rows as JSON.kiln clean --report --reclaim-mine [path]— The same report, then deletes theMINErows and nothing else. Exit 1 when a folder does not go.kiln import-qbs [path]— Each product's.qbstranslated into its.kiln, with every construct it cannot translate named by file and line. It writes nothing.kiln import-qbs --check [path]— The overlay lint: only the constructs no overlay covers and the covers whose construct is gone. See Check modes.kiln graph [path]— Brings the checkout's kept graph up to date and prints what changed: files added, removed, changed and moved.--watchkeeps 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 file's path in the checkout. A member of the shared test binary is listed under it with its own path, for exampletest/testAdsr/TestAdsr.cpp.kiln sources --check <compile_commands.json> [path]— Holds each product's C and C++ sources to what the qbs build compiles. See Check modes.kiln synth <dest> [--times n] [path]— Writes a synthetic tree,ntimes the checkout (default 10), with the same products, files, sizes, includes and moc markers, for measuring the graph at scale.kiln keys— The key list below, printed from the schema.kiln keys --check [path]— Holds eachoption.*line of the root.kilnto the default of theproject.qbsproperty of the same name. See Check modes.kiln commands [path]— Every compile a build would run, as a compile database for an editor.--variantpicks the variant.kiln commands --check <compile_commands.json> [path]— Holds the defines, options, flags and include folders of each compile to the ones in the qbs build's compile database. See Check modes.kiln build [path...]— Builds the product at eachpath, in one plan, or every product, through the queue.--installlays out the install tree after it,--installedbuilds only what the install tree holds,--dry-runsays what would run,--variant releasebuilds the release variant intorelease/under the output folder, where no option buildsvariant.defaultof the root.kiln, which isdebug,--os windowsbuilds for Windows on another system withwindows.sysroot(kiln-file §KN-K26),--os androidfor Android withandroid.ndk, and--arch arm64for Linux on arm64 withlinux.sysroot.--techniques <list>picks the ways it reuses work: a list ofobjects,backend,snapshots,linkandreach, ortrusted, the default, ornone, which reads and writes no cache.--tracekeeps each step's phases, why it ran and whether its output kept its bytes in the build graph;--trace-filesalso each whole trace under<build root>/.kiln/traces;--steps-file <file>one JSON line per step it ran. Before it plans, the build stops with exit 3 when a pinned tree that one of its products holds is not the tree that its pin describes. The message names the tree, what the pin asks for and what the tree holds, and says to runkiln vendor. A pinned tree of the graph with fewer files than its marker counts is listed again before the build plans. A program with no source to compile and no library to link is not linked: a build of every product leaves it out with one line, and a build that names it stops with exit 3.kiln test [path...] [-- args]— Builds the suites at or under eachpathand runs each to its contract: its timeout, its expected counts, headless unless it needs a display.--prebuiltruns 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--batchsays otherwise. The options are in kiln test.kiln calibrate [--jobs n]— Measures how fast this host runs a suite against the reference host, the Threadripper 3970X that the suites' timeouts were written on, keeps the score inkiln/host-score.jsonin the user's cache folder, and prints it.--jobsis the number of suites that run at the same time, as inkiln test.kiln testmeasures by itself when no kept score fits, so this command is for a new machine or a check. See Host-scaled timeouts.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] [--all]— Writes the pinned trees the checkout's products read, such as LLVM's source, from the shared cache or by download checked against the pin. A tree no product reads waits, with a line that says so: Qt's source, until Qt's products are built.--allwrites every pinned tree. After it writes or replaces a tree, it lists that tree again in the kept graph, with the whole check ofkiln graph, so the next build sees every file of the tree.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 kit write <folder>— Writes the stage-0 kit of the checkout's kiln into<folder>, which must be new or empty: a GNU Makefile with one explicit rule for each file of kiln's own release plan, the files kiln's in-process generators wrote,kit.conf,closure.sha256, onepins/<name>.pinfor each pinned tree the plan reaches, andbootstrap.sh. A host with a C++ compiler, Qt 6's qtbase and Qt Svg, and GNU make builds a first kiln from the kit, with no kiln and no qbs. The kit is a release without link-time optimization,-Werror, debug information, split DWARF or split debug information, with the features of Qt modules off, and it links only the Qt modules whose headers its sources include.--checkout <dir>names the checkout (default: the current folder's), and--qmake <qmake>the Qt whose modules the plan uses (default:qt.qmake). A plan for Windows gives a Windows kit, for clang with its MSVC target and lld-link: on Windows by default, elsewhere with--os windowsand awindows.sysroot. The graph is read in memory, so no broker is needed. A plan the kit cannot carry is refused with exit 3 and nothing is written: each line names the cause, the product and the step, such as an include of a Qt module outside qtbase and Qt Svg, with the file, its library and the edge that brought the library into the closure, a qsb or unknown generator, a path make cannot name, a flag only clang takes, a link input the kit does not know, or a folder that is not empty.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.--shipnarrows the applications.--arch arm64on an x64 host builds for arm64 and makes<name>_<version>_arm64.debor thearm64archive; the Debian package then needs arm64 in this host's Debian multiarch (dpkg --add-architecture arm64, the target's libraries as:arm64packages,linux.sysroot = /) andbinutils-aarch64-linux-gnu. Making a package needs Debian's packaging tools and the binutils.kiln package kiln <folder>— Makes the standalone kiln infolder, which must be empty or new: the kiln that runs asbin/kiln, the libraries of the Qt installation that it links inlib/, the SQLite plugin inplugins/,bin/qt.confand clang's builtin headers. A host with no kiln unpacks the tree anywhere and runsbin/kiln. The first compile of a standalone kiln captures the host's C and C++ headers fromc++into the tree, so the host needs its C++ compiler and the standard library headers. Every other library is the host's. Linux only (kiln-stage0 §KS-D6).kiln package single <app> [path]— Builds and installs the application, then writes it as one program file into<build root>/package/single, release by default. The file carries Qt, its plugins and resources, and every library of the tree. It needsqt.provider = vendoredandqt.vendored.linkage = static, and is refused with exit 3 otherwise. Beside it,<app>.dependsnames the system libraries the program still loads, such as the C library, the graphics drivers and the windowing libraries, with the Debian package that owns each, and aDepends:line of those packages.<app>.debugholds its debug information when the build split it. The command refuses a program that loads a Qt library, or a library that no Debian package owns. Linux only (qt-vendoring §QV-D7g).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. Needswindows.sysrootwith the runtimewinvm runtimecopies.kiln package apk [path]— Builds the application at the path for Android (--archpicks the ABI) and makes its package in<build root>/package, signed with the SDK's debug key unlessandroid.keystorenames another. The tests-runner carries the suites--suitesnames. 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 newestbundletool-all-<version>.jarin the SDK) and signed with jarsigner. Needs the JDK'sjarsignerbeside whatapkneeds.kiln package apk [path] --install [--launch]— Makes the package as above, then installs it withadb install -ron the device adb sees, or on the oneandroid.devicenames; kiln asks adb for the device before the build.--launchthen starts the launcher activity of the application's manifest witham start -W -n <package>/<activity>and watches the process for--launch-watchseconds, 30 by default, 0 for not at all. A process that dies in that time exits 1 with its name, its process ID and thelogcatlines about that ID.--arch arm64and--arch x64both work. A 32-bit ABI, such asarmv7orarmeabi-v7a, is refused with exit 2 and a message that points toAGENTS.md, "Android architecture support".kiln install --list-layers [<name>]— Loads the Vulkan loader (libvulkan.so.1,vulkan-1.dllorlibvulkan.dylib) and prints the instance layers it offers, one name per line. With a name: exit 0 if the loader offers that layer, 1 if not. Exit 4 when there is no loader, 5 when it cannot be asked. It reads no environment variable; the loader reads its own.kiln install --register-layer <manifest|folder> [--all-users] [--unregister-layer]— Windows only, and exit 2 elsewhere with nothing done: registers a laid-out layer's manifest for the Vulkan loader, underSOFTWARE\Khronos\Vulkan\ExplicitLayersofHKEY_CURRENT_USER, or ofHKEY_LOCAL_MACHINEwith--all-usersfrom an elevated process: the manifest's absolute path as the value's name, DWORD 0 as its data. A folder means itsVkLayer_khronos_validation.json. It removes each value whose manifest is gone, and refuses a manifest whoselibrary_pathis not./<library>beside it.--unregister-layerremoves the value instead.kiln install --start-menu [path]— Windows only, and exit 2 elsewhere with nothing done: puts the Qt runtime beside the applications ofpackage.shipin the checkout's install tree, read from the programs with libdeploy as the Windows packages are, with the symbol files of Qt's own programs, then writes one Start Menu shortcut per application toPrograms\OctoMY.--variantpicks the build, release by default. Runkiln build --installfirst.kiln install --build-shortcuts [root...]— Windows only, and exit 2 elsewhere with nothing done: one shortcut per build and backend (d3d12,vulkan) inDesktop\octomy-builds, for each<root>\<configuration>\install-root\bin\construct.exe, opening the checkout's demonstration scene. The old shortcuts go first. The roots default to the test boxes'octomy\default,octomy-winmain\defaultandbrelmainin the home folder.kiln publish <folder>— Copies the running kiln into the folder, with the headers its compiler reads into<folder>/share/octomy: the headers first, then the program, each through a copy and a rename. A client that starts the published kiln finds its headers beside it, and a running broker keeps its old program until it restarts. Run it from an install tree (kiln build --install) or a build tree. Exit 1 for the program's own folder or a kiln with no headers under its root (kiln-file §KN-K21d).kiln publish <folder> --restart [--quiet-for <time>] [--wait-at-most <time>] [--broker-task <name>]— Publishes and restarts the broker in one quiet moment. The command waits until the broker has had no work for--quiet-for(default60s): no job, no queued job, and nokiln build,test,package,install,runorcoveragethat still runs. Then it publishes while the broker turns new work away, and the broker drains. A client that the broker turned away sends its job again after 2 s and meets the new broker. The old program is kept in<folder>/fallback/, and each publish adds a line to<folder>/publish.log. A time is written as90s,2mor6h. Exit 5 when no quiet came within--wait-at-most(default6h): the broker then serves on and nothing is published. Exit 1 when the publish failed: the broker serves on with the old kiln. Exit 4 when the broker is of a kiln that cannot hand over: publish without--restartonce (kiln-freshness §KFRD-3).kiln freshness --state <folder> --checkout <worktree> --publish-to <folder> [--packages <folder>] [--broker-task <name>]— One run of the automation that keeps a dev machine's kiln and apps current, made for a timer. It fetchesmaininto the work tree, which nothing else may use, and compares the code of kiln's whole link closure with the commit of the kiln in--publish-to. When they differ, it builds kiln with the published kiln, runs the gate suitestestKilnBroker,testKilnGraph,testKilnCompileandtestKilnBuildPlan, and publishes withkiln publish --restart, with--broker-taskwhen it is given (a Windows builder, whose broker no client starts). A commit that failed is kept in the state folder and not built again. With--packages, it then installs the newest app package of that folder when it is newer than the installed one, and keeps the two newest packages. Each run adds lines to<state>/freshness.logand writes<state>/state.json. A second run while one runs exits 0 and does nothing. Exit 1 when a step failed; the log says which (kiln-freshness §KFRD-4).kiln freshness status --state <folder>— Prints the last run, the published kiln, the installed package and a failed commit, if there is one.kiln freshness rollback-apps --state <folder>— Installs the older of the two kept packages again. Exit 4 when no older package is kept.kiln --version --verbose [--json]— The version, then the record of kiln's own code for its in-process steps: the commit kiln was built from, the folders of each row, and the folders that had local changes then. A kiln with no record says so. See When kiln's own code differs from your tree.kiln coverage [path]— Merges the profiles thatkiln testof a coverage build wrote,<report>/profiles, intocoverage.profdata, then counts the lines and functions of each source file of ours that the run reached, by library, intocoverage.jsonandcoverage.md, and prints the table.--reportnames the run's folder,test-resultsin the build folder by default;--prebuiltnames the build folder whose programs the profiles are of. Linux x86-64 only. See Coverage.kiln apidocs— Builds theapidocstool anduiautomationfor this host, then makes the API reference as theapi-referenceqbs product does: the widgets rendered into theimagesfolder besideapidocs.classes, QDoc's DocBook pages and the HTML that holds its index intoapidocs-reference/qdocin the build root, the pages counted againstapidocs.minimum_pages, and the markdown reference intoapidocs.classesand the folders beside it. Prints the page count. Needs Qt'sqdocand 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.
When kiln's own code differs from your tree
kiln runs some build steps with code that is part of the kiln program: the help, the asset bundles, the shader includes, and generators such as the OPAL registry. The output of such a step is the output of the kiln that ran it, not of your tree. A kiln built from a checkout records the folders of that code and the commit. Each build compares them with your checkout through git, over the steps that the build holds, and prints one warning for each row that differs:
kiln build: warning: the help step runs the code of kiln 211f15ccba, and this tree's src/libs/libhelpbuild differ from it, so its output is that kiln's. A kiln built from this tree gives this tree's output (kiln-freshness §KFRD-2).
The build goes on: its output is valid for the code of the kiln that made it.
If you need your tree's output, build kiln from your tree, or wait for the next
publish of the shared kiln. A kiln that qbs built has no record and checks
nothing. kiln check prints the same as one line, in-process.
The door file
The account's broker writes door.json, one line of JSON, in kiln's state
folder of the user when it starts, and removes it when it stops. kiln check, a client and a person
read it to find the broker and the kiln it runs.
| System | Path |
|---|---|
| Linux | /run/user/<uid>/kiln/door.json, the user's runtime folder |
| Windows | %USERPROFILE%\kiln\door.json |
| Field | Holds |
|---|---|
endpoint |
The socket, or on Windows the named pipe, that the broker serves on |
protocol |
The version of the broker's protocol |
pid |
The broker's process id. When no process has it, no broker runs and the file is left over |
started |
When the broker started, in UTC, ISO 8601 |
binary |
The absolute path of the kiln program that runs the broker: the machine's kiln for this account |
version |
That kiln's version |
commit |
The commit that kiln was built from |
A broker older than the fields binary, version and commit writes none of
them, and kiln check says so on an info line. A broker started with
--broker <name> serves on a name of its own and writes no door file.
Check modes
Until qbs retires, the .kiln files must describe what qbs, the second path, builds.
Four commands take --check and compare the two. commands, sources and
keys print what they found on the standard output. import-qbs prints it on
the standard error, as it did before it had a ceiling. Each exits with one of
these codes:
| Exit | Meaning |
|---|---|
| 0 | kiln and qbs agree |
| 1 | A difference. Each one is a VIOLATION line, or an OWED line for what a kiln compile cannot give yet |
| 2 | The command line is wrong, for example no compile database |
| 3 | An input does not read: the description, the database, a .qbs or an overlay |
| 4 | An input is missing, or part of the tree was not judged. The output gives the command that makes the input |
| Mode | What it compares | Differs by design, so not a finding |
|---|---|---|
kiln commands --check <db> [path] |
For each file both builds compile: the -D defines by name and value, the optimization level, the debug information, the language standard, the instruction-set flags, split DWARF, link-time optimization, exceptions and RTTI for C++, every other flag as a set, and each folder qbs includes from |
OC_TOOLCHAIN, OC_QBS_PROFILE and the commit defines by name only. OC_GIT_DIRTY and OC_GIT_NON_MAIN_BRANCH not at all. A path value under either build folder by its place in that folder. gcc's -frandom-seed, -m64 and -pipe. An include folder that only kiln has, and a folder inside either build folder |
kiln sources --check <db> [path] |
Each qbs product's compiled C and C++ files against the kiln product of the same name | A generated file outside the checkout. A product that is off on this system |
kiln keys --check [path] |
Each option.<name> line before the first section of the root .kiln, against property bool <name> or property string <name> in project.qbs, for each option that options.schema declares |
packageVersion, which is package.version. An option with projectNative: false. .kiln.local |
kiln import-qbs --check [path] |
Each construct of a .qbs that the importer cannot translate, against the qbs.covers lines of the product's overlay |
Up to qbs.uncovered_ceiling constructs with no cover |
commands --check shows the first five files of each difference, and
sources --check the first 40 files that kiln lists and qbs does not compile.
--list shows all of them. commands --check
needs qt.qmake, and it compares the variant that --variant picks, so give
the variant whose configuration wrote the database.
A product whose .qbs is newer than the database, and a source file that is
newer than the database, are not judged: the database has not seen them. The
mode names them and exits 4 when it found nothing else. sources --check
also fails when kiln lists more files that qbs does not compile than its
ceiling, which is 0. import-qbs --check exits 4 when it read no .qbs, and
says when the ceiling is higher than the count, so that you lower it.
The compile database comes from qbs:
qbs generate -g clangdb -d <build directory> -f project.qbs config:<configuration>
It writes <build directory>/<configuration>/compile_commands.json. For the
canonical build that is default/compile_commands.json.
OPAL tasks
The build family drives and reads the broker of the machine. None starts a
broker, and none raises the ceiling above the processor count plus one.
| Task | Does | Asks for confirmation |
|---|---|---|
build.queue.status |
Every job running and waiting, the ceiling and why it is there, and the pressure | No |
build.stats |
The broker's snapshot and its recent past, as the kiln activity draws it; since gives only what is newer |
No |
build.cache.stats |
The compile cache: hits, misses, what it kept and its size, and the index's store: per store and shape the entries, sizes, hit rate and floor, the policy, the target and the free disk |
No |
build.cache.policy |
As kiln cache policy, and with policy or parameters (name=value pairs, comma-separated) as kiln cache policy set |
Every call that sets |
build.cache.simulate |
As kiln cache simulate: policies (semicolon-separated), boundsGb (comma-separated), since |
No |
build.explain |
One product's settings, each with the file and line that set it | No |
build.run |
Builds or tests a folder of a kiln checkout, logging kiln's lines as it goes. With folder, kiln runs in that checkout or worktree, so the build counts as that lane's. Its progress is the booking's finished steps over its planned ones, with the state as the detail, and booking gives the id. A test run gives the path of its tests.json in report |
Once a session |
build.progress |
As kiln progress --json: one booking by booking (an id), or the live or newest booking of checkout (an absolute path; the working folder's if empty). since is a cursor, fields a comma-separated list, wait_s waits up to 0 to 540 seconds for the end while reporting the steps as progress, and ack marks an ended result read. The report is in report, the exit code of kiln progress in exit_code |
No |
build.announce.list |
As kiln announce list --json: the active messages, with all the ended ones of the last 7 days, in announcements, and their number in count |
No |
build.announce.read |
As kiln announce read --json for the reader as (opal if empty): the unread messages, then the read mark unless keep_unread. wait_s waits up to 0 to 540 seconds for one |
No |
build.announce.post |
Posts text for every lane or the lanes of to, comma-separated, with ttl and hold. The author is opal@<host>. Returns id and expires |
Every call |
build.announce.done |
Retires the message id before its expiry |
Every call |
build.cancel |
Ends one job by its session, or every job of one checkout or worktree by its folder |
Every call |
build.queue.tune |
As kiln tune: slots, memoryBudgetMb, pause (true or false) or reset, and returns the state after it |
Every call |
build.techniques |
Each technique's state, counters and evidence, as kiln techniques |
No |
build.techniques.promote |
As kiln cache promote: technique, one state up through its gate, or the conditions it misses |
Every call |
build.checks |
The oracle's results since since, with divergences true for the divergences alone |
No |
build.storage.report |
The rows of kiln clean --report for the checkout at path, as JSON in report; minimumMb (default 1024) is the smallest folder that is a row. It needs no broker and deletes nothing |
No |
build.activity.view |
Reads the kiln activity's Mix slider, or sets it with mix (0 to 100) as if you moved it; the charts and the lane and job lists follow. It fails when no kiln activity is open |
No |
build.remote.status |
As kiln remote <node> status: node, and inventory for another inventory file. The report is in report |
No |
build.remote.sync |
As kiln remote <node> sync: node, checkout, lane (the checkout's folder name if empty) and commit (HEAD if empty) |
Once a session |
build.remote.run |
As kiln remote <node> <verb>: verb (build, test, package, install, run or exclusive) and arguments, a list. The builder's lines go to the step's log |
Once a session |
build.remote.fetch |
As kiln remote <node> fetch: path in the lane's workspace and destination, a local folder |
Once a session |
build.run and build.cancel hold the kiln.broker resource, so two plans
cannot drive one queue at once. build.queue.tune holds none, so it is
answered while a build runs. The build.remote tasks hold none either: the
queue they drive is the builder's.
kiln remote
kiln remote <node> <verb> drives a shared builder: a row of
~/.config/octomy/devnodes.json with a builder object. The client starts
ssh <host> <builder.kiln> door --root <builder.root>, and the door relays
kiln's frames to the builder's one broker. The procedure is in
Build on the shared Windows builder.
| Verb | What it does |
|---|---|
sync [<commit>] |
Sends the commit, HEAD by default, as a git bundle of what the builder does not have, and checks it out in lanes/<lane>/ under the builder's root. Never uncommitted work |
vendor |
Runs kiln vendor of the builder's kiln in the lane's workspace: the pinned trees, such as LLVM's source, that a new worktree needs before its first build |
build, test, package, install [args] |
Runs kiln <verb> <args> of the builder's kiln in the lane's workspace. The output comes back as it is written |
run -- <program> [args] |
Runs the program in the lane's workspace as one admitted job of the builder's queue |
exclusive -- <verb> [args] |
Holds the builder's queue for the lane, then runs the verb. No job of another lane starts until it ends |
fetch <path> <folder> |
Copies a file or folder of the workspace to a local folder with scp |
progress [<id> | <path>] [args] |
Runs kiln progress of the builder's kiln in the lane's workspace, with the arguments of Booking records. It reads only the bookings of build roots inside the workspace, by their real paths: another, through an id or a link, is refused with exit 2. A --wait keeps the ssh session open while it waits |
status [--json] |
The builder broker's report, a line for each remote lane, and each workspace with its commit and its last sync. A workspace that no sync touched for 14 days is marked |
stop |
Ends every job of the lane on the builder |
clean |
Removes the lane's workspace |
announce add|list|read|done [args] |
The builder's announcement board, as kiln announce. The door runs it itself, with no broker. A post's author is the lane's origin; a lane cannot post a hold, reads as itself, and retires only its own messages. Its text may name a path |
| Option | Meaning |
|---|---|
--lane <name> |
The lane on the builder. Default: the folder name of the checkout. Lower-case letters, digits and - |
--inventory <file> |
Another inventory than ~/.config/octomy/devnodes.json |
builder key |
Meaning |
|---|---|
root |
The builder's root folder: repo.git, lanes/, logs/ and incoming/. Required |
kiln |
The builder's one kiln. Required |
vcvars |
Windows: the batch file whose environment each remote verb starts in, so a broker it starts gives cl its INCLUDE and LIB |
hostKey |
The builder's ssh host key, as ssh-keyscan prints it without the host. With it, ssh and scp accept that key and no other |
broker |
A broker name for the door and every kiln it starts, while the account's broker is not yet the builder's. Empty, the target: the account's own broker. The door starts the broker when none listens |
Each job that a door starts carries an origin: the lane, the host, the
account and the commit. kiln status on the builder shows it. A path in the
arguments is relative to the workspace: the client and the door refuse an
absolute path and a path with .., with exit 2. The exit code is the verb's
on the builder; 2 is a refusal, 4 a lane with no workspace, and 5 a failed or
dropped connection. A dropped connection ends the verb on the builder.
Each session but heads, lanes and announce starts with the lane's unread announcements, on standard error, until the lane reads them; a relayed status shows the ones for every lane. While a hold is active for the lane, build, test, package, install, vendor, run, exclusive, sync and clean end with exit 5 and the hold's text, also when no broker runs.
The stage-0 kit
What kiln kit write writes, and what its bootstrap.sh does with it
(internal spec kiln-stage0).
| File | What it holds |
|---|---|
bootstrap.sh |
The script that builds a first kiln from the kit |
Makefile, rules/<product>.mk |
One explicit rule for each file of kiln's release plan. Paths are the make variables KS_SRC, KS_OUT, KS_KIT, KS_QT_HEADERS, KS_QT_LIBS and KS_QT_SPEC |
kit.conf |
key=value lines: kit.format, kit.commit, kit.commit_date, kit.kiln, kit.arch, kit.os (linux or windows), qt.minimum, qt.modules (module keys), make.tested, cxx.tested.gcc, cxx.tested.clang, pins (pin names), system.libraries, products |
closure.sha256 |
The sha256 of each checkout file the kit reads, as sha256sum writes it |
pins/<name>.pin |
Each pinned tree the plan reaches, as key=value lines |
gen/ |
What kiln's own generators wrote: pantry bundles, branding, the OPAL family files, the build-*.json files. A .in file names the checkout and the build folder as @KS_SRC@ and @KS_OUT@ |
bootstrap.sh --checkout <dir> --qmake <qmake> [--build <dir>] [--jobs <n>]
[--cxx <path>] [--cc <path>] [--ar <path>] [--ld <path>] [--make <path>]
[--launcher <path>] [--archive <name>=<file>]... [--check-only] [--help]
The script checks the tools, the Qt modules, each system library, and every
checkout file against closure.sha256. It makes each pinned tree exactly as
kiln vendor does, from the archive and the pin's tree digest, so kiln vendor keeps it later. Then it writes config.mk and runs GNU make with an
empty environment: PATH of the tools it found, LC_ALL=C.UTF-8 and HOME.
The job count is the processor count, held to the free memory at 1.5 GiB a
job. --check-only stops after the checks and writes nothing. --launcher <path> runs each compile and link through a launcher such as ccache, so a
second build of a kit takes its objects from the launcher's cache. The script
reads no environment variable for a setting.
A Windows kit runs in Git Bash. The compiler is clang with the target
x86_64-pc-windows-msvc, and llvm-ar and lld-link (--ld) come from its
folder. make must be a GNU make built for Windows. Every path is written as
C:/a/b. The build keeps ProgramData and SYSTEMROOT besides PATH, because
clang and lld-link find MSVC and the Windows SDK through ProgramData, and sets
MSYS2_ARG_CONV_EXCL=* so that Git Bash passes the compiler's arguments unchanged. The
first kiln is kiln.exe, with the Qt DLLs it links and a qt.conf beside it.
| Exit | Meaning |
|---|---|
| 0 | The first kiln exists and starts |
| 1 | make failed, or the first kiln does not start |
| 2 | A flag is wrong, or a path holds a character make cannot name |
| 3 | kit.conf has an unknown format, or a checkout file, a tree digest or an override differs |
| 4 | A tool, a Qt module, a system library or a folder is missing |
| 5 | A download or a write failed |
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 |
| 6 | Pending: the work goes on, ask again. kiln progress of a live booking, or at the timeout of --wait |
Booking records
Each kiln build and kiln test writes one booking in
<build root>/.kiln/bookings/<id>/, readable by its user only. The id is
<yyyyMMdd>T<HHmmss>-<pid>-<4 hex digits>, in UTC, and the run says it in the
line kiln build: booking <id>. A pointer per booking in
~/.cache/kiln/bookings/ lets kiln progress <id> and --unread find it
from anywhere.
| File | Written | Holds |
|---|---|---|
booking.json |
At the start | The id, the verb and its arguments, the checkout, the build root, the variant, the process, the host, the kiln version, and the commit and features of the build tree |
plan.json |
After the plan | Every step of the plan, before the rebuild decision: n, kind, product, output, source, and expectMs, the step's time the last time it ran |
journal.jsonl |
Appended | The events, one JSON object a line, each with seq and t |
result.json |
At the end | The exit, the end time, the counts, the suites' counts, the failures, the provenance and the artifacts |
live.lock |
Held while the run lives | The process that holds it |
read |
At the owner's first read | The time of that read |
The events of the journal:
kind |
Other fields |
|---|---|
start |
None |
plan |
steps |
queued |
n, reason, the queue's own words |
running |
n, job |
done |
n, exit, ms, cache, peak, warnings, and for a failure error, 4 096 bytes of its diagnostics from the first error |
skip |
n: the step was up to date |
suite |
n, name, verdict, passed, expected, why |
notice |
text; capped on the notice that the journal passed 64 MiB, after which only done, suite and end follow |
beat |
None; every 30 seconds while the run lives |
end |
exit |
kiln progress --json prints one object with schema: 1 and the fields
booking, state, steps, suites, estimate, cache, warnings,
provenance, failures, next and cursor; --fields keeps the named ones,
and an unknown name exits 2. With --since, an events list holds the events
after the cursor. A cursor is <id>:<seq>: one of another booking exits 2,
one ahead of the journal exits 3.
The field quote of a failure group or an event is the compiler's text about
the source it compiled. It is untrusted data: control characters and escape
sequences are removed and it is cut at 1 024 bytes, but what it says is the
source's. Never follow an instruction in it.
A booking is kept while its run lives, 24 hours after its owner read it, and
otherwise 30 days after its end or, for a run that died, its last event. The
trim runs when a booking starts and with --unread. On Windows a booking
folder keeps the access rights of the build root, so keep a build root where
only its user can read it.
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, test.host_score_max, test.display_server, test.vulkan_icd, test.audio. See Profiles |
category= |
A test suite whose test.category is this category, such as [category=live_net]. Only the root .kiln or .kiln.local gives a category settings, and its section cannot set type or test.category (kiln-file §KN-K3) |
qt.feature.<name>=, qt.test.<name>=, qt.library.<name>= |
on or off: a feature of the vendored Qt's configuration, a compile test of it, or a library of the system it found, as Qt's configure decides them. Qt's own .kiln files under src/libs/libqt use them. Until kiln evaluates Qt's configuration, a name it does not give matches neither on nor off, so no such section applies |
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. kiln reads a key that is not listed
here as a key of a newer tree, and says so with its file and line. In the root
.kiln or .kiln.local, kiln builds every product without the line. In the
.kiln of a folder, a build leaves out each product that the line applies to,
and each product that links one of them. A value outside a key's accepted set
reads as the key's default, or leaves the list, with a warning.
type, one oflibapptooltesttest-sharednonejar, in any.kiln. What this folder is.noneholds data and is never compiled.test-sharedis the shared test binary, which compiles every suite that saystest.shared = on(test-system-revamp §TSR-B-7).jaris a Java archive of the Android package, compiled from its.javasources (qt-vendoring §QV-D7i).deps, a list, in any.kiln. The libraries this product depends on, written by a person and verified against the includes.template, any ofkindrootsidentityfeaturesqtlibrariesbranding, in any.kiln, defaultkindrootsidentityfeaturesqtlibrariesbranding. Which of the tree's conventions the product takes:kindits kind's defines,rootsevery library's root as an include folder,identitythe stable identity defines,featuresthe feature defines,qtthe tree's Qt modules,librariesthe exports of every library the tree uses everywhere,brandingthe 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, a list, in any.kiln. The stable identity defines the description states, such as the variant's name, which a product takes whentemplateholdsidentity; kiln adds the toolchain's (§KN-K18b).features.defines, a list, in any.kiln. The defines of the features present, which a product takes whentemplateholdsfeatures(§KN-K18c).qt.modules.tree, a list, in any.kiln. The Qt modules the tree's templates give, which a product takes whentemplateholdsqt(§KN-K5).qt.modules, a list, in any.kiln. 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, a list, in any.kiln. 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, a list, in any.kiln. Definitions every product that uses this library compiles with (§KN-K19a).export.includes, a list, in any.kiln. System include folders, relative to the checkout, every product that uses this library compiles with (§KN-K19a).export.to.all, a switchonoff, in any.kiln, defaulton. Whether every application and test takes this library's exports, as qbs'soctomylibproduct type gave them. On for a library of the tree; a raw one says so itself (§KN-K19c).export.uses, a list, in any.kiln. 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, a list, in any.kiln. Qt modules every product that uses this library compiles and links with (§KN-K19a).export.std, one ofc++17c++20c++23, in any.kiln. The least C++ version every product that uses this library compiles with: a product takes the highest its owncompiler.stdand its libraries ask for, as qbs does (§KN-K19a).export.link.libraries, a list, in any.kiln. System libraries every program that uses this library links with (§KN-K19a).export.compiler.flags, a list of flags, in any.kiln. Compiler flags every product that uses this library compiles with, after its own, as CMake passes a PUBLIC or INTERFACE compile option on (§KN-K19a). Each must be known to the flag table.export.linker.flags, a list, in any.kiln. Options passed to the linker of every program that links this library, after its own, as CMake passes a PUBLIC or INTERFACE link option on (§KN-K19a).variant.defines, a list, in any.kiln. Definitions every product of the variant compiles with, whatever its template:NDEBUGin release, as qbs gives a raw item too (§KN-BG11c).options.defines, a list, in any.kiln. 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, a switchonoff, in any.kiln, defaulton. Whether the product is built at all. Off for one whose.qbscondition is never true, which the importer writes, as qbs leaves the product out;kiln explainsays why (§KN-F25).built_by_default, a switchonoff, in any.kiln, defaulton. Whether a build of every product takes this one, as qbs's builtByDefault. Off, it builds when it is named or when a product the build takes depends on it (§KN-K4b).requires, a list, in any.kiln. The features this product needs; without one of them it is skipped with one line.systems, any oflinuxwindowsandroid, in any.kiln. The systems this product is built for. Unset means every system; a product for some of them lists them.install, a switchonoff, in any.kiln, defaultoff. Whether the product is installed with the application.install.dir, a value, in any.kiln, defaultbin. The folder underinstall.prefixthe product's file is installed in, as qbs's installDir: a loader plugin's folder beside the programs, such asbin/vulkan/explicit_layer.d(§KN-K21a).install.files, a list, in any.kiln. 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 fromconfigure.files(§KN-K21a).runtime.dlopen, a list, in any.kiln. The system libraries this product's code opens at run time by name, withdlopenorQLibrary, by soname:libvulkan.so.1. No link names them, so the Debian package'sDependsand the.dependsofkiln package singletake each one's Debian package from here, for every product a program links; thedlopen-declaredlint refuses a load in a product's sources that its list does not name (§KN-K23g).library.shared, a switchonoff, in any.kiln, defaultoff. Whether the library is linked as a shared object a loader opens, as qbs's DynamicLibrary:lib<output.name>.so,<output.name>.dllon Windows. It links the libraries it uses as a program does (§KN-K21a). A product that names it inuseslinks it and finds it at run time through a run path from its own folder; a plugin is named by none (§KN-K21c).library.soversion, a value, in any.kiln. The version a shared library's file and soname carry,lib<output.name>.so.<library.soversion>, as Qt's libQt6Core.so.6; none by default (§KN-K21c).output.name, a value, in any.kiln. The base name of the product's file, instead of the product's name, as qbs's targetName.layering.tier, one offoundationwidgets, in any.kiln. The library's layering tier: what it may depend on is checked against it.layering.core, a switchonoff, in any.kiln, defaultoff. Whether the library's public headers include Qt Core and nothing else from Qt, so a host tool may use it.qbs.covers, a list, in any.kiln. The fingerprints of the constructs of the product's.qbsthat this file translates by hand, askiln import-qbsnames them. A construct with no cover, or a cover whose construct is gone, fails the build.qbs.uncovered_ceiling, a number, in the root.kilnonly. How many constructs of the tree's.qbsfileskiln import-qbs --checkaccepts with no cover: more fails the check, and fewer asks for a lower number. Unset is 0 (script-ports §SCP-D-4.1).sources.exclude, a list, in any.kiln. Folder names the source glob skips.kiln explainlists every folder skipped.export.generated, a switchonoff, in any.kiln, defaultoff. Whether the products that use this library compile with its gen/ folder, where its steps write, as a system include folder (§KN-K12k).generated.replaces, a value, in any.kiln. A committed folder of generated files, relative to the checkout, that this product makes again in its gen/ folder: an include folder in it, of any compile, is read from the gen/ folder instead (§KN-K12k).sources.vendored, a list, in any.kiln. Sources from a tree ofvendor.trees, each<tree>:<path>: a folder with its subfolders, lesssources.exclude; a folder's own files when the path ends in/*; or one file. The one place a product compiles what lies outside its folder (§KN-K5b, qt-vendoring §QV-D3e).sources.files, a list, in any.kiln. Globs, relative to the product folder, naming exactly the files it compiles, in order: a glob adds,!globtakes away, and the last that matches decides. Unset, it compiles every source the walk finds (§KN-K13a).sources.required, a list, in any.kiln. 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, a list, in any.kiln. Include folders beyond the library roots, relative to the checkout: vendored headers, committed generated headers. Agen:folder is below the product's gen/ folder, abuild:one below the build root (§KN-K12j3).qt.module.depends, a list, in any.kiln. In one of Qt's modules: the keys of Qt's module table its entry depends on,corefor QtGui, as its qt_lib_.pri says (qt-vendoring §QV-D4b). qt.module.internal, a switchonoff, in any.kiln, defaultoff. In one of Qt's modules: an INTERNAL_MODULE, whose entry in Qt's module table is its private half alone,connectivity_private, whatever its target's name (qt-vendoring §QV-D4b).qt.module.private.depends, a list, in any.kiln. In one of Qt's modules: the keys its private half depends on beside the module itself,core_privatefor QtGui, from its PRIVATE_MODULE_INTERFACE (qt-vendoring §QV-D4b).qt.translations, a switchonoff, in any.kiln, defaultoff. In Qt's translations product: the.qmits steps write and thecatalogs.jsonbeside its.kilnare Qt's translations, laid out in<build root>/translations/and installed in<prefix>/translations/, whereQLibraryInfolooks (qt-vendoring §QV-D3n).qt.plugin.type, a value, in any.kiln. In one of Qt's plugins: its PLUGIN_TYPE, the folder below plugins/ it loads from,platformsfor the xcb plugin; a static program links the plugins of its closure's types (qt-vendoring §QV-D7e).qt.plugin.module, a value, in any.kiln. In one of Qt's plugins: the module it belongs to, whose PLUGIN_TYPES has its type,QtGuifor the xcb plugin; a static program links it where it links that module (qt-vendoring §QV-D7e).qt.plugin.class, a value, in any.kiln. In one of Qt's plugins: its class, which a static program's Q_IMPORT_PLUGIN line names,QXcbIntegrationPlugin(qt-vendoring §QV-D7e).qt.android.jars, a list, in any.kiln. In one of Qt's modules or plugins: the jars an Android package of it carries, as its QT_ANDROID_BUNDLED_JAR_DEPENDENCIES names them below Qt's prefix,jar/Qt6Android.jar; the build makes thetype = jarproduct of that name for an Android program that loads it (qt-vendoring §QV-D7i).qt.android.libs, a list, in any.kiln. In one of Qt's modules or plugins: the libraries an Android package of it carries beside what it links, as its QT_ANDROID_LIB_DEPENDENCIES names them below Qt's prefix without the ABI,plugins/platforms/libplugins_platforms_qtforandroid.so(qt-vendoring §QV-D7i).qt.android.permissions, a list, in any.kiln. In one of Qt's modules or plugins: the Android permissions it needs, each a quoted entry of the permission's name and then its attributes as<attribute>=<value>, as qt_internal_add_android_permission records its NAME and ATTRIBUTES,"android.permission.BLUETOOTH_CONNECT minSdkVersion=31"(qt-vendoring §QV-D7i).java.classpath, a list, in any.kiln. In atype = jarproduct: the othertype = jarproducts its sources compile against, made first,Qt6Androidfor the multimedia jar (qt-vendoring §QV-D7i).includes.qt.library, a list, in any.kiln. Libraries of the system that Qt's configure finds, by its table's name,glib2, whose header folders the product compiles with: each folder the probe found, named below the target's root (§KN-K12j4).export.includes.qt.library, a list, in any.kiln. As includes.qt.library, for the products that use this one or take its headers: a library Qt links publicly, KmsSupportPrivate's libdrm (§KN-K12j4).includes.system, a list, in any.kiln. 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 itsincludesis a system folder.defines, a list, in any.kiln. Preprocessor definitions,NAMEorNAME=value.defines.paths, a list, in any.kiln. Definitions that name a place,NAME=relative/path: the absolute path in the checkout, quoted, at build time.NAME=.is the checkout,NAME=@buildthe build directory (§KN-K18a).edition.defines, a list, in any.kiln. 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, a list, in any.kiln. The product's asset bundles, one quoted entry each offield=valuewords:nameandsource(a folder relative to the product),mount(by default/<name>), and any number offilterglobs,memberpaths, and alistJSON file with itskeys. Kiln writes each and compiles it with rcc under its name (§KN-K12c).branding.resource, a switchonoff, in any.kiln, defaultoff. Whether the product compiles the edition's resource file, branding.qrc, under the namebranding, which Q_INIT_RESOURCE(branding) names; libres does (kiln-file §KN-K12b).shaders.bake, a switchonoff, in any.kiln, defaulton. 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, a value, in any.kiln. 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, a list, in any.kiln. Files written from a template into the product's folder in the build tree, one quoted entry each ofin=<template>, relative to the product,out=<name>, and@NAME@=valuewords, each@NAME@of the template replaced by its value; a template naming a@NAME@the entry does not give is an error.{pin:<tree>.commit}or{pin:<tree>.version}in a value is that field of the pin of a tree ofvendor.trees, read from the pin (§KN-K12h).qt.provider, one ofinstalledvendored, in the root.kilnonly, defaultinstalled. Where the build takes Qt from:installed, the installationqt.qmakenames, orvendored, the Qt kiln builds from its pin withqt.vendored.build = on: each Qt module a product asks for is a product it uses, and its moc, rcc, uic and qsb steps run the tools the build makes (qt-vendoring §QV-D7).qt.vendored.modules, a list, in the root.kilnonly. The modules of the vendored Qt, as qt-everywhere-src names its folders, in the order Qt builds them: each one's feature table undersrc/libs/libqt/<module>is evaluated (qt-vendoring §QV-D8).qt.vendored.features, a list, in the root.kilnonly. The vendored Qt's features the configuration sets, each<feature>=onor<feature>=off; every other feature takes the value Qt's configure gives it. A feature set on whose condition is false is an error that names the condition's first false term (qt-vendoring §QV-D4c, §QV-D8).qt.vendored.variables, a list, in the root.kilnonly. CMake variables Qt's configure reads that a package of Qt sets, eachNAME=value: aTEST_*result, a minimum version, an option such as LLVM_ENABLE_RTTI.{pin:<tree>.commit}or{pin:<tree>.version}in a value is that field of the pin of a tree ofvendor.trees(§KN-K12h), so a vendored library's version follows its pin (qt-vendoring §QV-D8).qt.vendored.bundled, a list, in the root.kilnonly. The libraries the vendored Qt takes from its own src/3rdparty instead of the system: double-conversion, freetype, harfbuzz, libb2, libjpeg, libpng, md4c, pcre2, sqlite, xcb-xinput, zlib. Each turns itssystem_*feature off; a library not named is taken from the system when it is there (qt-vendoring §QV-D5, §QV-D8).qt.vendored.build, a switchonoff, in the root.kilnonly, defaultoff. Whether the build makes Qt's own products from the pin: Qt's configure runs for the target, its conditions decide Qt's.kilnfiles, and the walk goes below the folders that saywalk.with_qt = on. The tree's products take Qt fromqt.provider, these products withvendored(qt-vendoring §QV-P5 to P8).includes.from, a list, in any.kiln. Products whose exported include folders this product compiles with, without linking them: theirexport.includes, gen: ones included, as Qt's bootstrap library takes QtCore's headers (qt-vendoring §QV-P5). The product is planned after each.export.includes.from, a list, in any.kiln. Asincludes.from, and passed on to the products that use this one.uic.program, a value, in any.kiln. A tool of the checkout that runs uic on this product's forms in place of the Qt installation's uic: Qt's own products take the uic the build makes from the pin (qt-vendoring P6). The build makes the tool first.rcc.program, a value, in any.kiln. A tool of the checkout that runs rcc on this product's resource files in place of the Qt installation's rcc: Qt's own products take the rcc the build makes from the pin (qt-vendoring P6). The build makes the tool first; its output's compression is the build's Qt's.moc.metatypes, a value, in any.kiln. In one of Qt's modules: the file name of its metatypes,qt6qml_metatypes.json. Each of its moc steps writes its JSON beside its output, and a step after them collects them intogen/meta_types/<name>, as qt6_extract_metatypes does; a{metatypes}in a tool step of a product that uses the module names it (qt-vendoring P7).moc.program, a value, in any.kiln. A tool of the checkout that runs moc on this product's sources in place of the Qt installation's moc: Qt's own products take the moc the build makes from the pin (qt-vendoring §QV-P5). The build makes the tool first, and a product that takes no installed Qt gets moc steps, and no uic or rcc, from it.moc.skip, a list, in any.kiln. Sources moc does not read, relative to the product's folder as its sources are listed: Qt's SKIP_AUTOMOC files, whose meta-object code another source includes.walk.with_qt, a switchonoff, in any.kiln, defaultoff. In atype = nonefolder: the walk goes below it when the build makes Qt's own products (qt.vendored.build = on), as src/libs/libqt says; otherwise nothing below it is read (§KN-K4, qt-vendoring §QV-D3e).qt.vendored.linkage, one ofsharedstatic, in the root.kilnonly, defaultshared. How the vendored Qt's libraries are linked:shared, its shared libraries, orstatic, its archives (qt-vendoring §QV-D7e).tool.steps, a list, in any.kiln. Runs of a program of the build that write files of the product, one quoted entry each ofprogram=<a tool or app>,out=<file>under the product's gen/ folder (one or more, the first the step's output),in=<file>relative to the product,arg=<word>in order,depfile=onandcompiled=on, which compiles each source among the outputs,cwd=genorcwd=build:<folder>, where it runs, andenv=<NAME>=<value>, a variable of its process alone; an argument or a value names{in},{out},{in.N},{out.N},{gen},{folder},{build}and{depfile}, and an argument{includes}is the product's include folders as@<file>,-I<folder>a line. The build makes the program first (§KN-K12j).pantry.live, a switchonoff, in any.kiln, defaultoff. 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, a switchonoff, in any.kiln, defaultoff. Whether a program defines the OPAL task-family dispatch from the libraries it links (§KN-K12f). Every program whose template holdslibrariesdoes; another says so, as qbs's opalregistry module, which a Tool loads by name.build.linked_sources, a switchonoff, in any.kiln, defaultoff. Whether a program records the code of kiln's in-process steps: the folders of each step's libraries, the commit it was built from and what differed from it then. A kiln with the record warns when a tree's code for those steps differs (kiln-freshness §KFRD-1). Only kiln's own product says it.git.defines, any ofvolatilebranch, in any.kiln. The identity defines beyond the stable ones every product has:volatile(the commit and whether the tree is dirty) andbranch(§KN-K18b).features, a list, in the root.kilnonly. The feature names this project knows. Each is present when what its own section says it needs is:feature.qt,feature.treeandfeature.systems; one that says none is always present (§KN-K7a).feature.qt, a list, in the root.kilnonly. In a feature's own section, the Qt modules it needs: it is present when the installation has every one.feature.tree, a list, in the root.kilnonly. 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 oflinuxwindowsandroid, in the root.kilnonly. In a feature's own section, the systems it exists on: on another it is absent, and permanently so.features.required, a list, in the root.kilnonly. Features that must be present: one of them missing is an error, whateverfeatures.strictsays, as qbs's requireLlvm, requireLlama and requireRl make it.features.strict, a switchonoff, in the root.kilnonly, defaultoff. Whenon, a product whose feature is missing is an error instead of a skip. A feature the root does not declare is not wanted, and stays a skip.variants, a list, in the root.kilnonly. The variant names this project knows. A variant nobody declares is an error.variant.default, a value, in the root.kilnonly. The variant built when none is named. It must be one ofvariants.compiler.std, one ofc++17c++20c++23gnu++17gnu++20gnu++23, in any.kiln, defaultc++20. The C++ language version; a gnu++ one adds the compiler's extensions, as CMake's default does for Qt's own sources (qt-vendoring §QV-D8d).compiler.c_std, one ofdefaultc99c11c17gnu11gnu17, in any.kiln, defaultdefault. The C language version of the product's C sources;defaultis the compiler's own, as qbs leaves it when a product names none.compiler.optimization, one ofO0O1O2O3OsOz, in any.kiln, defaultO0. The optimisation level.compiler.debuginfo, one ofnonelinefull, in any.kiln, defaultfull. How much debug information to emit.compiler.split_dwarf, a switchonoff, in any.kiln, defaultoff. Whether a C++ compile with full debug information writes it to a.dwobeside 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 ofoffthinfull, in any.kiln, defaultoff. Link-time optimisation.compiler.include_roots, one ofallused, in the root.kilnonly, defaultused. Which library folders a compile of a product that takes therootspiece gets as include roots:all, every library's, orused, the libraries the product's includes reach and theirs in turn, in the order ofall. One header path has one owner (kiln-file §KN-K6b), so a unit finds the same headers either way, and withuseda new library changes only its users' commands (kiln-fine-cache §KF-F16). A root key: the build reads it once.compiler.exceptions, a switchonoff, in any.kiln, defaultoff. Whether C++ exceptions are enabled.compiler.rtti, a switchonoff, in any.kiln, defaultoff. Whether run-time type information is enabled.compiler.warnings, a list of flags, in any.kiln. Warning flags. Each must be known to the flag table.compiler.flags, a list of flags, in any.kiln. Other compiler flags. Each must be known to the flag table.compiler.sanitize, any ofaddressundefinedintegerthread, in any.kiln. The sanitizers a compile instruments for and a link takes the runtimes of, which the build makes from the vendored compiler-rt (§KN-K31). address and thread exclude each other; undefined and integer go with one of them.compiler.coverage, a switchonoff, in any.kiln, defaultoff. Whether a compile instruments for LLVM source-based coverage and a link takes the profile runtime, which the build makes from the vendored compiler-rt; kiln test collects the profiles and kiln coverage summarizes them (§KN-K32).linker, one ofbfdgoldmoldlld, in any.kiln, defaultbfd. The linker the compiler driver uses.linker.split_debug, a switchonoff, in any.kiln, defaultoff. Whether a program's debug information is moved into<program>.debugbeside 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, a list, in any.kiln. Options passed to the linker itself, such as--gc-sections.linker.version_script, a value, in any.kiln. The version script, relative to the product, orgen:below its gen/ folder for one a step writes, that names the symbols a shared library exports; an edit to it links the library again (§KN-K21a).linker.dynamic_list, a value, in any.kiln. The dynamic list a shared library's link passes with --dynamic-list, the symbols it keeps open to interposition: relative to the product,gen:below its gen/ folder, orbuild:below the build root, as Qt's QtCore.dynlist that its configure writes (§KN-K21c).link.libraries, a list, in any.kiln. System libraries outside Qt that a product links, such asdlorws2_32, usually in anos=section.link.static_runtime, a switchonoff, in any.kiln, defaultoff. 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 ofunitintegrationwidgethardwareinteractivelegacyperflive_audiolive_netopal, in any.kiln, defaultunit. The test's category.legacy,interactive,hardware,perfandlive_audioare left out by default.test.requires, any ofd3d12elf-closureposixprocfsserial-ttyvulkan, in any.kiln. The capabilities the suite needs from its target, such asd3d12, never an operating system. A build of every product, and a run ofkiln test, leaves out a suite whose target lacks one, and the run reports it SKIPPED with the reason, even when its path names it (kiln-file §KN-K15d).toolchain.headers.capture, a value, in any.kiln. The host compiler, such asc++, 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, a switchonoff, in any.kiln, defaultoff. Whether the suite reads the install tree:kiln testbuilds every installed program in its batch and lays the tree out before it runs, as a whole qbs build leaves one (§KN-K15a).toolchain.compiler_rt, a value, in the root.kilnonly. The vendored compiler-rt, relative to the checkout, which a sanitized build makes its runtimes from (§KN-K31).toolchain.clang.headers, a list, in any.kiln. 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, a list, in any.kiln. The tree's programs a suite runs, by product name:kiln testbuilds them with it, since the suite finds them beside itself rather than linking them (§KN-K15a).test.timeout, a number, in any.kiln, default60. Seconds before the suite is ended as hung; 0 for never, as an interactive suite needs.kiln testalso gives this value, plus 10 seconds, to QTest's per-function watchdog,QTEST_FUNCTION_TIMEOUT.test.headless, a switchonoff, in any.kiln, defaulton. Whether the suite runs without a display.test.real_platform, a switchonoff, in any.kiln, defaultoff. Whether the suite needs a real window system rather than the offscreen one.test.skip_build, a value, in any.kiln. Why the suite cannot run in a build class at all, under the[option.…=on]section of that class.kiln testthen reports it SKIPPED withbuild class <class>: <reason>and does not run it (build-class §BCL-6).test.intentionally_offscreen, a value, in any.kiln. Why the suite runs on the OpenGL fallback on purpose, when a real platform is there. Without it,kiln testfails a suite that took the fallback beside a reachable display (test-system-revamp §TSR-R-6).test.shared, a switchonoff, in any.kiln, defaultoff. 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, a switchonoff, in any.kiln, defaultoff. 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 = platformkeeps only these suites, as the Windows leg does (test-system-revamp §TSR-S-3, §TSR-R-7).test.exclusive, a switchonoff, in any.kiln, defaultoff. Whether the suite runs alone, after the parallel part of akiln test --jobsrun, for a reason other than a display: a fixed port, a heavy benchmark (test-system-revamp §TSR-R-5).test.namespace, one ofnoneuser, in any.kiln. The namespacekiln teststarts the suite in:user, root of a private user, network and mount namespace, with no real root, for a suite that builds network namespaces, as the root gives thelive_netcategory;none, or unset, the host's own. A host that gives no such namespace has the suite SKIPPED with the reason, and a member of the shared binary cannot sayuser(kiln-file §KN-K15e, test-system-revamp §TSR-F-9).test.guard, a switchonoff, in any.kiln, defaultoff. Whether the suite is a guard. Thegateprofile runs only guards, andlint --with-testsruns that profile.test.expected_passed, a number, in any.kiln. The number of passing cases a guard suite must report; any other number is a failure.test.expected_minimum_passed, a number, in any.kiln. The fewest passing cases a guard suite may report; a suite that grows needs no edit.install.prefix, a value, in the root.kilnonly, defaultusr/local. 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 itsbin.install.layer_bundle, a list, in the root.kilnonly. A foreign Vulkan validation layer for a build without its own, relative to the checkout or absolute: the upstream manifest and the library, such as/usr/share/vulkan/explicit_layer.d/VkLayer_khronos_validation.json /usr/lib/x86_64-linux-gnu/libVkLayer_khronos_validation.so, which--installlays out inbin/vulkan/explicit_layer.d, the library copied and the manifest'slibrary_pathwritten as./<library>; or one folder laid out so already, whose files it copies there. Ignored while thevulkanvalidationfeature builds the tree's own layer (kiln-file §KN-K21b, script-ports §SCP-D-6.2).output.dir, a value, in the root.kilnonly. Where the build tree is written.externals, a list, in the root.kilnonly. The external roots: installations outside the tree, Qt and the system, one quoted entry each ofname=<name> dir=<folder>, withinclude=<folder>(any number) andlib=<folder>relative to it where they are notincludeandlib; the root gives qbs's default and.kiln.locala machine's (kiln-file §KN-K25a).external.uses, a list, in any.kiln. The external roots this product compiles and links with: each one'sincludea system folder, and itslibsearched by every program that links the product (kiln-file §KN-K25b).windows.vc_dir, a value, in the root.kilnonly. 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, a value, in the root.kilnonly. The folder of the applications' window icons, relative to the checkout,<application>.svgeach, 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, a value, in the root.kilnonly. The folder of the DirectX Shader Compiler runtime,dxcompiler.dllanddxil.dll, which every Windows program carries beside itself; unset,dxc/x64inwindows.sysroot, whichwinvm runtimefills, or the newest Windows SDK's on a Windows host (kiln-file §KN-K25d). A machine's setting.windows.require_dxc, a switchonoff, in the root.kilnonly, defaulton. 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, a value, in the root.kilnonly. 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, a value, in the root.kilnonly. 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, a value, in the root.kilnonly. The password ofwindows.signing_pfx. A machine's setting, for.kiln.local.windows.sysroot, a value, in the root.kilnonly. The toolchain of a Windows build on another system: a folder in clang's /winsysroot layout,VC/Tools/MSVC/<version>andWindows Kits/10, whichwinvm sysrootcopies 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, a value, in the root.kilnonly. 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, asmmdebstrap --variant=extractmakes 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, a value, in the root.kilnonly. The Android NDK an Android build compiles against: its folder, holdingtoolchains/llvm/prebuilt/<host>/sysrootwith 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, a number, in the root.kilnonly, default28. 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, a value, in the root.kilnonly. The Android SDK an Android package is made with: its folder, holdingbuild-tools/<version>with aapt2, d8, zipalign and apksigner, andplatforms/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, a value, in the root.kilnonly. 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, a value, in the root.kilnonly. Retired 2026-10-11: QDoc's pages stay in the build root, and no command reads this key (api-reference §APD-A15). Known, so an older tree still reads (§KN-K11b).apidocs.classes, a value, in the root.kilnonly. Wherekiln apidocswrites the markdown class pages, relative to the checkout. Its parent is the reference's folder: the namespaces, the overview and the widget renders go beside it, each emptied first so a renamed class leaves no page behind (kiln-file §KN-K22a, api-reference §APD-A15).apidocs.minimum_pages, a number, in the root.kilnonly. The class pages below whichkiln apidocsfails: QDoc exits 0 on a smaller tree. Raised when a run earns it, never lowered to pass (kiln-file §KN-K22a).apidocs.defines, a list, in the root.kilnonly. 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, a value, in the root.kilnonly. The bundletool jarkiln package aabwrites an App Bundle with; unset, the newestbundletool-all-<version>.jarinandroid.sdk, where qbs's Android module looks for it (kiln-file §KN-K29g). A machine's setting.android.target_api, a number, in the root.kilnonly, default35. 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, a list, in the root.kilnonly. 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, a value, in the root.kilnonly. The serial of the devicekiln test --os androidruns the suites on, asadb deviceslists it; unset, the one device adb sees (kiln-file §KN-K29e). A machine's setting, for.kiln.local.android.keystore, a value, in the root.kilnonly. 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, a value, in the root.kilnonly. The password ofandroid.keystore; the debug key's,android, when that is unset. A machine's setting.android.key_alias, a value, in the root.kilnonly. The key inandroid.keystorethe package is signed with; the debug key's,androiddebugkey, when that is unset. A machine's setting.android.key_password, a value, in the root.kilnonly. The password ofandroid.key_alias; the debug key's,android, whenandroid.keystoreis unset. A machine's setting.run.checkout, a value, in the root.kilnonly. 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, a value, in the root.kilnonly.output.diras 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, a value, in the root.kilnonly. 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 byoption.<name>and tested by a section'soption.<name>=condition (kiln-file §KN-K24).edition.dir, a value, in the root.kilnonly. The edition the build brands its products with, the folder of itsedition.json, relative to the checkout; unset for the loud no-edition build (edition-data §ED-A1, kiln-file §KN-K12b).test.skip, a list, in the root.kilnonly. 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.capabilities, any ofd3d12elf-closureposixprocfsserial-ttyvulkan, in the root.kilnonly. The capabilities the target provides, whichtest.requiresnames: the root states them in itsos=sections, as qbs's TestConfig.capabilityTargets does (kiln-file §KN-K15d).test.select, a list, in the root.kilnonly, defaultall. Which suites a run ofkiln testkeeps:all,guardfor the guard suites,platformfor the suites withtest.platform_sensitive, 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;--categoryand--guard-onlywin over it (test-system-revamp §TSR-R-3).test.isolation, a switchonoff, in the root.kilnonly, defaultoff. Whether a run ofkiln testruns 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, a value, in the root.kilnonly, default1. How many suites a run ofkiln testruns at the same time: a count, orautofor half the cores. Each suite is still its own process. A suite that declarestest.exclusiveruns alone afterwards, and so does a suite that needs a display, unlesstest.display_server = xvfbgives each job a display of its own.--jobswins over it (test-system-revamp §TSR-R-5).test.link, one ofstaticblob, in any.kiln, defaultstatic. How a test program links the tree's libraries:static, each its own archives as an application does;blob, one shared object of every library a test links,testblob, so each test program is small and links in a second. Linux only: a Windows DLL exports at most 65 535 symbols, and an Android test is a shared object already. A test whose code calls a library oftest.blob_privatesaysstaticin its own.kiln(kiln-file §KN-K15b).test.blob_private, a list, in the root.kilnonly. The libraries the test blob holds but does not export: their symbols stay inside it, so a system library the process loads, such as Mesa's own LLVM, never binds to them. A test whose own code reaches one of them links its archives (kiln-file §KN-K15b).test.cap, a number, in the root.kilnonly, default900. Seconds a suite that declares no timeout of its own may run before it is ended; 0 waits.--max-timeoutwins over it (test-system-revamp §TSR-R-3).test.host_score, a value, in the root.kilnonly. This machine's host score, written in.kiln.local: its time for kiln's kernel over the reference host's, the Threadripper 3970X a suite'stimeout:is written for. Unset,kiln testmeasures it and keeps it until the host changes or 30 days pass;kiln calibratemeasures it now (kiln-file §KN-K15c).test.host_score_max, a number, in the root.kilnonly, default8. The largest factor a run ofkiln testmultiplies a suite's timeout, its QtTest watchdog and its waits by, so a hang on a slow host still ends. Theciprofile sets 4, so CI stays strict (kiln-file §KN-K15c).test.sanitize_factor, a number, in the root.kilnonly, default3. In a sanitized build, the factor a run ofkiln testmultiplies the host's factor by, aftertest.host_score_maxcapped it: AddressSanitizer and ThreadSanitizer run code several times slower (kiln-file §KN-K15c, §KN-K31).test.coverage_factor, a number, in the root.kilnonly, default2. In a coverage build, the factor a run ofkiln testmultiplies the host's factor by, aftertest.host_score_maxcapped it, astest.sanitize_factorin a sanitized build (build-class §BCL-3.3).test.report, any ofjsonjunit, in the root.kilnonly. The result files a run ofkiln testwrites into its report folder:jsonfor tests.json,junitfor tests.junit.xml.--reportnames the folder (test-system-revamp §TSR-R-4).test.display, one ofautoonoff, in the root.kilnonly, defaultauto. Which suites run on the display:autothe suites withtest.real_platform,onevery suite,offnone, and a suite withtest.real_platformis SKIPPED then. It is SKIPPED too on a host where no display answers, unlesstest.display_server = xvfbstarts one.--displaywins over it (test-system-revamp §TSR-R-3).test.display_server, one ofservicexvfb, in the root.kilnonly, defaultservice. Which X server a suite that opens windows uses:servicethe one the test-display unit names, as libtest finds it;xvfbanXvfbfor each of the run's jobs, whichkiln teststarts before the run and stops after it, whose display each suite of that job gets as--test-display :<n>.--xvfbnames the program (script-ports §SCP-D-4.2, test-system-revamp §TSR-R-5).test.vulkan_icd, one oflavapipe, in the root.kilnonly. The Vulkan driver every suite gets:lavapipe, Mesa's software Vulkan, whoselvp_icd*.jsonkiln finds in the Vulkan loader's folders and gives each suite asVK_DRIVER_FILESandVK_ICD_FILENAMES; unset, the loader's own choice.--vulkan-icd-dirnames the folder (script-ports §SCP-D-4.2).test.audio, one ofnull, in the root.kilnonly. Where the suites' sound goes:null, a PulseAudio null sinkoctomy_test_nullthatkiln testloads withpactlbefore the run and unloads after it, given to each suite asPULSE_SINK; unset, the session's own sink. Withoutpactlthe run warns and goes on.--pactlnames the program (script-ports §SCP-D-4.2).package.version, a value, in the root.kilnonly, default0.0.0-dev. The release version the build stamps into the products that print their identity, asOC_PACKAGE_VERSION; a release build sets it, a developer's is the default (kiln-file §KN-K18b).package.name, a value, in the root.kilnonly, defaultoctomy. The Debian package's name (§KN-K23a).package.base, a value, in the root.kilnonly, defaultoctomy. 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, a value, in the root.kilnonly. The package's maintainer, a name and an address in angle brackets.package.homepage, a value, in the root.kilnonly. The project's home page, in the control file and the metainfo.package.source_url, a value, in the root.kilnonly. Where the source is, in the copyright file'sSource:.package.copyright, a value, in the root.kilnonly. The copyright file'sCopyright:line: years and holder.package.tagline, a value, in the root.kilnonly. The words after the brand in the control file's summary line,<brand> - <tagline>;{brand}is the edition's brand.package.description, a list, in the root.kilnonly. 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, a list, in the root.kilnonly. Edition packages from before the side-by-side layout, which the package Breaks when older thanpackage.side_by_side_since.package.side_by_side_since, a value, in the root.kilnonly. The first version of the side-by-side layout; an older legacy package is broken by this one.package.alternatives_priority, a number, in the root.kilnonly, default50. The auto-mode priority of this edition's bare command names in update-alternatives.package.section, a value, in the root.kilnonly, defaultmisc. The Debian section.package.priority, a value, in the root.kilnonly, defaultoptional. The Debian priority.package.license, a value, in the root.kilnonly. The project's license as an SPDX identifier, for AppStream; the copyright file gets its DEP-5 name.package.metadata_license, a value, in the root.kilnonly, defaultCC0-1.0. The license of the AppStream metainfo files themselves.package.ship, a list, in the root.kilnonly. The applications a package ships;kiln package --shipnarrows it for one run.package.plugin_categories, a list, in the root.kilnonly. The Qt plugin categories the Debian package carries; empty lets the closure derive them from the Qt modules the binaries link. A category left out is a plugin the application cannot load.package.fallback_depends, a list, in the root.kilnonly. The Depends used only where dpkg-shlibdeps names nothing; a Debian Qt package is never taken from it.package.title, a value, in any.kiln. An application's menu name after the brand,<brand> <title>; an application without one gets no launcher and no metainfo.package.comment, a value, in any.kiln. An application's menu tooltip and AppStream summary.package.categories, a value, in any.kiln. An application's freedesktop menu categories, each followed by;.package.about, a list, in any.kiln. An application's AppStream description, one quoted paragraph each; the first is a software centre's introduction.qt.qmake, a value, in the root.kilnonly. The qmake of the Qt installation this machine builds with;qmake -querygives the rest (§KN-BG11a).vendor.trees, a list, in the root.kilnonly. The pinned trees the checkout builds from, one quoted entry each ofname=<pin section> pin=<pin file> tree=<folder>, relative to the checkout, whichkiln vendorandkiln fetchmaterialise (§KN-K13c).cache.dir, a value, in the root.kilnonly. Where the vendored-source cache lives.build.jobs, a number, in the root.kilnonly. 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).build.techniques, a value, in the root.kilnonly. The techniques a build uses when it names none with --techniques: a comma-separated list of objects, backend, snapshots, link and reach, or trusted for every technique in Sampled or Trusted, or none, which reads and writes no cache. Unset, trusted (kiln-fine-cache §KF-M8).clean.roots, a list, in the root.kilnonly. The folders whose subfolderskiln clean --reportlists as build storage, with their owner, size on disk and last write (script-ports §SCP-D-8). A machine's setting, for.kiln.local.clean.keep, a list, in the root.kilnonly. The folderskiln cleannever lists and never deletes, such as the compiler cache, which is what makes a rebuild cheap (script-ports §SCP-D-8). A machine's setting, for.kiln.local.
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. A path that holds no suite fails the
run with exit code 4, as a misspelled profile fails it. 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 is exclusive runs alone, after them. So does a suite that needs a display, unless test.display_server = xvfb gives each job a display of its own. 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. After it installs a package, kiln puts the fixtures of the package's suites in the package's own files folder, /data/user/0/<package>/files/project: one tar archive, pushed to /data/local/tmp and extracted through run-as, with test/fixtures/ once for the run and the folder test/<suite>/ of each suite. Each suite gets --project-root with that folder, so fixturePath() finds its fixtures there. If the transfer fails, kiln says so once on stderr, and the suites run without the fixtures and without --project-root |
--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 |
--xvfb <program> |
The X server that test.display_server = xvfb starts. Default: Xvfb on PATH |
--vulkan-icd-dir <dir> |
The folder where test.vulkan_icd = lavapipe finds lvp_icd*.json. Default: the folders of the Vulkan loader |
--pactl <program> |
The program that test.audio = null loads and unloads the null sink with. Default: pactl on PATH |
Host-scaled timeouts
A suite's test.timeout is seconds on the reference host, the Threadripper
3970X that the suites were written on. A slower host gives each suite more
time, in proportion:
kiln testuses this host's score: the time of a fixed piece of work here, divided by its time on the reference host. A score of 2 means that this host takes twice as long.- The factor is the score rounded up to a quarter. It is at least 1, so a
faster host never gets tighter limits. It is at most
test.host_score_max, 8 by default and 4 in theciprofile, so a hang still ends. - The suite's limit and the cap are multiplied by the factor. The QtTest watchdog follows the limit.
- A suite gets
--time-scale <factor>when the factor is over 1. A suite onlibtestscales its waits withtest::utility::scaled(ms).
The host factor does not scale a bound that a case asserts, such as a speed
budget. Assert a speed budget as a ratio of CPU times to the reference work,
with referencework::relativeTime(). See
libreferencework and
Write a test → A speed budget.
The first run on a host measures the score, which takes about 15 seconds, and
keeps it in kiln/host-score.json in the user's cache folder, one score for
each --jobs count. A run measures again when the host, its thread count, its
memory, the Qt version or the system kernel changes, or after 30 days.
test.host_score in .kiln.local pins a score, and no measurement runs. On an
Android device the timeouts stay as declared.
The run prints the score and the factor on stderr, for example host score 4.40 (kept, ...): every timeout x 4.5, at most 8. A TIMEOUT names both
limits: exceeded timeout 270s (60s on the reference host x 4.5 for this host). tests.json holds them in host.
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, were skipped for a capability, were skipped for want
of a display, and were skipped for want of a user namespace (each only when
there are some), and were left out by the selection. A suite whose
test.requires names a capability that the root's test.capabilities does not
give for this target is SKIPPED, also when its path names it. A suite with
test.real_platform in a run with test.display = off is SKIPPED too, also
when its path names it. So is a suite that says test.namespace = user on a
host that gives no user namespace, with the host's reason. The exit code is 0
when every selected suite kept its contract and 1 otherwise; 2 for a wrong
command line, 3 for an input that kiln cannot use, such as an unknown profile
or an unreadable build request, 4 when a path holds no suite, when the profile
asks for Xvfb or lavapipe and the machine has none, or when no suite is left to
run, and 5 when Xvfb does not start.
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, times the host's factor (Host-scaled timeouts). 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 |
VK_DRIVER_FILES, VK_ICD_FILENAMES |
Only with test.vulkan_icd = lavapipe: the lavapipe manifests that kiln found, separated by the list separator of the system (: on Linux). The Vulkan loader takes its driver only from its environment. A newer loader reads the first variable, and a loader older than the 1.3.207 headers reads only the second |
PULSE_SINK |
Only with test.audio = null: octomy_test_null. The PulseAudio client sends the suite's sound to that sink, and the default sink of the session does not change |
LLVM_PROFILE_FILE |
Only in a coverage build (compiler.coverage = on): <report>/profiles/%m.profraw. LLVM's profile runtime in each program and shared library writes its profile there when the process ends. %m gives each module its own file. See Coverage |
With test.display_server = xvfb, each suite also gets the argument
--test-display :<n>, the display of the Xvfb that kiln started. kiln does not
set DISPLAY: libtest chooses the display and the platform itself.
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
test.host_score_max = 4
[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
[profile=gpu-sw]
test.display = on
test.select = testConstructViewportProducer testViewportParity
test.display_server = xvfb
test.vulkan_icd = lavapipe
The gpu and gpu-sw profiles name more suites than this extract shows.
test.skip is set once at the root, and every profile takes it. The gpu-sw
section of the root .kiln is active since 2026-10-11. A kiln older than its
keys refuses a key that it does not know, and then reads nothing of the file.
| Key | Values | Default |
|---|---|---|
test.skip |
categories | the root's value |
test.select |
all, guard, platform, categories, suite names |
all |
test.cap |
seconds | 900 |
test.host_score_max |
a number | 8 |
test.jobs |
a count, or auto |
1 |
test.report |
json, junit |
none |
test.display |
auto, on, off |
auto |
test.isolation |
on, off |
off |
test.display_server |
service, xvfb |
service |
test.vulkan_icd |
lavapipe |
none |
test.audio |
null |
none |
What each key does:
test.skip— The categories that the run leaves out. Each suite of one isSKIPPED.test.select— The suites that the run keeps.guardkeeps the guard suites,platformthe suites withtest.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— The time a suite that declares no timeout of its own may run. 0 waits.test.host_score_max— The largest factor by which a slower host multiplies the timeouts. See Host-scaled timeouts.test.jobs— The suites that run at the same time.autois half the cores, at least 1.test.report— The result files to write. Without--report, they go intotest-results/of the build folder.test.display— Which suites run on the display.autogives the display to the suites withtest.real_platform,onto every suite, andoffto none: a suite withtest.real_platformis thenSKIPPED.test.isolation— Runs each member of the shared binary twice, in its shard and then alone, and fails a member whose two verdicts differ.test.display_server— The X server for the windows of the suites.serviceis the display that the test-display unit names, which libtest finds.xvfbstartsXvfb -displayfd 1before the run, gives each suite--test-display :<n>, and stops Xvfb after the run.test.vulkan_icd— The Vulkan driver of the suites.lavapipefindslvp_icd*.jsonin the folders of the Vulkan loader and gives each suiteVK_DRIVER_FILESandVK_ICD_FILENAMES. No manifest fails the run with exit code 4.test.audio— The sink for the sound of the suites.nullloadsmodule-null-sinkasoctomy_test_nullwithpactlbefore the run, gives each suitePULSE_SINK, and unloads the module after the run. A sink that is already there is used and left alone. Withoutpactl, the run writes a warning and goes on.
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.test.namespace = userstarts the suite as root of a private user, network and mount namespace, with no real root: user id 0, its own network withloup, a writable/run/netns, the old/run/userstill reachable, and/usr/sbinand/sbinon itsPATH. The root gives it to everylive_netsuite with[category=live_net];test.qbshas no property for it. A host that gives no such namespace has the suiteSKIPPEDwith the reason, named or not, and the count line addsN skipped for want of a user namespace. A member of the shared binary cannot sayuser: that is an error.
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", "gpu-sw", "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,
"host": { "score": 4.4, "factor": 4, "maximum": 4, "source": "kept", "hostName": "honeybadger32", "threads": 4, "jobs": 2, "measured": "2026-10-11T08:00:00Z" },
"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 |
host |
The host score that the timeouts were scaled by: score, factor, maximum (test.host_score_max), source (measured, kept, pinned or none), and for a measured or kept score hostName, threads, jobs and measured. Absent in a run on an Android device. See Host-scaled timeouts |
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.
Coverage
A coverage build counts which lines and functions of our code the tests run. It is LLVM's source-based coverage, built and read by kiln alone. Linux x86-64 only.
- Use a build folder of its own. In its checkout's
.kiln.local, setoutput.dirto a new folder andoption.enableCoverage = on. - Run
kiln vendor, if the checkout does not havesrc/libs/libllvm/llvm-src/compiler-rt/lib/profile. - Run
kiln build. The debug variant instruments every product but the vendored libraries, and builds the profile runtime into<build root>/clang-rt. - Run
kiln test --report <dir>, with the suites and the profile you want. Each suite writes its profile into<dir>/profiles. - Run
kiln coverage --report <dir>. It prints the table and writescoverage.md,coverage.jsonandcoverage.profdatainto<dir>.
| Column | Meaning |
|---|---|
| Library | A folder under src/libs |
| Lines | The lines that hold code, in the library's own source files and headers |
| Lines run | The lines that ran at least once in the run |
| Functions | The functions that start in the library's files. A template counts once, whatever its instantiations |
| Functions run | The functions that ran at least once |
The table leaves out a file under a prefix of
integration/lint/vendored-paths.txt, a file generated into the build folder,
and a file outside the checkout. A suite that kiln test stops at its timeout
writes no profile, so its lines count as not run.