Tint makes use of code generation tooling to emit source code and build files used to build Tint.
All code is generated with ./tools/run gen
.
The generator uses heavy use of Go's text/template package. This is augmented with the functions declared in tools/src/template/template.go
, and the data types provided by the tooling.
The generator will scan all the Tint source directories to produce BUILD.gn
and BUILD.cmake
files. These files contain the per-directory targets, conditionals and inter-target dependency information which is labour-intensive to maintain by hand.
The bulk of the build generator logic is in the file: tools/src/cmd/gen/build/build.go
There are 8 kinds of build target:
cmd
targets are executables.lib
targets are libraries used in production code, and can also be used as a dependency by any other target kind .test
targets are libraries used by Tint unittests. Must not be used by production code.test_cmd
are test executables.bench
targets are libraries used by Tint benchmarks. Must not be used by production code.bench_cmd
are benchmark executables.fuzz
targets are libraries used by Tint fuzzers. Must not be used by production code.fuzz_cmd
are fuzzer executables.The build generator uses a file naming convention based on the file name before the extension to classify each source file to a single target kind.
test
or with a _test
suffix are classed as test
library targets. parser_test.cc
.bench
or with a _bench
suffix are classed as bench
library targets. writer_bench.cc
.fuzz
or with a _fuzz
suffix are classed as fuzz
library targets. writer_fuzz.cc
.main
are classed as executable targets. These typically exist under src/tint/cmd
. cmd/tint/main.cc
.main_test
are classed as test executable targets. These typically exist under src/tint/cmd/test
. cmd/test/main_test.cc
.main_bench
are classed as benchmark executable targets. These typically exist under src/tint/cmd/bench
. cmd/benchmark/main_bench.cc
.main_fuzz
are classed as fuzzer executable targets. These typically exist under src/tint/cmd/fuzz
. cmd/benchmark/main_bench.cc
.lib
targets. parser.cc
.Each source directory can have at most one lib
, test
, test_main
, bench
, bench_main
or cmd
target.
The graph of target dependencies must be acyclic (DAG).
Target dependencies are automatically inferred from #include
s made by the source files. Additional target dependencies can be added with the use of a BUILD.cfg
file.
All external dependencies must be declared in src/tint/externals.json
.
The syntax of this file is:
{ "external-target-name": { "IncludePatterns": [ /* A list of #include path patterns that refer to this external target. You may use the '*' wildcard for a single directory, or '**' as a multi-directory wildcard. */ "myexternal/**.h", ], /* An optional build condition expression to wrap all uses of this external dependency */ "Condition": "expression", }, /* Repeat the above for all external targets */ }
GEN_BUILD
directivesSource and build files can be annotated with special directives in comments to control the build file generation.
Directive | Description |
---|---|
GEN_BUILD:IGNORE_FILE | Add to a source file to have the file ignored by the generator Example: // GEN_BUILD:IGNORE_FILE |
GEN_BUILD:IGNORE_INCLUDE | Apply to the end of a #include in a source file to ignore this include for dependency analysis Example: #include "foo/bar.h" // GEN_BUILD:IGNORE_INCLUDE |
GEN_BUILD:CONDITION( cond) | Applies the build condition for this source file. Example: // GEN_BUILD:CONDITION(is_linux) |
GEN_BUILD:DO_NOT_GENERATE | Prevents the BUILD.* file from being generated. Example: # GEN_BUILD:DO_NOT_GENERATE |
BUILD.cfg
filesA source directory may have an optional BUILD.cfg
JSON file. The syntax of this file is:
{ /* Build condition to apply to all targets of this directory. */ "Condition": "cond", /* Options for the 'lib' target */ "lib": { /* see TargetConfig */ }, /* Options for the 'test' target */ "test": { /* see TargetConfig */ }, /* Options for the 'bench' target */ "bench": { /* see TargetConfig */ }, /* Options for the 'cmd' target */ "cmd": { /* see TargetConfig */ }, }
All fields are optional.
The syntax of TargetConfig
is:
{ /* An override for the output file name for the target */ "OutputName": "name", /* An additional condition for building this target */ "Condition": "cond", "AdditionalDependencies": { "Internal": [ /* A list of target name patterns that should in added as dependencies to this target. You may use the '*' wildcard for a single directory, or '**' as a multi-directory wildcard. */ ], "External": [ /* A list of external targets that should in added as dependencies to this target. Must match an external dependency declared in src/tint/externals.json */ ] }, }
All fields are optional.
The build generator will emit a BUILD.
ext file in each source directory, for each BUILD.
ext.tmpl
file found in tools/src/cmd/gen/build
.
The template will be passed the Directory
as $
.