| # Code generation | |
| 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](https://pkg.go.dev/text/template) | |
| package. This is augmented with the functions declared in [`tools/src/template/template.go`](../../tools/src/template/template.go), and the data types provided by the tooling. | |
| ## Build file generation | |
| 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`](../../tools/src/cmd/gen/build/build.go) | |
| ### Targets | |
| 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. | |
| * Source files named `test` or with a `_test` suffix are classed as `test` library targets. \ | |
| Example: `parser_test.cc`. | |
| * Source files named `bench` or with a `_bench` suffix are classed as `bench` library targets. \ | |
| Example: `writer_bench.cc`. | |
| * Source files named `fuzz` or with a `_fuzz` suffix are classed as `fuzz` library targets. \ | |
| Example: `writer_fuzz.cc`. | |
| * Source files with the name `main` are classed as executable targets. | |
| These typically exist under `src/tint/cmd`. \ | |
| Example: `cmd/tint/main.cc`. | |
| * Source files with the name `main_test` are classed as test executable targets. | |
| These typically exist under `src/tint/cmd/test`. \ | |
| Example: `cmd/test/main_test.cc`. | |
| * Source files with the name `main_bench` are classed as benchmark executable targets. | |
| These typically exist under `src/tint/cmd/bench`. \ | |
| Example: `cmd/benchmark/main_bench.cc`. | |
| * Source files with the name `main_fuzz` are classed as fuzzer executable targets. | |
| These typically exist under `src/tint/cmd/fuzz`. \ | |
| Example: `cmd/benchmark/main_bench.cc`. | |
| * All other files are considered `lib` targets. \ | |
| Example: `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](#buildcfg-files). | |
| ### External dependencies | |
| All external dependencies must be declared in [`src/tint/externals.json`](../../src/tint/externals.json). | |
| The syntax of this file is: | |
| ```json | |
| { | |
| "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` directives | |
| Source 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 <br> 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 <br> Example: `#include "foo/bar.h" // GEN_BUILD:IGNORE_INCLUDE` | | |
| | `GEN_BUILD:CONDITION(`_cond_`)` | Applies the build condition for this source file. <br> Example: `// GEN_BUILD:CONDITION(is_linux)` | | |
| | `GEN_BUILD:DO_NOT_GENERATE` | Prevents the `BUILD.*` file from being generated. <br> Example: `# GEN_BUILD:DO_NOT_GENERATE` | | |
| ### `BUILD.cfg` files | |
| A source directory may have an optional `BUILD.cfg` JSON file. The syntax of this file is: | |
| ```json | |
| { | |
| /* 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: | |
| ```json | |
| { | |
| /* 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. | |
| ## Templates | |
| 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`](../../tools/src/cmd/gen/build). | |
| The template will be passed the [`Directory`](../../tools/src/cmd/gen/build/directory.go) as `$`. |