Build Clang TableGen Sources with clang-tblgen-18
Your build stops with a missing generated .inc file, and the tool that makes it is clang-tblgen-18, which may not even be installed. This guide checks that it exists, parses a Clang TableGen source file without writing generated code, then runs a selected Clang backend into a named output file.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow 15 to 30 minutes if the LLVM source tree is already present. This is a developer tool, not a normal Clang compiler command.
1. Check the executable and package version
The manual describes clang-tblgen as a translator for compiler-related .td files. Its name is easy to confuse with the other TableGen programs shipped by LLVM, and a package can contain the manual without putting this executable on your PATH.
$ command -v clang-tblgen-18
$ dpkg-query -W -f='${Package} ${Version}\n' llvm-18
llvm-18 18.1.3-1ubuntu1
$ clang-tblgen-18 -version
A working installation prints a path and a version line. The final command uses the documented -version option and does not read a source file.
Warning
If command -v prints nothing, stop here. Do not substitute llvm-tblgen-18 for a Clang generator: they share the TableGen machinery but expose different backend options.
On the machine used to prepare this guide, llvm-18 is installed at version 18.1.3, but /usr/bin/clang-tblgen-18 is absent. The installed Clang man page is therefore reference material, not proof that the executable is available. Find which package should provide the binary through your normal package management before continuing. Do not create a symlink to an unrelated TableGen executable.
2. Locate the source and include directories
TableGen processes one input file and follows included .td files. Use a source checkout that matches the LLVM and Clang revision you are building. Pass include directories with -I; the option accepts a full or partial directory path.
$ LLVM_SRC=/path/to/llvm-project/llvm
$ CLANG_SRC=/path/to/llvm-project/clang
$ test -r "$CLANG_SRC/include/clang/Basic/Diagnostic.td" && echo input-readable
input-readable
$ test -d "$LLVM_SRC/include" && test -d "$CLANG_SRC/include" && echo includes-found
includes-found
Replace both placeholder paths with real directories. The source file above is an example of a Clang-owned TableGen input, not something the installed binary can invent. If it is missing, check out the matching source package or find the particular .td file your build names. Do not guess at a nearby file.
3. Parse the source without generating output
Use -null-backend for a first smoke test. It parses the sources and builds the records but runs no backend, so it tests paths, includes and TableGen syntax without touching a generated file.
$ clang-tblgen-18 -null-backend \
-I "$LLVM_SRC/include" \
-I "$CLANG_SRC/include" \
"$CLANG_SRC/include/clang/Basic/Diagnostic.td"
$ printf 'exit status: %s\n' "$?"
exit status: 0
Checkpoint
Success may print nothing useful on standard output. The exit status is the signal, and you want 0.
A missing include normally means an incorrect -I directory or a source checkout from a different LLVM revision. Fix the paths first. Adding random system include directories can make a mismatched tree appear to work while producing the wrong records.
4. Select a Clang backend and output file
A parse alone produces no C++ or other generated artefact. The Clang-specific options in this man page include generators for diagnostics, attributes, declarations, statements and types. Choose the backend that the build rule you are reproducing requires. For example, -gen-clang-diags-defs asks for Clang diagnostic definitions.
$ mkdir -p /tmp/clang-tblgen-test
$ clang-tblgen-18 \
-gen-clang-diags-defs \
-I "$LLVM_SRC/include" \
-I "$CLANG_SRC/include" \
-o /tmp/clang-tblgen-test/DiagnosticDefs.inc \
"$CLANG_SRC/include/clang/Basic/Diagnostic.td"
$ test -s /tmp/clang-tblgen-test/DiagnosticDefs.inc && echo generated
generated
The output filename is yours to choose. The -o option accepts a filename, while -o - sends generated output to standard output. Treat generated files as build artefacts, and do not point -o at a tracked source file unless the project build explicitly requires that path.
Warning
A shell redirection or an existing -o destination can overwrite useful work. Use a temporary output as above, inspect it, then copy or move it into the build directory only when the build instructions say so. If this test produced an unwanted file, remove only the known temporary path:
$ rm -- /tmp/clang-tblgen-test/DiagnosticDefs.inc
That removal is irreversible. The command does not change the source checkout, and rerunning the generation command recreates the temporary artefact.
5. Make repeatable builds quieter
Use -write-if-changed when a build keeps regenerating the same output. It writes the output file only when it is new or different, which avoids needless timestamp changes. Keep the backend, include paths, input file and output path identical when comparing runs.
$ clang-tblgen-18 \
-gen-clang-diags-defs \
-write-if-changed \
-I "$LLVM_SRC/include" \
-I "$CLANG_SRC/include" \
-o /tmp/clang-tblgen-test/DiagnosticDefs.inc \
"$CLANG_SRC/include/clang/Basic/Diagnostic.td"
Tip
For build-system integration, add -d /path/to/dependencies.d to request a dependency filename. That output is separate from the generated C++ file, so check the syntax with the build system that consumes it rather than assuming.
6. Inspect records and diagnose failures
To see what was parsed rather than a backend's generated file, use -print-records or -print-detailed-records. They write reports to standard output unless you redirect them. For tooling that needs structured data, -dump-json prints a JSON representation of the records.
$ clang-tblgen-18 -dump-json \
-I "$LLVM_SRC/include" \
-I "$CLANG_SRC/include" \
"$CLANG_SRC/include/clang/Basic/Diagnostic.td" \
> /tmp/clang-tblgen-test/diagnostic-records.json
$ test -s /tmp/clang-tblgen-test/diagnostic-records.json && echo records-captured
records-captured
If parsing fails, read the first diagnostic carefully:
- File not found. A path problem.
- Unknown class or record. Often the input and included sources come from different revisions.
- Unsupported
-gen-clang-...option. The executable does not match the Clang source tree, or the option was copied from another LLVM release.
Confirm the installed binary with -version and compare it with the source checkout before changing flags.
Done means
- Tool found.
clang-tblgen-18 -versionresolves to the intended executable, or you have identified the package gap that blocks use. - Inputs readable. The
.tdfile and the matching LLVM and Clang include directories can be read. - Parse passes.
-null-backendparses the source with exit status 0 before generation is attempted. - Deliberate output. The selected Clang backend writes to a chosen path and the output is non-empty.
- Clean removal. Temporary artefacts can go without touching the source checkout or tracked build inputs.