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 #includes 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 $.