| Index: tools/gn/docs/language.md
|
| diff --git a/tools/gn/docs/language.md b/tools/gn/docs/language.md
|
| index 7fb68e0d0190c456ce421db26bf93ea26d77f467..6032329227ba3605397137457fc073fc4e62548b 100644
|
| --- a/tools/gn/docs/language.md
|
| +++ b/tools/gn/docs/language.md
|
| @@ -15,6 +15,11 @@ every function and built-in variable. This page is more high-level.
|
| gn help
|
| ```
|
|
|
| +You can also see the
|
| +[slides](https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit?usp=sharing)
|
| +from a March, 2016 introduction to GN. The speaker notes contain the full
|
| +content.
|
| +
|
| ### Design philosophy
|
|
|
| * Writing build files should not be a creative endeavour. Ideally two
|
| @@ -41,34 +46,37 @@ GN uses an extremely simple, dynamically typed language. The types are:
|
|
|
| * Boolean (`true`, `false`).
|
| * 64-bit signed integers.
|
| - * Strings
|
| - * Lists (of any other types)
|
| - * Scopes (sort of like a dictionary, only for built-in stuff)
|
| + * Strings.
|
| + * Lists (of any other types).
|
| + * Scopes (sort of like a dictionary, only for built-in stuff).
|
|
|
| There are some built-in variables whose values depend on the current
|
| environment. See `gn help` for more.
|
|
|
| There are purposefully many omissions in the language. There are no
|
| -loops or function calls, for example. As per the above design
|
| -philosophy, if you need this kind of thing you're probably doing it
|
| -wrong.
|
| +user-defined function calls, for example (templates are the closest thing). As
|
| +per the above design philosophy, if you need this kind of thing you're probably
|
| +doing it wrong.
|
|
|
| The variable `sources` has a special rule: when assigning to it, a list
|
| of exclusion patterns is applied to it. This is designed to
|
| automatically filter out some types of files. See `gn help
|
| set_sources_assignment_filter` and `gn help label_pattern` for more.
|
|
|
| +The full grammar for language nerds is available in `gn help grammar`.
|
| +
|
| ### Strings
|
|
|
| Strings are enclosed in double-quotes and use backslash as the escape
|
| -character. The only escape sequences supported are
|
| +character. The only escape sequences supported are:
|
|
|
| * `\"` (for literal quote)
|
| * `\$` (for literal dollars sign)
|
| - * `\\` (for literal backslash) Any other use of a backslash is treated
|
| - as a literal backslash. So, for example, `\b` used in patterns does
|
| - not need to be escaped, nor do most windows paths like
|
| - `"C:\foo\bar.h"`.
|
| + * `\\` (for literal backslash)
|
| +
|
| +Any other use of a backslash is treated as a literal backslash. So, for
|
| +example, `\b` used in patterns does not need to be escaped, nor do most Windows
|
| +paths like `"C:\foo\bar.h"`.
|
|
|
| Simple variable substitution is supported via `$`, where the word
|
| following the dollars sign is replaced with the value of the variable.
|
| @@ -82,6 +90,9 @@ b = "$a/foo.cc" # b -> "mypath/foo.cc"
|
| c = "foo${a}bar.cc" # c -> "foomypathbar.cc"
|
| ```
|
|
|
| +You can encode 8-bit haracters using "$0xFF" syntax, so a string with newlines
|
| +(hex 0A) would `"look$0x0Alike$0x0Athis"
|
| +
|
| ### Lists
|
|
|
| There is no way to get the length of a list. If you find yourself
|
| @@ -118,6 +129,11 @@ there is no way to test for inclusion, the main use-case is to set up a
|
| master list of files or flags, and to remove ones that don't apply to
|
| the current build based on various conditions.
|
|
|
| +Stylistically, prefer to only add to lists and have each source file or
|
| +dependency appear once. This is the opposite of the advice Chrome-team used to
|
| +give for GYP (GYP would prefer to list all files, and then remove the ones you
|
| +didn't want in conditionals).
|
| +
|
| Lists support zero-based subscripting to extract values:
|
|
|
| ```
|
| @@ -126,7 +142,6 @@ b = a[1] # -> "second"
|
| ```
|
|
|
| The \[\] operator is read-only and can not be used to mutate the
|
| -list. This is of limited value absent the ability to iterate over a
|
| list. The primary use-case of this is when an external script returns
|
| several known values and you want to extract them.
|
|
|
| @@ -166,15 +181,30 @@ Conditionals look like C:
|
| You can use them in most places, even around entire targets if the
|
| target should only be declared in certain circumstances.
|
|
|
| -### Functions
|
| +### Looping
|
| +
|
| +You can iterate over a list with `foreach`. This is discouraged. Most things
|
| +the build should do can normally be expressed without doing this, and if you
|
| +find it necessary it may be an indication you're doing too much work in the
|
| +metabuild.
|
| +
|
| +```
|
| +foreach(i, mylist) {
|
| + print(i) # Note: i is a copy of each element, not a reference to it.
|
| +}
|
| +```
|
| +
|
| +### Function calls
|
|
|
| -Simple functions look like most other languages:
|
| +Simple function calls look like most other languages:
|
|
|
| ```
|
| print("hello, world")
|
| assert(is_win, "This should only be executed on Windows")
|
| ```
|
|
|
| +Such functions are built-in and the user can not define new ones.
|
| +
|
| Some functions take a block of code enclosed by `{ }` following them:
|
|
|
| ```
|
| @@ -183,23 +213,26 @@ static_library("mylibrary") {
|
| }
|
| ```
|
|
|
| -This means that the block becomes an argument to the function for the
|
| -function to execute. Most of the block-style functions execute the block
|
| -and treat the resulting scope as a dictionary of variables to read.
|
| +Most of these define targets. The user can define new functions like this
|
| +with the template mechanism discussed below.
|
| +
|
| +Precisely, this expression means that the block becomes an argument to the
|
| +function for the function to execute. Most of the block-style functions execute
|
| +the block and treat the resulting scope as a dictionary of variables to read.
|
|
|
| ### Scoping and execution
|
|
|
| -Files and `{ }` blocks introduce new scopes. Scoped are nested. When you
|
| -read a variable, the containing scopes will be searched in reverse order
|
| -until a matching name is found. Variable writes always go to the
|
| +Files and function calls followed by `{ }` blocks introduce new scopes. Scopes
|
| +are nested. When you read a variable, the containing scopes will be searched in
|
| +reverse order until a matching name is found. Variable writes always go to the
|
| innermost scope.
|
|
|
| There is no way to modify any enclosing scope other than the innermost
|
| one. This means that when you define a target, for example, nothing you
|
| do inside of the block will "leak out" into the rest of the file.
|
|
|
| -`if`/`else` statements, even though they use `{ }`, do not introduce a
|
| -new scope so changes will persist outside of the statement.
|
| +`if`/`else`/`foreach` statements, even though they use `{ }`, do not introduce
|
| +a new scope so changes will persist outside of the statement.
|
|
|
| ## Naming things
|
|
|
| @@ -246,10 +279,11 @@ means to look for the thing named "test\_support" in
|
|
|
| When loading a build file, if it doesn't exist in the given location
|
| relative to the source root, GN will look in the secondary tree in
|
| -`tools/gn/secondary`. The structure of this tree mirrors the main
|
| +`build/secondary`. The structure of this tree mirrors the main
|
| repository and is a way to add build files for directories that may be
|
| pulled from other repositories where we can't easily check in BUILD
|
| -files.
|
| +files. The secondary tree is a fallback rather than an override, so a file in
|
| +the normal location always takes precedence.
|
|
|
| A canonical label also includes the label of the toolchain being used.
|
| Normally, the toolchain label is implicitly inherited, but you can
|
| @@ -270,14 +304,19 @@ the path name and just start with a colon.
|
| ":base"
|
| ```
|
|
|
| -Labels can be specified as being relative to the current directory:
|
| +Labels can be specified as being relative to the current directory.
|
| +Stylistically, we prefer to use absolute paths for all non-file-local
|
| +references unless a build file needs to be run in different contexts (like
|
| +a project needs to be both standalone and pulled into other projects in
|
| +difference places in the directory hierarchy).
|
|
|
| ```
|
| -"source/plugin:myplugin"
|
| +"source/plugin:myplugin" # Prefer not to do these.
|
| "../net:url_request"
|
| ```
|
|
|
| -If a name is unspecified, it will inherit the directory name:
|
| +If a name is unspecified, it will inherit the directory name. Stylistically, we
|
| +prefer to omit the colon and name in these cases.
|
|
|
| ```
|
| "//net" = "//net:net"
|
| @@ -292,12 +331,13 @@ If a name is unspecified, it will inherit the directory name:
|
| directory tree until one is found. Set this directory to be the
|
| "source root" and interpret this file to find the name of the build
|
| config file.
|
| - 2. Execute the build config file (this is the default toolchain).
|
| + 2. Execute the build config file (this is the default toolchain). In Chrome
|
| + this is `//build/config/BUILDCONFIG.gn`.
|
| 3. Load the `BUILD.gn` file in the root directory.
|
| 4. Recursively load `BUILD.gn` in other directories to resolve all
|
| current dependencies. If a BUILD file isn't found in the specified
|
| location, GN will look in the corresponding location inside
|
| - `tools/gn/secondary`.
|
| + `build/secondary`.
|
| 5. When a target's dependencies are resolved, write out the `.ninja`
|
| file to disk.
|
| 6. When all targets are resolved, write out the root `build.ninja`
|
| @@ -307,7 +347,7 @@ If a name is unspecified, it will inherit the directory name:
|
|
|
| The first file executed is the build config file. The name of this file
|
| is specified in the `.gn` file that marks the root of the repository. In
|
| -Chrome it is `src/build/config/BUILDCONFIG.gn`. There is only one build
|
| +Chrome it is `//build/config/BUILDCONFIG.gn`. There is only one build
|
| config file.
|
|
|
| This file sets up the scope in which all other build files will execute.
|
| @@ -371,7 +411,8 @@ more help) are:
|
|
|
| * `action`: Run a script to generate a file.
|
| * `action_foreach`: Run a script once for each source file.
|
| - * `component`: Configurable to be another type of library.
|
| + * `bundle_data`: Declare data to go into a Mac/iOS bundle.
|
| + * `create_bundle`: Creates a Mac/iOS bundle.
|
| * `executable`: Generates an executable file.
|
| * `group`: A virtual dependency node that refers to one or more other
|
| targets.
|
| @@ -382,7 +423,16 @@ more help) are:
|
| * `static_library`: A .lib or .a file (normally you'll want a
|
| `source_set` instead).
|
|
|
| -You can extend this to make custom target types using templates (see below).
|
| +You can extend this to make custom target types using templates (see below). In
|
| +Chrome some of the more commonly-used templates are:
|
| +
|
| + * `component`: Either a source set or shared library, depending on the
|
| + build type.
|
| + * `test`: A test executable. On mobile this will create the appropritate
|
| + native app type for tests.
|
| + * `app`: Executable or Mac/iOS application.
|
| + * `android_apk`: Make an APK. There are a _lot_ of other Android ones, see
|
| + `//build/config/android/rules.gni`.
|
|
|
| ## Configs
|
|
|
| @@ -456,7 +506,11 @@ static_library("intermediate_library") {
|
|
|
| A target can forward a config to all dependents until a link boundary is
|
| reached by setting it as an `all_dependent_config`. This is strongly
|
| -discouraged.
|
| +discouraged as it can spray flags and defines over more of the build than
|
| +necessary. Instead, use public_deps to control which flags apply where.
|
| +
|
| +In Chrome, prefer the build flag header system (`build/buildflag_header.gni`)
|
| +for defines which prevents most screw-ups with compiler defines.
|
|
|
| ## Toolchains
|
|
|
| @@ -596,11 +650,22 @@ Templates are GN's primary way to re-use code. Typically, a template
|
| would expand to one or more other target types.
|
|
|
| ```
|
| -# Declares static library consisting of rules to build all of the IDL files into
|
| -# compiled code.
|
| +# Declares a script that compiles IDL files to source, and then compiles those
|
| +# source files.
|
| template("idl") {
|
| + # Always base helper targets on target_name so they're unique. Target name
|
| + # will be the string passed as the name when the template is invoked.
|
| + idl_target_name = "${target_name}_generate"
|
| + action_foreach(idl_target_name) {
|
| + ...
|
| + }
|
| +
|
| + # Your template should always define a target with the name target_name.
|
| + # When other targets depend on your template invocation, this will be the
|
| + # destination of that dependency.
|
| source_set(target_name) {
|
| ...
|
| + deps = [ ":$idl_target_name" ] # Require the sources to be compiled.
|
| }
|
| }
|
| ```
|
| @@ -636,7 +701,7 @@ generally accounts for most file handling in a template). However, if
|
| the template has files itself (perhaps it generates an action that runs
|
| a script), you will want to use absolute paths ("//foo/...") to refer to
|
| these files to account for the fact that the current directory will be
|
| -unpredictable during invocation. See `gn help template` for more
|
| +unpredictable during invocation. See `gn help template` for more
|
| information and more complete examples.
|
|
|
| ## Other features
|
| @@ -644,14 +709,19 @@ information and more complete examples.
|
| ### Imports
|
|
|
| You can import `.gni` files into the current scope with the `import`
|
| -function. This is _not_ an include. The imported file is executed
|
| -independently and the resulting scope is copied into the current file.
|
| -This allows the results of the import to be cached, and also prevents
|
| -some of the more "creative" uses of includes.
|
| +function. This is _not_ an include in the C++ sense. The imported file is
|
| +executed independently and the resulting scope is copied into the current file
|
| +(C++ executes the included file in the current context of when the
|
| +include directive appeared). This allows the results of the import to be
|
| +cached, and also prevents some of the more "creative" uses of includes like
|
| +multiply-included files.
|
|
|
| Typically, a `.gni` would define build arguments and templates. See `gn
|
| help import` for more.
|
|
|
| +Your `.gni` file can define temporary variables that are not exported files
|
| +that include it by using a preceding underscore in the name like `_this`.
|
| +
|
| ### Path processing
|
|
|
| Often you will want to make a file name or a list of file names relative
|
| @@ -695,18 +765,24 @@ executing a script requires that the current buildfile execution be
|
| suspended until a Python process completes execution, relying on
|
| external scripts is slow and should be minimized.
|
|
|
| -You can synchronously read and write files which is occasionally
|
| -necessary when synchronously running scripts. The typical use-case would
|
| -be to pass a list of file names longer than the command-line limits of
|
| -the current platform. See `gn help read_file` and `gn help write_file`
|
| -for how to read and write files. These functions should be avoided if at
|
| -all possible.
|
| +To prevent abuse, files permitted to call `exec_script` can be whitelisted in
|
| +the toplevel `.gn` file. Chrome does this to require additional code review
|
| +for such additions. See `gn help dotfile`.
|
| +
|
| +You can synchronously read and write files which is discouraged but
|
| +occasionally necessary when synchronously running scripts. The typical use-case
|
| +would be to pass a list of file names longer than the command-line limits of
|
| +the current platform. See `gn help read_file` and `gn help write_file` for how
|
| +to read and write files. These functions should be avoided if at all possible.
|
| +
|
| +Actions that exceed command-line length limits can use response files to
|
| +get around this limitation without synchronously writing files. See
|
| +`gn help response_file_contents`.
|
|
|
| # Differences and similarities to Blaze
|
|
|
| -[Blaze](http://google-engtools.blogspot.com/2011/08/build-in-cloud-how-build-system-works.html)
|
| -is Google's internal build system. It has inspired a number of other
|
| -systems such as
|
| +Blaze is Google's internal build system, now publicly released as
|
| +[Bazel](http://bazel.io/). It has inspired a number of other systems such as
|
| [Pants](https://github.com/twitter/commons/tree/master/src/python/twitter/pants)
|
| and [Buck](http://facebook.github.io/buck/).
|
|
|
| @@ -722,11 +798,10 @@ toolchain, but built into the tool itself. The way that toolchains work
|
| in GN is a result of trying to separate this concept out into the build
|
| files in a clean way.
|
|
|
| -GN keeps some GYP concept like "all dependent" and "direct dependent"
|
| -settings which work a bit differently in Blaze. This is partially to
|
| -make conversion from the existing GYP code easier, and the GYP
|
| -constructs generally offer more fine-grained control (which is either
|
| -good or bad, depending on the situation).
|
| +GN keeps some GYP concept like "all dependent" settings which work a bit
|
| +differently in Blaze. This is partially to make conversion from the existing
|
| +GYP code easier, and the GYP constructs generally offer more fine-grained
|
| +control (which is either good or bad, depending on the situation).
|
|
|
| GN also uses GYP names like "sources" instead of "srcs" since
|
| abbreviating this seems needlessly obscure, although it uses Blaze's
|
|
|