|  | # GN Style Guide | 
|  |  | 
|  | [TOC] | 
|  |  | 
|  | ## Naming and ordering within the file | 
|  |  | 
|  | ### Location of build files | 
|  |  | 
|  | It usually makes sense to have more build files closer to the code than | 
|  | fewer ones at the top level; this is in contrast with what we did with | 
|  | GYP. This makes things easier to find, and also makes the set of owners | 
|  | required for reviews smaller since changes are more focused to particular | 
|  | subdirectories. | 
|  |  | 
|  | ### Targets | 
|  |  | 
|  | * Most BUILD files should have a target with the same name as the | 
|  | directory. This target should be the first target. | 
|  | * Other targets should be in some logical order -- usually | 
|  | more important targets will be first, and unit tests will follow the | 
|  | corresponding target. If there's no clear ordering, consider | 
|  | alphabetical order. | 
|  | * Test support libraries should be static libraries named "test\_support". | 
|  | For example, "//ui/compositor:test\_support". Test support libraries should | 
|  | include as public deps the non-test-support version of the library | 
|  | so tests need only depend on the test\_support target (rather than | 
|  | both). | 
|  |  | 
|  | Naming advice | 
|  |  | 
|  | * Targets and configs should be named using lowercase with underscores | 
|  | separating words, unless there is a strong reason to do otherwise. | 
|  | * Source sets, groups, and static libraries do not need globally unique names. | 
|  | Prefer to give such targets short, non-redundant names without worrying | 
|  | about global uniqueness. For example, it looks much better to write a | 
|  | dependency as `"//mojo/public/bindings"` rather than | 
|  | `"//mojo/public/bindings:mojo_bindings"` | 
|  | * Shared libraries (and by extension, components) must have globally unique | 
|  | output names. Give such targets short non-unique names above, and then | 
|  | provide a globally unique `output_name` for that target. | 
|  | * Executables and tests should be given a globally unique name. Technically | 
|  | only the output names must be unique, but since only the output names | 
|  | appear in the shell and on bots, it's much less confusing if the name | 
|  | matches the other places the executable appears. | 
|  |  | 
|  | ### Configs | 
|  |  | 
|  | * A config associated with a single target should be named the same as | 
|  | the target with `_config` following it. | 
|  | * A config should appear immediately before the corresponding target | 
|  | that uses it. | 
|  |  | 
|  | ### Example | 
|  |  | 
|  | Example for the `src/foo/BUILD.gn` file: | 
|  |  | 
|  | ``` | 
|  | # Copyright 2016 The Chromium Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style license that can be | 
|  | # found in the LICENSE file. | 
|  |  | 
|  | # Config for foo is named foo_config and immediately precedes it in the file. | 
|  | config("foo_config") { | 
|  | } | 
|  |  | 
|  | # Target matching path name is the first target. | 
|  | executable("foo") { | 
|  | } | 
|  |  | 
|  | # Test for foo follows it. | 
|  | test("foo_unittests") { | 
|  | } | 
|  |  | 
|  | config("bar_config") { | 
|  | } | 
|  |  | 
|  | source_set("bar") { | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ## Ordering within a target | 
|  |  | 
|  | 1. `output_name` / `visibility` / `testonly` | 
|  | 2. `sources` | 
|  | 3. `cflags`, `include_dirs`, `defines`, `configs` etc. in whatever | 
|  | order makes sense to you. | 
|  | 4. `public_deps` | 
|  | 5. `deps` | 
|  |  | 
|  | ### Conditions | 
|  |  | 
|  | Simple conditions affecting just one variable (e.g. adding a single | 
|  | source or adding a flag for one particular OS) can go beneath the | 
|  | variable they affect. More complicated conditions affecting more than | 
|  | one thing should go at the bottom. | 
|  |  | 
|  | Conditions should be written to minimize the number of conditional blocks. | 
|  |  | 
|  | ## Formatting and indenting | 
|  |  | 
|  | GN contains a built-in code formatter which defines the formatting style. | 
|  | Some additional notes: | 
|  |  | 
|  | * Variables are `lower_case_with_underscores`. | 
|  | * Comments should be complete sentences with periods at the end. | 
|  | * Compiler flags and such should always be commented with what they do | 
|  | and why the flag is needed. | 
|  |  | 
|  | ### Sources | 
|  |  | 
|  | Prefer to list sources only once. It is OK to conditionally include sources | 
|  | rather than listing them all at the top and then conditionally excluding them | 
|  | when they don't apply. Conditional inclusion is often clearer since a file is | 
|  | only listed once and it's easier to reason about when reading. | 
|  |  | 
|  | ``` | 
|  | sources = [ | 
|  | "main.cc", | 
|  | ] | 
|  | if (use_aura) { | 
|  | sources += [ "thing_aura.cc" ] | 
|  | } | 
|  | if (use_gtk) { | 
|  | sources += [ "thing_gtk.cc" ] | 
|  | } | 
|  | ``` | 
|  |  | 
|  | ### Deps | 
|  |  | 
|  | * Deps should be in alphabetical order. | 
|  | * Deps within the current file should be written first and not | 
|  | qualified with the file name (just `:foo`). | 
|  | * Other deps should always use fully-qualified path names unless | 
|  | relative ones are required for some reason. | 
|  |  | 
|  | ``` | 
|  | deps = [ | 
|  | ":a_thing", | 
|  | ":mystatic", | 
|  | "//foo/bar:other_thing", | 
|  | "//foo/baz:that_thing", | 
|  | ] | 
|  | ``` | 
|  |  | 
|  | ### Import | 
|  |  | 
|  | Use fully-qualified paths for imports: | 
|  |  | 
|  | ``` | 
|  | import("//foo/bar/baz.gni")  # Even if this file is in the foo/bar directory | 
|  | ``` | 
|  |  | 
|  | ## Usage | 
|  |  | 
|  | ### Source sets versus static libraries | 
|  |  | 
|  | Source sets and static libraries can be used interchangeably in most cases. If | 
|  | you're unsure what to use, a source set is almost never wrong and is less likely | 
|  | to cause problems, but on a large project using the right kind of target can | 
|  | be important, so you should know about the following tradeoffs. | 
|  |  | 
|  | Static libraries follow different linking rules. When a static library is | 
|  | included in a link, only the object files that contain unresolved symbols will | 
|  | be brought into the build. Source sets result in every object file being added | 
|  | to the link line of the final binary. | 
|  |  | 
|  | * If you're eventually linking code into a component, shared library, or | 
|  | loadable module, you normally need to use source sets. This is because | 
|  | object files with no symbols referenced from within the shared library will | 
|  | not be linked into the final library at all. This omission will happen even | 
|  | if that object file has a symbol marked for export that targets dependent | 
|  | on that shared library need. This will result in undefined symbols when | 
|  | linking later targets. | 
|  |  | 
|  | * Unit tests (and anything else with static initializers with side effects) | 
|  | must use source sets. The gtest TEST macros create static initializers | 
|  | that register the test. But since no code references symbols in the object | 
|  | file, linking a test into a static library and then into a test executable | 
|  | means the tests will get stripped. | 
|  |  | 
|  | * On some platforms, static libraries may involve duplicating all of the | 
|  | data in the object files that comprise it. This takes more disk space and | 
|  | for certain very large libraries in configurations with very large object | 
|  | files can cause internal limits on the size of static libraries to be | 
|  | exceeded. Source sets do not have this limitation. Some targets switch | 
|  | between source sets and static libraries depending on the build | 
|  | configuration to avoid this problem. Some platforms (or toolchains) may | 
|  | support something called "thin archives" which don't have this problem; | 
|  | but you can't rely on this as a portable solution. | 
|  |  | 
|  | * Source sets can have no sources, while static libraries will give strange | 
|  | platform-specific errors if they have no sources. If a target has only | 
|  | headers (for include checking purposes) or conditionally has no sources on | 
|  | some platforms, use a source set. | 
|  |  | 
|  | * In cases where a lot of the symbols are not needed for a particular link | 
|  | (this especially happens when linking test binaries), putting that code in | 
|  | a static library can dramatically increase linking performance. This is | 
|  | because the object files not needed for the link are never considered in | 
|  | the first place, rather than forcing the linker to strip the unused code | 
|  | in a later pass when nothing references it. | 
|  |  | 
|  | ### Components versus shared libraries versus source sets | 
|  |  | 
|  | A component is a Chrome template (rather than a built-in GN concept) that | 
|  | expands either to a shared library or a static library / source set depending | 
|  | on the value of the `is_component_build` variable. This allows release builds | 
|  | to be linked statically in a large binary, but for developers to use shared | 
|  | libraries for most operations. Chrome developers should almost always use | 
|  | a component instead of shared library directly. | 
|  |  | 
|  | Much like the source set versus static library tradeoff, there's no hard | 
|  | and fast rule as to when you should use a component or not. Using | 
|  | components can significantly speed up incremental builds by making | 
|  | linking much faster, but they require you to have to think about which | 
|  | symbols need to be exported from the target. | 
|  |  | 
|  | ### Loadable modules versus shared libraries | 
|  |  | 
|  | A shared library will be listed on the link line of dependent targets and will | 
|  | be loaded automatically by the operating system when the application starts | 
|  | and symbols automatically resolved. A loadable module will not be linked | 
|  | directly and the application must manually load it. | 
|  |  | 
|  | On Windows and Linux shared libraries and loadable modules result in the same | 
|  | type of file (`.dll` and `.so`, respectively). The only difference is in how | 
|  | they are linked to dependent targets. On these platforms, having a `deps` | 
|  | dependency on a loadable module is the same as having a `data_deps` | 
|  | (non-linked) dependency on a shared library. | 
|  |  | 
|  | On Mac, these targets have different formats: a shared library will generate a | 
|  | `.dylib` file and a loadable module will generate a `.so` file. | 
|  |  | 
|  | Use loadable modules for things like plugins. In the case of plugin-like | 
|  | libraries, it's good practice to use both a loadable module for the target type | 
|  | (even for platforms where it doesn't matter) and data deps for targets that | 
|  | depend on it so it's clear from both places that how the library will be linked | 
|  | and loaded. | 
|  |  | 
|  | ## Build arguments | 
|  |  | 
|  | ### Scope | 
|  |  | 
|  | Build arguments should be scoped to a unit of behavior, e.g. enabling a feature. | 
|  | Typically an argument would be declared in an imported file to share it with | 
|  | the subset of the build that could make use of it. | 
|  |  | 
|  | Chrome has many legacy flags in `//build/config/features.gni`, | 
|  | `//build/config/ui.gni`. These locations are deprecated. Feature flags should | 
|  | go along with the code for the feature. Many browser-level features can go | 
|  | somewhere in `//chrome/` without lower-level code knowing about it. Some | 
|  | UI environment flags can go into `//ui/`, and many flags can also go with | 
|  | the corresponding code in `//components/`. You can write a `.gni` file in | 
|  | components and have build files in chrome or content import it if necessary. | 
|  |  | 
|  | The way to think about things in the `//build` directory is that this is | 
|  | DEPSed into various projects like V8 and WebRTC. Build flags specific to | 
|  | code outside of the build directory shouldn't be in the build directory, and | 
|  | V8 shouldn't get feature defines for Chrome features. | 
|  |  | 
|  | New feature defines should use the buildflag system. See | 
|  | `//build/buildflag_header.gni` which allows preprocessor defines to be | 
|  | modularized without many of the disadvantages that made us use global defines | 
|  | in the past. | 
|  |  | 
|  | ### Type | 
|  |  | 
|  | Arguments support all the [GN language types](language.md#Language). | 
|  |  | 
|  | In the vast majority of cases `boolean` is the preferred type, since most | 
|  | arguments are enabling or disabling features or includes. | 
|  |  | 
|  | `String`s are typically used for filepaths. They are also used for enumerated | 
|  | types, though `integer`s are sometimes used as well. | 
|  |  | 
|  | ### Naming conventions | 
|  |  | 
|  | While there are no hard and fast rules around argument naming there are | 
|  | many common conventions. If you ever want to see the current list of argument | 
|  | names and default values for your current checkout use | 
|  | `gn args out/Debug --list --short`. | 
|  |  | 
|  | `use_foo` - indicates dependencies or major codepaths to include (e.g. | 
|  | `use_open_ssl`, `use_ozone`, `use_cups`) | 
|  |  | 
|  | `enable_foo` - indicates feature or tools to be enabled (e.g. | 
|  | `enable_google_now`, `enable_nacl`, `enable_remoting`, `enable_pdf`) | 
|  |  | 
|  | `disable_foo` - _NOT_ recommended, use `enable_foo` instead with swapped default | 
|  | value | 
|  |  | 
|  | `is_foo` - usually a global state descriptor (e.g. `is_chrome_branded`, | 
|  | `is_desktop_linux`); poor choice for non-globals | 
|  |  | 
|  | `foo_use_bar` - prefixes can be used to indicate a limited scope for an argument | 
|  | (e.g. `rtc_use_h264`, `v8_use_snapshot`) | 
|  |  | 
|  | #### Variables | 
|  |  | 
|  | Prefix top-level local variables within `.gni` files with an underscore. This | 
|  | prefix causes variables to be unavailable to importing scripts. | 
|  |  | 
|  | ``` | 
|  | _this_var_will_not_be_exported = 1 | 
|  | but_this_one_will = 2 | 
|  | ``` |