xref: /aosp_15_r20/external/cronet/build/docs/writing_gn_templates.md (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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