xref: /aosp_15_r20/external/angle/build/docs/writing_gn_templates.md (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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