• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# GN Frequently Asked Questions
2
3[TOC]
4
5## Where is the GN documentation?
6
7GN has extensive built-in help, so you can run `gn help`, but you can also see
8all of the help on [the reference page](reference.md). See also the [quick
9start](quick_start.md) guide and the [language and operation
10details](language.md).
11
12## Can I generate XCode or Visual Studio projects?
13
14You can generate skeleton (or wrapper) projects for Xcode, Visual Studio,
15QTCreator, and Eclipse that will list the files and targets in the build, but
16use Ninja to do the actual build. You cannot generate "real" projects that look
17and compile like native ones.
18
19Run `gn help gen` for more details.
20
21## How do I do cross-compiles?
22
23GN has robust support for doing cross compiles and building things for
24multiple architectures in a single build.
25
26See [GNCrossCompiles](cross_compiles.md) for more info.
27
28## Can I control what targets are built by default?
29
30Yes! If you create a group target called "default" in the top-level (root) build
31file, i.e., "//:default", GN will tell Ninja to build that by default, rather
32than building everything.
33
34## Are there any public presentations on GN?
35
36[There's at least one](https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit?usp=sharing), from 2015. There
37haven't been big changes since then apart from moving it to a standalone
38repo, so it should still be relevant.
39
40## What is the order of flags and values given to the compiler?
41
42The final values of compiler flags, linker flags, defines, and include
43directories are collected from various sources by GN. The ordering is defined
44as:
45
461. Those set directly on the current target (not in a config).
472. Those set on the `configs` on the target in order that the configs appear in the list.
483. Those set on the `all_dependent_configs` on the target in order that the configs appear in the list.
494. Those set on the `public_configs` on the target in order that those configs appear in the list.
505. `all_dependent_configs` pulled from dependencies, in the order of the `deps` list. This is done recursively. If a config appears more than once, only the first occurrence will be used.
516. `public_configs` pulled from dependencies, in the order of the `deps` list. If a dependency is public, they will be applied recursively.
52
53If you need a specific relative ordering of values you may need to put those
54flags in a config and prepend or append that config in a way that produces the
55desired result.
56
57## How can a target affect those that depend on it?
58
59The main way that information flows up the dependency graph is via
60`public_configs`. This allows a target to add preprocessor defines, compiler
61flags, and linker flags to targets that depend on it. A typical example is a
62library that requires `include_dirs` and `defines` to be set in a certain way
63for its headers to work. It would put its values in a config:
64
65```
66config("icu_config") {
67  include_dirs = [ "//third_party/icu" ]
68  defines = [ "U_USING_ICU_NAMESPACE=0" ]
69}
70```
71
72The library would then reference that as a `public_config` which will apply it
73to any target that directly depends on the `icu` target:
74
75```
76shared_library("icu") {
77  sources = [ ... ]
78  deps = [ ... ]
79
80  public_configs = [ ":icu_config" ]  # Label of config defined above.
81}
82```
83
84A `public_config` applies only to direct dependencies of the target. If a target
85wants to "republish" the `public_configs` from its dependencies, it would list
86those dependencies in its `public_deps`. In this example, a "browser" library
87might use ICU headers in its own headers, so anything that depends on it also
88needs to get the ICU configuration:
89
90```
91shared_library("browser") {
92  ...
93
94  # Anything that depends on this "browser" library will also get ICU's settings.
95  public_deps = [ "//third_party/icu" ]
96}
97```
98
99Another way apply settings up the dependency graph is with
100`all_dependent_configs` which works like `public_configs` except that it is
101applied to all dependent targets regardless of `deps`/`public_deps`. Use of this
102feature is discouraged because it is easy to accumulate lots of unnecessary
103settings in a large project. Ideally all targets can define which information
104their dependencies need and can control this explicitly with `public_deps`.
105
106The last way that information can be collected across the dependency graph is
107with the metadata feature. This allows data (see `gn help metadata`) to be
108collected from targets to be written to disk (see `gn help generated_file`) for
109the build to use. Computed metadata values are written after all BUILD.gn files
110are processed and are not available to the GN script.
111
112Sometimes people want to write conditional GN code based on values of a
113dependency. This is not possible: GN has no defined order for loading BUILD.gn
114files (this allows pararellism) so GN may not have even loaded the file
115containing a dependency when you might want information about it. The only way
116information flows around the dependency graph is if GN itself is propagating
117that data after the targets are defined.
118
119## How can a target affect its dependencies?
120
121Sometimes you might have a dependency graph **A �� Z** or a longer chain **A �� B
122�� C �� Z** and want to control some aspect of **Z** when used from **A**. This is
123not possible in GN: information only flows up the dependency chain.
124
125Every label in GN is compiled once per _toolchain_. This means that every target
126that depends on **B** gets the same version of **B**. If you need different
127variants of **B** there are only two options:
128
1291. Explicitly define two similar but differently named targets encoding the
130variations you need. This can be done without specifying everything twice using
131a template or by writing things like the sources to a variable and using that
132variable in each version of the target.
133
1342. Use different toolchains. This is commonly used to encode "host" versus
135"target" differences or to compile parts of a project with something like ASAN.
136It is possible to use toolchains to encode any variation you might desire but
137this can be difficult to manage and might be impossible or discoraged depending
138on how your project is set up (Chrome and Fuchsia use toolchains for specific
139purposes only).
140
141## How can I recursively copy a directory as a build step?
142
143Sometimes people want to write a build action that expresses copying all files
144(possibly recursively, possily not) from a source directory without specifying
145all files in that directory in a BUILD file. This is not possible to express:
146correct builds must list all inputs. Most approaches people try to work around
147this break in some way for incremental builds, either the build step is run
148every time (the build is always "dirty"), file modifications will be missed, or
149file additions will be missed.
150
151One thing people try is to write an action that declares an input directory and
152an output directory and have it copy all files from the source to the
153destination. But incremental builds are likely going to be incorrect if you do
154this. Ninja determines if an output is in need of rebuilding by comparing the
155last modified date of the source to the last modified date of the destination.
156Since almost no filesystems propagate the last modified date of files to their
157directory, modifications to files in the source will not trigger an incremental
158rebuild.
159
160Beware when testing this: most filesystems update the last modified date of the
161parent directory (but not recursive parents) when adding to or removing a file
162from that directory so this will appear to work in many cases. But no modern
163production filesystems propagate modification times of the contents of the files
164to any directories because it would be very slow. The result will be that
165modifications to the source files will not be reflected in the output when doing
166incremental builds.
167
168Another thing people try is to write all of the source files to a "depfile" (see
169`gn help depfile`) and to write a single stamp file that tracks the modified
170date of the output. This approach also may appear to work but is subtly wrong:
171the additions of new files to the source directory will not trigger the build
172step and that addition will not be reflected in an incremental build.
173
174## Why does "gn check" complain about conditionally included headers?
175
176The "gn check" feature (see `gn help check`) validates that the source code's
177use of header files follows the requirements set up in the build. It can be a
178very useful tool for ensuring build correctness.
179
180GN scans the source code for `#include` directives and checks that the included
181files are allowed given the specification of the build. But it is relatively
182simplistic and does not understand the preprocessor. This means that some
183headers that are correctly included for a different build variant might be
184flagged by GN. To disable checking of an include, append a "nogncheck"
185annotation to the include line:
186
187```
188#if defined(OS_ANDROID)
189#include "src/android/foo/bar.h"  // nogncheck
190#endif
191```
192
193Correctly handling these cases requires a full preprocessor implementation
194because many preprocessor conditions depend on values set by other headers.
195Implementing this would require new code and complexity to define the toolchain
196and run the preprocessor, and also means that a full build be done before doing
197the check (since some headers will be generated at build-time). So far, the
198complexity and disadvantages have outweighed the advantages of a perfectly
199correct "gn check" implementation.
200
201## Why does "gn check" miss my header?
202
203The "gn check" feature (see previous question) only checks for headers that have
204been declared in the current toolchain. So if your header never appears in a
205`sources` or `public` list, any file will be able to include it without "gn
206check" failing. As a result, targets should always list all headers they contain
207even though listing them does not affect the build.
208
209Sometimes a feature request is made to flag unknown headers so that people will
210know they should be added to the build. But the silent omission of headers
211outside of the current toolchain is an important feature that limits the
212necessity of "nogncheck" annotations (see previous question).
213
214In a large project like Chrome, many platform-specific headers will only be
215defined in that platform's build (for example, Android-specific headers would
216only be listed in the build when compiling for Android). Because the checking
217doesn't understand the preprocessor, checking unknown files would flag uses of
218these headers even if they were properly guarded by platform conditionals. By
219ignoring headers outside of the current toolchain, the "nogncheck" annotations
220can be omitted for most platform-specific files.
221