| # GN Frequently Asked Questions | |
| [TOC] | |
| ## Where is the GN documentation? | |
| GN has extensive built-in help, so you can run `gn help`, but you can also see | |
| all of the help on [the reference page](reference.md). See also the [quick | |
| start](quick_start.md) guide and the [language and operation | |
| details](language.md). | |
| ## Can I generate XCode or Visual Studio projects? | |
| You can generate skeleton (or wrapper) projects for Xcode, Visual Studio, | |
| QTCreator, and Eclipse that will list the files and targets in the build, but | |
| use Ninja to do the actual build. You cannot generate "real" projects that look | |
| and compile like native ones. | |
| Run `gn help gen` for more details. | |
| ## How do I do cross-compiles? | |
| GN has robust support for doing cross compiles and building things for | |
| multiple architectures in a single build. | |
| See [GNCrossCompiles](cross_compiles.md) for more info. | |
| ## Can I control what targets are built by default? | |
| Yes! If you create a group target called "default" in the top-level (root) build | |
| file, i.e., "//:default", GN will tell Ninja to build that by default, rather | |
| than building everything. | |
| ## Are there any public presentations on GN? | |
| [There's at least one](https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit?usp=sharing), from 2015. There | |
| haven't been big changes since then apart from moving it to a standalone | |
| repo, so it should still be relevant. | |
| ## What is the order of flags and values given to the compiler? | |
| The final values of compiler flags, linker flags, defines, and include | |
| directories are collected from various sources by GN. The ordering is defined | |
| as: | |
| 1. Those set directly on the current target (not in a config). | |
| 2. Those set on the `configs` on the target in order that the configs appear in the list. | |
| 3. Those set on the `all_dependent_configs` on the target in order that the configs appear in the list. | |
| 4. Those set on the `public_configs` on the target in order that those configs appear in the list. | |
| 5. `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. | |
| 6. `public_configs` pulled from dependencies, in the order of the `deps` list. If a dependency is public, they will be applied recursively. | |
| If you need a specific relative ordering of values you may need to put those | |
| flags in a config and prepend or append that config in a way that produces the | |
| desired result. | |
| ## How can a target affect those that depend on it? | |
| The main way that information flows up the dependency graph is via | |
| `public_configs`. This allows a target to add preprocessor defines, compiler | |
| flags, and linker flags to targets that depend on it. A typical example is a | |
| library that requires `include_dirs` and `defines` to be set in a certain way | |
| for its headers to work. It would put its values in a config: | |
| ``` | |
| config("icu_config") { | |
| include_dirs = [ "//third_party/icu" ] | |
| defines = [ "U_USING_ICU_NAMESPACE=0" ] | |
| } | |
| ``` | |
| The library would then reference that as a `public_config` which will apply it | |
| to any target that directly depends on the `icu` target: | |
| ``` | |
| shared_library("icu") { | |
| sources = [ ... ] | |
| deps = [ ... ] | |
| public_configs = [ ":icu_config" ] # Label of config defined above. | |
| } | |
| ``` | |
| A `public_config` applies only to direct dependencies of the target. If a target | |
| wants to "republish" the `public_configs` from its dependencies, it would list | |
| those dependencies in its `public_deps`. In this example, a "browser" library | |
| might use ICU headers in its own headers, so anything that depends on it also | |
| needs to get the ICU configuration: | |
| ``` | |
| shared_library("browser") { | |
| ... | |
| # Anything that depends on this "browser" library will also get ICU's settings. | |
| public_deps = [ "//third_party/icu" ] | |
| } | |
| ``` | |
| Another way apply settings up the dependency graph is with | |
| `all_dependent_configs` which works like `public_configs` except that it is | |
| applied to all dependent targets regardless of `deps`/`public_deps`. Use of this | |
| feature is discouraged because it is easy to accumulate lots of unnecessary | |
| settings in a large project. Ideally all targets can define which information | |
| their dependencies need and can control this explicitly with `public_deps`. | |
| The last way that information can be collected across the dependency graph is | |
| with the metadata feature. This allows data (see `gn help metadata`) to be | |
| collected from targets to be written to disk (see `gn help generated_file`) for | |
| the build to use. Computed metadata values are written after all BUILD.gn files | |
| are processed and are not available to the GN script. | |
| Sometimes people want to write conditional GN code based on values of a | |
| dependency. This is not possible: GN has no defined order for loading BUILD.gn | |
| files (this allows pararellism) so GN may not have even loaded the file | |
| containing a dependency when you might want information about it. The only way | |
| information flows around the dependency graph is if GN itself is propagating | |
| that data after the targets are defined. | |
| ## How can a target affect its dependencies? | |
| Sometimes you might have a dependency graph **A 🠲 Z** or a longer chain **A 🠲 B | |
| 🠲 C 🠲 Z** and want to control some aspect of **Z** when used from **A**. This is | |
| not possible in GN: information only flows up the dependency chain. | |
| Every label in GN is compiled once per _toolchain_. This means that every target | |
| that depends on **B** gets the same version of **B**. If you need different | |
| variants of **B** there are only two options: | |
| 1. Explicitly define two similar but differently named targets encoding the | |
| variations you need. This can be done without specifying everything twice using | |
| a template or by writing things like the sources to a variable and using that | |
| variable in each version of the target. | |
| 2. Use different toolchains. This is commonly used to encode "host" versus | |
| "target" differences or to compile parts of a project with something like ASAN. | |
| It is possible to use toolchains to encode any variation you might desire but | |
| this can be difficult to manage and might be impossible or discoraged depending | |
| on how your project is set up (Chrome and Fuchsia use toolchains for specific | |
| purposes only). | |
| ## How can I recursively copy a directory as a build step? | |
| Sometimes people want to write a build action that expresses copying all files | |
| (possibly recursively, possily not) from a source directory without specifying | |
| all files in that directory in a BUILD file. This is not possible to express: | |
| correct builds must list all inputs. Most approaches people try to work around | |
| this break in some way for incremental builds, either the build step is run | |
| every time (the build is always "dirty"), file modifications will be missed, or | |
| file additions will be missed. | |
| One thing people try is to write an action that declares an input directory and | |
| an output directory and have it copy all files from the source to the | |
| destination. But incremental builds are likely going to be incorrect if you do | |
| this. Ninja determines if an output is in need of rebuilding by comparing the | |
| last modified date of the source to the last modified date of the destination. | |
| Since almost no filesystems propagate the last modified date of files to their | |
| directory, modifications to files in the source will not trigger an incremental | |
| rebuild. | |
| Beware when testing this: most filesystems update the last modified date of the | |
| parent directory (but not recursive parents) when adding to or removing a file | |
| from that directory so this will appear to work in many cases. But no modern | |
| production filesystems propagate modification times of the contents of the files | |
| to any directories because it would be very slow. The result will be that | |
| modifications to the source files will not be reflected in the output when doing | |
| incremental builds. | |
| Another thing people try is to write all of the source files to a "depfile" (see | |
| `gn help depfile`) and to write a single stamp file that tracks the modified | |
| date of the output. This approach also may appear to work but is subtly wrong: | |
| the additions of new files to the source directory will not trigger the build | |
| step and that addition will not be reflected in an incremental build. | |
| ## How can I reference all files in a directory (glob)? | |
| Sometimes people want to automatically refer to all files in a directory, | |
| typically something like `"*.cc"` for the sources. This is called a "glob." | |
| Globs are not supported in GN. In order for Ninja to know when to re-run | |
| GN, it would need to check the directory modification times of any | |
| directories being globbed. Directory modification times that reflect | |
| additions and removals of files are not as reliably implemented across | |
| platforms and filesystems as file modification times (for example, it is | |
| not supported on Windows FAT32 drives). | |
| Even if directory modification times work properly on your build systems, | |
| GN's philosophy prefers a very explicit build specification style that | |
| is contrary to globs. | |
| ## Why does "gn check" complain about conditionally included headers? | |
| The "gn check" feature (see `gn help check`) validates that the source code's | |
| use of header files follows the requirements set up in the build. It can be a | |
| very useful tool for ensuring build correctness. | |
| GN scans the source code for `#include` directives and checks that the included | |
| files are allowed given the specification of the build. But it is relatively | |
| simplistic and does not understand the preprocessor. This means that some | |
| headers that are correctly included for a different build variant might be | |
| flagged by GN. To disable checking of an include, append a "nogncheck" | |
| annotation to the include line: | |
| ``` | |
| #if defined(OS_ANDROID) | |
| #include "src/android/foo/bar.h" // nogncheck | |
| #endif | |
| ``` | |
| Correctly handling these cases requires a full preprocessor implementation | |
| because many preprocessor conditions depend on values set by other headers. | |
| Implementing this would require new code and complexity to define the toolchain | |
| and run the preprocessor, and also means that a full build be done before doing | |
| the check (since some headers will be generated at build-time). So far, the | |
| complexity and disadvantages have outweighed the advantages of a perfectly | |
| correct "gn check" implementation. | |
| ## Why does "gn check" miss my header? | |
| The "gn check" feature (see previous question) only checks for headers that have | |
| been declared in the current toolchain. So if your header never appears in a | |
| `sources` or `public` list, any file will be able to include it without "gn | |
| check" failing. As a result, targets should always list all headers they contain | |
| even though listing them does not affect the build. | |
| Sometimes a feature request is made to flag unknown headers so that people will | |
| know they should be added to the build. But the silent omission of headers | |
| outside of the current toolchain is an important feature that limits the | |
| necessity of "nogncheck" annotations (see previous question). | |
| In a large project like Chrome, many platform-specific headers will only be | |
| defined in that platform's build (for example, Android-specific headers would | |
| only be listed in the build when compiling for Android). Because the checking | |
| doesn't understand the preprocessor, checking unknown files would flag uses of | |
| these headers even if they were properly guarded by platform conditionals. By | |
| ignoring headers outside of the current toolchain, the "nogncheck" annotations | |
| can be omitted for most platform-specific files. |