Regenerate the API reference

One qbs command writes the class pages, and two numbers fail the build when the run is wrong

The API reference is one markdown page per documented C++ class, struct and namespace. QDoc reads the docstrings in src/, and the apidocs tool turns QDoc's DocBook pages into markdown. The pages are build output, they are not tracked, and a fresh clone does not have them.

Do not hand-edit a file under content/doc/published/reference/api/classes/, namespaces/ or overview/. The next run deletes those folders first.

The whole routine

Run this from the repository root:

kiln apidocs

That is the whole command. It takes about seven minutes on a loaded machine. On the qbs path, the second path until qbs retires, the qbs product does the same steps: qbs build project.buildApiDocs:true --products api-reference.

What the run does

The product is api-reference, in integration/qbs/apidocs.qbs, and kiln apidocs runs the same steps in the same order:

  1. Derive the configuration. apidocs config walks the tree and writes generated.qdocconf into the build directory. It lists every qbs product root that holds first-party C++, every vendored directory to exclude, every Qt include directory, and the directory the widget screenshots live in. Beside it, generated-externalpages.qdoc registers every published page as a link target, so a docstring can say \l {Communication System Architecture}{…} and a renamed page becomes a warning. Nothing in either file is hand-written.
  2. Wipe QDoc's output. The rule deletes QDoc's output folder in the build directory, so that a renamed class leaves no orphan page behind.
  3. Render the widgets. The rule deletes content/doc/published/reference/api/images/ and runs uiautomation -platform offscreen --generate-screenshots into it. A class page that shows its widget finds the image there. The build makes uiautomation first, so no manual capture comes before a run.
  4. Generate. QDoc reads generated.qdocconf, which includes the tracked content/doc/internal/qdoc/octomy.qdocconf. It writes DocBook pages into docbook/ and HTML into html/, both in the build directory. Nothing publishes the HTML: QDoc writes its index, octomy.index, only with its HTML generator, and only the HTML generator reports a broken link.
  5. Count the pages. The rule counts the DocBook pages and fails below the floor.
  6. Project to markdown. apidocs project turns each DocBook page into a markdown page under classes/, namespaces/ or overview/, which the website and the application's help system both read. It takes the declaring header of each class from QDoc's index.

Read the output

The run prints the page count and one summary line from the projection:

api-reference: 1165 class pages in .../qdoc/docbook
1098 class pages, 65 namespace pages and 1 other pages projected, 102 showing a live widget; 161 links left as text

The first number is the one the floor reads. "Links left as text" are links QDoc writes to a class that has no \class block, and so no page: a base class or a parameter type. apidocs project --verbose names each such class once. Everything else in the log is a QDoc warning.

When the page floor fails

The rule refuses a smaller tree:

api-reference: QDoc generated 812 class pages, below the floor of 1010.

The generator exits 0 on a smaller tree, so this check is what notices. There are three usual causes:

  • A vendored tree entered the parse. QDoc builds one precompiled header from every header directory it is given, and one vendored tree poisons it for every file. This cost 545 class pages and 24 minutes per run until 2026-10-07.
  • A product root left the plan, because its last first-party source went away.
  • A library was renamed, and its pages are now under different names.

Diagnose it without running QDoc again:

kiln build src/tools/apidocs
debug/apidocs/apidocs check --repo . --verbose

debug/apidocs/apidocs is the tool's path with no output.dir (The build convention).

check writes nothing. It prints how many roots are read, which roots hold no first-party C++, which directories are excluded, and any prefix in integration/lint/vendored-paths.txt that matches nothing on disk. It fails when a directory named *-src or vendor* is not covered by that file, which is the exact shape of the defect above.

When the warning ceiling fails

QDoc counts its own warnings and exits with the count when the count rises above the ceiling:

QDoc: error: Documentation warnings (309) exceeded the limit (308) for 'OctoMY'.

Read that message, not the exit code. The exit status is truncated to 8 bits, so a count of 1,448 would arrive as 168.

The fix is to fix the warnings, not to raise the number. Find them with grep:

grep -a '(qdoc) warning:' <build log>

Use grep -a. The log carries lines long enough that grep treats the file as binary, prints nothing, and exits 1. A count taken without -a reads as zero warnings.

The ceiling is warninglimit in content/doc/internal/qdoc/octomy.qdocconf. It moves down in the commit that earns it, and it does not move up.

Where the two halves of the configuration live

Half File Holds
Tracked octomy.qdocconf What a person decides: the project name, the Qt modules, the output formats, the warning ceiling, the one suppression
Generated generated.qdocconf What a machine knows: every directory, every exclusion, every Qt include path

The paths of the two files:

content/doc/internal/qdoc/octomy.qdocconf
<build>/api-reference/generated.qdocconf

The tracked half carries no directory list and no absolute path, and test/testApiReferenceConfig fails the build if either comes back. That guard runs in every test run, so a hand-written list cannot creep back one library at a time. It drifted to 99 of 193 product roots the last time it was hand-maintained.

Publishing

The website export, uiautomation --export-site, copies what is on disk. Regenerate the reference before the export, or the release publishes nothing where the reference should be.

Topics
howto development api qdoc documentation
See also