1*8975f5c5SAndroid Build Coastguard Worker# Writing GN Templates 2*8975f5c5SAndroid Build Coastguard WorkerGN and Ninja are documented here: 3*8975f5c5SAndroid Build Coastguard Worker* GN: https://gn.googlesource.com/gn/+/main/docs/ 4*8975f5c5SAndroid Build Coastguard Worker* Ninja: https://ninja-build.org/manual.html 5*8975f5c5SAndroid Build Coastguard Worker 6*8975f5c5SAndroid Build Coastguard Worker[TOC] 7*8975f5c5SAndroid Build Coastguard Worker 8*8975f5c5SAndroid Build Coastguard Worker## Things to Consider When Writing Templates 9*8975f5c5SAndroid Build Coastguard Worker### Inputs and Depfiles 10*8975f5c5SAndroid Build Coastguard WorkerList all files read (or executed) by an action as `inputs`. 11*8975f5c5SAndroid Build Coastguard Worker * It is not enough to have inputs listed by dependent targets. They must be 12*8975f5c5SAndroid Build Coastguard Worker listed directly by targets that use them, or added by a depfile. 13*8975f5c5SAndroid Build Coastguard Worker * Non-system Python imports are inputs! For scripts that import such modules, 14*8975f5c5SAndroid Build Coastguard Worker use [`action_with_pydeps`] to ensure all dependent Python files are captured 15*8975f5c5SAndroid Build Coastguard Worker as inputs. 16*8975f5c5SAndroid Build Coastguard Worker 17*8975f5c5SAndroid Build Coastguard Worker[`action_with_pydeps`]: https://cs.chromium.org/chromium/src/build/config/python.gni?rcl=320ee4295eb7fabaa112f08d1aacc88efd1444e5&l=75 18*8975f5c5SAndroid Build Coastguard Worker 19*8975f5c5SAndroid Build Coastguard WorkerTo understand *why* actions must list all inputs directly, you need to 20*8975f5c5SAndroid Build Coastguard Workerunderstand ninja's "restat" directive, which is used for all GN `action()`s. 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard WorkerFrom https://ninja-build.org/manual.html: 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker> if present, causes Ninja to re-stat the command’s outputs after execution of 25*8975f5c5SAndroid Build Coastguard Worker> the command. Each output whose modification time the command did not change 26*8975f5c5SAndroid Build Coastguard Worker> will be treated as though it had never needed to be built. This may cause the 27*8975f5c5SAndroid Build Coastguard Worker> output’s reverse dependencies to be removed from the list of pending build 28*8975f5c5SAndroid Build Coastguard Worker> actions. 29*8975f5c5SAndroid Build Coastguard Worker 30*8975f5c5SAndroid Build Coastguard WorkerSo, if your action depends on target "X", and "X" does not change its outputs 31*8975f5c5SAndroid Build Coastguard Workerwhen rebuilt, then ninja will not bother to rebuild your target. 32*8975f5c5SAndroid Build Coastguard Worker 33*8975f5c5SAndroid Build Coastguard WorkerFor action inputs that are not computable during "gn gen", actions can write 34*8975f5c5SAndroid Build Coastguard Workerdepfiles (.d files) to add additional input files as dependencies for 35*8975f5c5SAndroid Build Coastguard Workersubsequent builds. They are relevant only for incremental builds since they 36*8975f5c5SAndroid Build Coastguard Workerwon't exist for the initial build. 37*8975f5c5SAndroid Build Coastguard Worker * Depfiles should not list files that GN already lists as `inputs`. 38*8975f5c5SAndroid Build Coastguard Worker * Besides being redundant, listing them also makes it harder to remove 39*8975f5c5SAndroid Build Coastguard Worker inputs, since removing them from GN does not immediately remove them from 40*8975f5c5SAndroid Build Coastguard Worker depfiles. 41*8975f5c5SAndroid Build Coastguard Worker * Stale paths in depfiles can cause ninja to complain of circular 42*8975f5c5SAndroid Build Coastguard Worker dependencies [in some cases](https://bugs.chromium.org/p/chromium/issues/detail?id=639042). 43*8975f5c5SAndroid Build Coastguard Worker * Use [`action_helpers.write_depfile()`] to write these. 44*8975f5c5SAndroid Build Coastguard Worker 45*8975f5c5SAndroid Build Coastguard Worker[`action_helpers.write_depfile()`]: https://source.chromium.org/chromium/chromium/src/+/main:build/action_helpers.py?q=symbol:%5Cbwrite_depfile 46*8975f5c5SAndroid Build Coastguard Worker 47*8975f5c5SAndroid Build Coastguard Worker### Ensuring "gn analyze" Knows About your Inputs 48*8975f5c5SAndroid Build Coastguard Worker"gn analyze" is used by bots to run only affected tests and build only affected 49*8975f5c5SAndroid Build Coastguard Workertargets. Try it out locally via: 50*8975f5c5SAndroid Build Coastguard Worker```bash 51*8975f5c5SAndroid Build Coastguard Workerecho "compute_inputs_for_analyze = true" >> out/Debug/args.gn 52*8975f5c5SAndroid Build Coastguard Workergn analyze //out/Debug <(echo '{ 53*8975f5c5SAndroid Build Coastguard Worker "files": ["//BUILD.gn"], 54*8975f5c5SAndroid Build Coastguard Worker "test_targets": ["//base"], 55*8975f5c5SAndroid Build Coastguard Worker "additional_compile_targets":[]}') result.txt; cat result.txt 56*8975f5c5SAndroid Build Coastguard Worker``` 57*8975f5c5SAndroid Build Coastguard Worker* For analyze to work properly, GN must know about all inputs. 58*8975f5c5SAndroid Build Coastguard Worker* Inputs added by depfiles are *not available* to "gn analyze". 59*8975f5c5SAndroid Build Coastguard Worker * When paths listed in a target's depfile are listed as `inputs` to a 60*8975f5c5SAndroid Build Coastguard Worker dependent target, analyze will be correct. 61*8975f5c5SAndroid Build Coastguard Worker * Example: An `AndroidManifest.xml` file is an input to an 62*8975f5c5SAndroid Build Coastguard Worker `android_library()` and is included in an `android_apk()`'s depfile. 63*8975f5c5SAndroid Build Coastguard Worker `gn analyze` will know that a change to the file will require the APK 64*8975f5c5SAndroid Build Coastguard Worker to be rebuilt, because the file is marked as an input to the library, and 65*8975f5c5SAndroid Build Coastguard Worker the library is a dep of the APK. 66*8975f5c5SAndroid Build Coastguard Worker * When paths listed in a target's depfile are *not* listed as `inputs` to a 67*8975f5c5SAndroid Build Coastguard Worker dependent target, a few options exist: 68*8975f5c5SAndroid Build Coastguard Worker * Rather than putting the inputs in a depfile, force users of your template 69*8975f5c5SAndroid Build Coastguard Worker to list them, and then have your action re-compute them and assert that 70*8975f5c5SAndroid Build Coastguard Worker they were correct. 71*8975f5c5SAndroid Build Coastguard Worker * `jinja_template()` does this. 72*8975f5c5SAndroid Build Coastguard Worker * Rather than putting the inputs in a depfile, compute them beforehand and 73*8975f5c5SAndroid Build Coastguard Worker save them to a text file. Have your template Use `read_file()` to read 74*8975f5c5SAndroid Build Coastguard Worker them in. 75*8975f5c5SAndroid Build Coastguard Worker * `action_with_pydeps()` does this. 76*8975f5c5SAndroid Build Coastguard Worker * Continue using a depfile, but use an `exec_script()` to compute them when 77*8975f5c5SAndroid Build Coastguard Worker [`compute_inputs_for_analyze`](https://cs.chromium.org/chromium/src/build/config/compute_inputs_for_analyze.gni) 78*8975f5c5SAndroid Build Coastguard Worker is set. 79*8975f5c5SAndroid Build Coastguard Worker * `grit()` does this. 80*8975f5c5SAndroid Build Coastguard Worker 81*8975f5c5SAndroid Build Coastguard Worker### Outputs 82*8975f5c5SAndroid Build Coastguard Worker#### What to List as Outputs 83*8975f5c5SAndroid Build Coastguard WorkerDo not list files as `outputs` unless they are important. Outputs are important 84*8975f5c5SAndroid Build Coastguard Workerif they are: 85*8975f5c5SAndroid Build Coastguard Worker * used as an input by another target, or 86*8975f5c5SAndroid Build Coastguard Worker * are roots in the dependency graph (e.g. binaries, apks, etc). 87*8975f5c5SAndroid Build Coastguard Worker 88*8975f5c5SAndroid Build Coastguard WorkerExample: 89*8975f5c5SAndroid Build Coastguard Worker* An action runs a binary that creates an output as well as a log file. Do not 90*8975f5c5SAndroid Build Coastguard Worker list the log file as an output. 91*8975f5c5SAndroid Build Coastguard Worker 92*8975f5c5SAndroid Build Coastguard WorkerRationale: 93*8975f5c5SAndroid Build Coastguard Worker* Inputs and outputs are a node's public API on the build graph. Not listing 94*8975f5c5SAndroid Build Coastguard Worker "implementation detail"-style outputs prevents other targets from depending on 95*8975f5c5SAndroid Build Coastguard Worker them as inputs. 96*8975f5c5SAndroid Build Coastguard Worker* Not listing them also helps to minimize the size of the build graph (although 97*8975f5c5SAndroid Build Coastguard Worker this would be noticeable only for frequently used templates). 98*8975f5c5SAndroid Build Coastguard Worker 99*8975f5c5SAndroid Build Coastguard Worker#### Where to Place Outputs 100*8975f5c5SAndroid Build Coastguard Worker**Option 1:** To make outputs visible in codesearch (e.g. generated sources): 101*8975f5c5SAndroid Build Coastguard Worker* use `$target_gen_dir/$target_name.$EXTENSION`. 102*8975f5c5SAndroid Build Coastguard Worker 103*8975f5c5SAndroid Build Coastguard Worker**Option 2:** Otherwise (for binary files): 104*8975f5c5SAndroid Build Coastguard Worker* use `$target_out_dir/$target_name.$EXTENSION`. 105*8975f5c5SAndroid Build Coastguard Worker 106*8975f5c5SAndroid Build Coastguard Worker**Option 3:** For outputs that are required at runtime 107*8975f5c5SAndroid Build Coastguard Worker(e.g. [runtime_deps](https://gn.googlesource.com/gn/+/main/docs/reference.md#runtime_deps)), 108*8975f5c5SAndroid Build Coastguard Workeroptions 1 & 2 do not work because they are not archived in builder/tester bot 109*8975f5c5SAndroid Build Coastguard Workerconfigurations. In this case: 110*8975f5c5SAndroid Build Coastguard Worker* use `$root_out_dir/gen.runtime` or `$root_out_dir/obj.runtime`. 111*8975f5c5SAndroid Build Coastguard Worker 112*8975f5c5SAndroid Build Coastguard WorkerExample: 113*8975f5c5SAndroid Build Coastguard Worker```python 114*8975f5c5SAndroid Build Coastguard Worker# This .json file is used at runtime and thus cannot go in target_gen_dir. 115*8975f5c5SAndroid Build Coastguard Worker_target_dir_name = rebase_path(get_label_info(":$target_name", "dir"), "//") 116*8975f5c5SAndroid Build Coastguard Worker_output_path = "$root_out_dir/gen.runtime/$_target_dir_name/$target_name.json" 117*8975f5c5SAndroid Build Coastguard Worker``` 118*8975f5c5SAndroid Build Coastguard Worker 119*8975f5c5SAndroid Build Coastguard Worker**Option 4:** For outputs that map 1:1 with executables, and whose paths cannot 120*8975f5c5SAndroid Build Coastguard Workerbe derived at runtime: 121*8975f5c5SAndroid Build Coastguard Worker* use `$root_build_dir/YOUR_NAME_HERE/$target_name`. 122*8975f5c5SAndroid Build Coastguard Worker 123*8975f5c5SAndroid Build Coastguard WorkerExamples: 124*8975f5c5SAndroid Build Coastguard Worker```python 125*8975f5c5SAndroid Build Coastguard Worker# Wrapper scripts for apks: 126*8975f5c5SAndroid Build Coastguard Worker_output_path = "$root_build_dir/bin/$target_name" 127*8975f5c5SAndroid Build Coastguard Worker# Metadata for apks. Used by binary size tools. 128*8975f5c5SAndroid Build Coastguard Worker_output_path = "$root_build_dir/size-info/${invoker.name}.apk.jar.info" 129*8975f5c5SAndroid Build Coastguard Worker``` 130*8975f5c5SAndroid Build Coastguard Worker 131*8975f5c5SAndroid Build Coastguard Worker## Best Practices for Python Actions 132*8975f5c5SAndroid Build Coastguard WorkerOutputs should be atomic and take advantage of `restat=1`. 133*8975f5c5SAndroid Build Coastguard Worker* Make outputs atomic by writing to temporary files and then moving them to 134*8975f5c5SAndroid Build Coastguard Worker their final location. 135*8975f5c5SAndroid Build Coastguard Worker * Rationale: An interrupted write can leave a file with an updated timestamp 136*8975f5c5SAndroid Build Coastguard Worker and corrupt contents. Ninja looks only at timestamps. 137*8975f5c5SAndroid Build Coastguard Worker* Do not overwrite an existing output with identical contents. 138*8975f5c5SAndroid Build Coastguard Worker * Rationale: `restat=1` is a ninja feature enabled for all actions that 139*8975f5c5SAndroid Build Coastguard Worker short-circuits a build when output timestamps do not change. This feature is 140*8975f5c5SAndroid Build Coastguard Worker the reason that the total number of build steps sometimes decreases when 141*8975f5c5SAndroid Build Coastguard Worker building.. 142*8975f5c5SAndroid Build Coastguard Worker* Use [`action_helpers.atomic_output()`] to perform both of these techniques. 143*8975f5c5SAndroid Build Coastguard Worker 144*8975f5c5SAndroid Build Coastguard Worker[`action_helpers.atomic_output()`]: https://source.chromium.org/chromium/chromium/src/+/main:build/action_helpers.py?q=symbol:%5Cbatomic_output 145*8975f5c5SAndroid Build Coastguard Worker 146*8975f5c5SAndroid Build Coastguard WorkerActions should be deterministic in order to avoid hard-to-reproduce bugs. 147*8975f5c5SAndroid Build Coastguard WorkerGiven identical inputs, they should produce byte-for-byte identical outputs. 148*8975f5c5SAndroid Build Coastguard Worker* Some common mistakes: 149*8975f5c5SAndroid Build Coastguard Worker * Depending on filesystem iteration order. 150*8975f5c5SAndroid Build Coastguard Worker * Writing absolute paths in outputs. 151*8975f5c5SAndroid Build Coastguard Worker * Writing timestamps in files (or in zip entries). 152*8975f5c5SAndroid Build Coastguard Worker * Tip: Use [`zip_helpers.py`] when writing `.zip` files. 153*8975f5c5SAndroid Build Coastguard Worker 154*8975f5c5SAndroid Build Coastguard Worker[`zip_helpers.py`]: https://source.chromium.org/chromium/chromium/src/+/main:build/zip_helpers.py 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker## Style Guide 157*8975f5c5SAndroid Build Coastguard WorkerChromium GN files follow 158*8975f5c5SAndroid Build Coastguard Worker[GN's Style Guide](https://gn.googlesource.com/gn/+/main/docs/style_guide.md) 159*8975f5c5SAndroid Build Coastguard Workerwith a few additions. 160*8975f5c5SAndroid Build Coastguard Worker 161*8975f5c5SAndroid Build Coastguard Worker### Action Granularity 162*8975f5c5SAndroid Build Coastguard Worker * Prefer writing new Python scripts that do what you want over 163*8975f5c5SAndroid Build Coastguard Worker composing multiple separate actions within a template. 164*8975f5c5SAndroid Build Coastguard Worker * Fewer targets makes for a simpler build graph. 165*8975f5c5SAndroid Build Coastguard Worker * GN logic and build logic winds up much simpler. 166*8975f5c5SAndroid Build Coastguard Worker 167*8975f5c5SAndroid Build Coastguard WorkerBad: 168*8975f5c5SAndroid Build Coastguard Worker```python 169*8975f5c5SAndroid Build Coastguard Workertemplate("generate_zipped_sources") { 170*8975f5c5SAndroid Build Coastguard Worker generate_files("${target_name}__gen") { 171*8975f5c5SAndroid Build Coastguard Worker ... 172*8975f5c5SAndroid Build Coastguard Worker outputs = [ "$target_gen_dir/$target_name.temp" ] 173*8975f5c5SAndroid Build Coastguard Worker } 174*8975f5c5SAndroid Build Coastguard Worker zip(target_name) { 175*8975f5c5SAndroid Build Coastguard Worker deps = [ ":${target_name}__gen" ] 176*8975f5c5SAndroid Build Coastguard Worker inputs = [ "$target_gen_dir/$target_name.temp" ] 177*8975f5c5SAndroid Build Coastguard Worker outputs = [ invoker.output_zip ] 178*8975f5c5SAndroid Build Coastguard Worker } 179*8975f5c5SAndroid Build Coastguard Worker} 180*8975f5c5SAndroid Build Coastguard Worker``` 181*8975f5c5SAndroid Build Coastguard Worker 182*8975f5c5SAndroid Build Coastguard WorkerGood: 183*8975f5c5SAndroid Build Coastguard Worker```python 184*8975f5c5SAndroid Build Coastguard Workertemplate("generate_zipped_sources") { 185*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 186*8975f5c5SAndroid Build Coastguard Worker script = "generate_and_zip.py" 187*8975f5c5SAndroid Build Coastguard Worker ... 188*8975f5c5SAndroid Build Coastguard Worker outputs = [ invoker.output_zip ] 189*8975f5c5SAndroid Build Coastguard Worker } 190*8975f5c5SAndroid Build Coastguard Worker} 191*8975f5c5SAndroid Build Coastguard Worker``` 192*8975f5c5SAndroid Build Coastguard Worker 193*8975f5c5SAndroid Build Coastguard Worker### Naming for Intermediate Targets 194*8975f5c5SAndroid Build Coastguard WorkerTargets that are not relevant to users of your template should be named as: 195*8975f5c5SAndroid Build Coastguard Worker`${target_name}__$something`. 196*8975f5c5SAndroid Build Coastguard Worker 197*8975f5c5SAndroid Build Coastguard WorkerExample: 198*8975f5c5SAndroid Build Coastguard Worker```python 199*8975f5c5SAndroid Build Coastguard Workertemplate("my_template") { 200*8975f5c5SAndroid Build Coastguard Worker action("${target_name}__helper") { 201*8975f5c5SAndroid Build Coastguard Worker ... 202*8975f5c5SAndroid Build Coastguard Worker } 203*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 204*8975f5c5SAndroid Build Coastguard Worker deps = [ ":${target_name}__helper" ] 205*8975f5c5SAndroid Build Coastguard Worker ... 206*8975f5c5SAndroid Build Coastguard Worker } 207*8975f5c5SAndroid Build Coastguard Worker} 208*8975f5c5SAndroid Build Coastguard Worker``` 209*8975f5c5SAndroid Build Coastguard Worker 210*8975f5c5SAndroid Build Coastguard WorkerThis scheme ensures that subtargets defined in templates do not conflict with 211*8975f5c5SAndroid Build Coastguard Workertop-level targets. 212*8975f5c5SAndroid Build Coastguard Worker 213*8975f5c5SAndroid Build Coastguard Worker### Visibility for Intermediate Targets 214*8975f5c5SAndroid Build Coastguard Worker 215*8975f5c5SAndroid Build Coastguard WorkerYou can restrict what targets can depend on one another using [visibility]. 216*8975f5c5SAndroid Build Coastguard WorkerWhen writing templates, with multiple intermediate targets, `visibility` should 217*8975f5c5SAndroid Build Coastguard Workeronly be applied to the final target (the one named `target_name`). Applying only 218*8975f5c5SAndroid Build Coastguard Workerto the final target ensures that the invoker-provided visibility does not 219*8975f5c5SAndroid Build Coastguard Workerprevent intermediate targets from depending on each other. 220*8975f5c5SAndroid Build Coastguard Worker 221*8975f5c5SAndroid Build Coastguard Worker[visibility]: https://gn.googlesource.com/gn/+/main/docs/reference.md#var_visibility 222*8975f5c5SAndroid Build Coastguard Worker 223*8975f5c5SAndroid Build Coastguard WorkerExample: 224*8975f5c5SAndroid Build Coastguard Worker```python 225*8975f5c5SAndroid Build Coastguard Workertemplate("my_template") { 226*8975f5c5SAndroid Build Coastguard Worker # Do not forward visibility here. 227*8975f5c5SAndroid Build Coastguard Worker action("${target_name}__helper") { 228*8975f5c5SAndroid Build Coastguard Worker # Do not forward visibility here. 229*8975f5c5SAndroid Build Coastguard Worker ... 230*8975f5c5SAndroid Build Coastguard Worker } 231*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 232*8975f5c5SAndroid Build Coastguard Worker # Forward visibility here. 233*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, [ "visibility" ]) 234*8975f5c5SAndroid Build Coastguard Worker deps = [ ":${target_name}__helper" ] 235*8975f5c5SAndroid Build Coastguard Worker ... 236*8975f5c5SAndroid Build Coastguard Worker } 237*8975f5c5SAndroid Build Coastguard Worker} 238*8975f5c5SAndroid Build Coastguard Worker``` 239*8975f5c5SAndroid Build Coastguard Worker 240*8975f5c5SAndroid Build Coastguard Worker### Variables 241*8975f5c5SAndroid Build Coastguard WorkerPrefix variables within templates and targets with an underscore. For example: 242*8975f5c5SAndroid Build Coastguard Worker 243*8975f5c5SAndroid Build Coastguard Worker```python 244*8975f5c5SAndroid Build Coastguard Workertemplate("example") { 245*8975f5c5SAndroid Build Coastguard Worker _outer_sources = invoker.extra_sources 246*8975f5c5SAndroid Build Coastguard Worker 247*8975f5c5SAndroid Build Coastguard Worker source_set(target_name) { 248*8975f5c5SAndroid Build Coastguard Worker _inner_sources = invoker.sources 249*8975f5c5SAndroid Build Coastguard Worker sources = _outer_sources + _inner_sources 250*8975f5c5SAndroid Build Coastguard Worker } 251*8975f5c5SAndroid Build Coastguard Worker} 252*8975f5c5SAndroid Build Coastguard Worker``` 253*8975f5c5SAndroid Build Coastguard Worker 254*8975f5c5SAndroid Build Coastguard WorkerThis convention conveys that `sources` is relevant to `source_set`, while 255*8975f5c5SAndroid Build Coastguard Worker`_outer_sources` and `_inner_sources` are not. 256*8975f5c5SAndroid Build Coastguard Worker 257*8975f5c5SAndroid Build Coastguard Worker### Passing Arguments to Targets 258*8975f5c5SAndroid Build Coastguard WorkerPass arguments to targets by assigning them directly within target definitions. 259*8975f5c5SAndroid Build Coastguard Worker 260*8975f5c5SAndroid Build Coastguard WorkerWhen a GN template goes to resolve `invoker.FOO`, GN will look in all enclosing 261*8975f5c5SAndroid Build Coastguard Workerscopes of the target's definition. It is hard to figure out where `invoker.FOO` 262*8975f5c5SAndroid Build Coastguard Workeris coming from when it is not assigned directly within the target definition. 263*8975f5c5SAndroid Build Coastguard Worker 264*8975f5c5SAndroid Build Coastguard WorkerBad: 265*8975f5c5SAndroid Build Coastguard Worker```python 266*8975f5c5SAndroid Build Coastguard Workertemplate("hello") { 267*8975f5c5SAndroid Build Coastguard Worker script = "..." 268*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 269*8975f5c5SAndroid Build Coastguard Worker # This action will see "script" from the enclosing scope. 270*8975f5c5SAndroid Build Coastguard Worker } 271*8975f5c5SAndroid Build Coastguard Worker} 272*8975f5c5SAndroid Build Coastguard Worker``` 273*8975f5c5SAndroid Build Coastguard Worker 274*8975f5c5SAndroid Build Coastguard WorkerGood: 275*8975f5c5SAndroid Build Coastguard Worker```python 276*8975f5c5SAndroid Build Coastguard Workertemplate("hello") { 277*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 278*8975f5c5SAndroid Build Coastguard Worker script = "..." # This is equivalent, but much more clear. 279*8975f5c5SAndroid Build Coastguard Worker } 280*8975f5c5SAndroid Build Coastguard Worker} 281*8975f5c5SAndroid Build Coastguard Worker``` 282*8975f5c5SAndroid Build Coastguard Worker 283*8975f5c5SAndroid Build Coastguard Worker**Exception:** `testonly` and `visibility` can be set in the outer scope so that 284*8975f5c5SAndroid Build Coastguard Workerthey are implicitly passed to all targets within a template. 285*8975f5c5SAndroid Build Coastguard Worker 286*8975f5c5SAndroid Build Coastguard WorkerThis is okay: 287*8975f5c5SAndroid Build Coastguard Worker```python 288*8975f5c5SAndroid Build Coastguard Workertemplate("hello") { 289*8975f5c5SAndroid Build Coastguard Worker testonly = true # Applies to all nested targets. 290*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 291*8975f5c5SAndroid Build Coastguard Worker script = "..." 292*8975f5c5SAndroid Build Coastguard Worker } 293*8975f5c5SAndroid Build Coastguard Worker} 294*8975f5c5SAndroid Build Coastguard Worker``` 295*8975f5c5SAndroid Build Coastguard Worker 296*8975f5c5SAndroid Build Coastguard Worker### Using forward_variables_from() 297*8975f5c5SAndroid Build Coastguard WorkerUsing [forward_variables_from()] is encouraged, but special care needs to be 298*8975f5c5SAndroid Build Coastguard Workertaken when forwarding `"*"`. The variables `testonly` and `visibility` should 299*8975f5c5SAndroid Build Coastguard Workeralways be listed explicitly in case they are assigned in an enclosing 300*8975f5c5SAndroid Build Coastguard Workerscope. 301*8975f5c5SAndroid Build Coastguard WorkerSee [this bug] for more a full example. 302*8975f5c5SAndroid Build Coastguard Worker 303*8975f5c5SAndroid Build Coastguard WorkerTo make this easier, `//build/config/BUILDCONFIG.gn` defines: 304*8975f5c5SAndroid Build Coastguard Worker```python 305*8975f5c5SAndroid Build Coastguard WorkerTESTONLY_AND_VISIBILITY = [ "testonly", "visibility" ] 306*8975f5c5SAndroid Build Coastguard Worker``` 307*8975f5c5SAndroid Build Coastguard Worker 308*8975f5c5SAndroid Build Coastguard WorkerExample usage: 309*8975f5c5SAndroid Build Coastguard Worker```python 310*8975f5c5SAndroid Build Coastguard Workertemplate("action_wrapper") { 311*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 312*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 313*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 314*8975f5c5SAndroid Build Coastguard Worker ... 315*8975f5c5SAndroid Build Coastguard Worker } 316*8975f5c5SAndroid Build Coastguard Worker} 317*8975f5c5SAndroid Build Coastguard Worker``` 318*8975f5c5SAndroid Build Coastguard Worker 319*8975f5c5SAndroid Build Coastguard WorkerIf your template defines multiple targets, be careful to apply `testonly` to 320*8975f5c5SAndroid Build Coastguard Workerboth, but `visibility` only to the primary one (so that the primary one is not 321*8975f5c5SAndroid Build Coastguard Workerprevented from depending on the other ones). 322*8975f5c5SAndroid Build Coastguard Worker 323*8975f5c5SAndroid Build Coastguard WorkerExample: 324*8975f5c5SAndroid Build Coastguard Worker```python 325*8975f5c5SAndroid Build Coastguard Workertemplate("template_with_multiple_targets") { 326*8975f5c5SAndroid Build Coastguard Worker action("${target_name}__helper") { 327*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, [ "testonly" ]) 328*8975f5c5SAndroid Build Coastguard Worker ... 329*8975f5c5SAndroid Build Coastguard Worker } 330*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 331*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 332*8975f5c5SAndroid Build Coastguard Worker ... 333*8975f5c5SAndroid Build Coastguard Worker } 334*8975f5c5SAndroid Build Coastguard Worker} 335*8975f5c5SAndroid Build Coastguard Worker``` 336*8975f5c5SAndroid Build Coastguard Worker 337*8975f5c5SAndroid Build Coastguard WorkerAn alternative would be to explicitly set `visibility` on all inner targets, 338*8975f5c5SAndroid Build Coastguard Workerbut doing so tends to be tedious and has little benefit. 339*8975f5c5SAndroid Build Coastguard Worker 340*8975f5c5SAndroid Build Coastguard Worker[this bug]: https://bugs.chromium.org/p/chromium/issues/detail?id=862232 341*8975f5c5SAndroid Build Coastguard Worker[forward_variables_from]: https://gn.googlesource.com/gn/+/main/docs/reference.md#func_forward_variables_from 342*8975f5c5SAndroid Build Coastguard Worker 343*8975f5c5SAndroid Build Coastguard Worker## Useful Ninja Flags 344*8975f5c5SAndroid Build Coastguard WorkerUseful ninja flags when developing build rules: 345*8975f5c5SAndroid Build Coastguard Worker* `ninja -v` - log the full command-line of every target. 346*8975f5c5SAndroid Build Coastguard Worker* `ninja -v -n` - log the full command-line of every target without having 347*8975f5c5SAndroid Build Coastguard Worker to wait for a build. 348*8975f5c5SAndroid Build Coastguard Worker* `ninja -w dupbuild=err` - fail if multiple targets have the same output. 349*8975f5c5SAndroid Build Coastguard Worker* `ninja -d keeprsp` - prevent ninja from deleting response files. 350*8975f5c5SAndroid Build Coastguard Worker* `ninja -n -d explain` - print why ninja thinks a target is dirty. 351*8975f5c5SAndroid Build Coastguard Worker* `ninja -j1` - execute only one command at a time. 352