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