dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 1 | # GN Language and Operation |
| 2 | |
| 3 | [TOC] |
| 4 | |
| 5 | ## Introduction |
| 6 | |
| 7 | This page describes many of the language details and behaviors. |
| 8 | |
| 9 | ### Use the built-in help! |
| 10 | |
| 11 | GN has an extensive built-in help system which provides a reference for |
| 12 | every function and built-in variable. This page is more high-level. |
| 13 | |
| 14 | ``` |
| 15 | gn help |
| 16 | ``` |
| 17 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 18 | You can also see the |
| 19 | [slides](https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit?usp=sharing) |
| 20 | from a March, 2016 introduction to GN. The speaker notes contain the full |
| 21 | content. |
| 22 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 23 | ### Design philosophy |
| 24 | |
| 25 | * Writing build files should not be a creative endeavour. Ideally two |
| 26 | people should produce the same buildfile given the same |
| 27 | requirements. There should be no flexibility unless it's absolutely |
| 28 | needed. As many things should be fatal errors as possible. |
| 29 | |
| 30 | * The definition should read more like code than rules. I don't want |
| 31 | to write or debug Prolog. But everybody on our team can write and |
| 32 | debug C++ and Python. |
| 33 | |
| 34 | * The build language should be opinionated as to how the build should |
| 35 | work. It should not necessarily be easy or even possible to express |
| 36 | arbitrary things. We should be changing source and tooling to make |
| 37 | the build simpler rather than making everything more complicated to |
| 38 | conform to external requirements (within reason). |
| 39 | |
| 40 | * Be like Blaze when it makes sense (see "Differences and similarities |
| 41 | to Blaze" below). |
| 42 | |
| 43 | ## Language |
| 44 | |
| 45 | GN uses an extremely simple, dynamically typed language. The types are: |
| 46 | |
| 47 | * Boolean (`true`, `false`). |
| 48 | * 64-bit signed integers. |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 49 | * Strings. |
| 50 | * Lists (of any other types). |
| 51 | * Scopes (sort of like a dictionary, only for built-in stuff). |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 52 | |
| 53 | There are some built-in variables whose values depend on the current |
| 54 | environment. See `gn help` for more. |
| 55 | |
| 56 | There are purposefully many omissions in the language. There are no |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 57 | user-defined function calls, for example (templates are the closest thing). As |
| 58 | per the above design philosophy, if you need this kind of thing you're probably |
| 59 | doing it wrong. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 60 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 61 | The full grammar for language nerds is available in `gn help grammar`. |
| 62 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 63 | ### Strings |
| 64 | |
| 65 | Strings are enclosed in double-quotes and use backslash as the escape |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 66 | character. The only escape sequences supported are: |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 67 | |
| 68 | * `\"` (for literal quote) |
| 69 | * `\$` (for literal dollars sign) |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 70 | * `\\` (for literal backslash) |
| 71 | |
| 72 | Any other use of a backslash is treated as a literal backslash. So, for |
| 73 | example, `\b` used in patterns does not need to be escaped, nor do most Windows |
| 74 | paths like `"C:\foo\bar.h"`. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 75 | |
| 76 | Simple variable substitution is supported via `$`, where the word |
| 77 | following the dollars sign is replaced with the value of the variable. |
| 78 | You can optionally surround the name with `{}` if there is not a |
| 79 | non-variable-name character to terminate the variable name. More complex |
| 80 | expressions are not supported, only variable name substitution. |
| 81 | |
| 82 | ``` |
| 83 | a = "mypath" |
| 84 | b = "$a/foo.cc" # b -> "mypath/foo.cc" |
| 85 | c = "foo${a}bar.cc" # c -> "foomypathbar.cc" |
| 86 | ``` |
| 87 | |
Quinten Yearsley | 030b729 | 2017-07-18 16:13:31 +0000 | [diff] [blame] | 88 | You can encode 8-bit characters using "$0xFF" syntax, so a string with newlines |
| 89 | (hex 0A) would `"look$0x0Alike$0x0Athis"`. |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 90 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 91 | ### Lists |
| 92 | |
Pascal Perez | 445ac32 | 2019-06-24 14:32:00 -0400 | [diff] [blame] | 93 | Aside from telling empty lists from non empty lists (`a == []`), there is no |
| 94 | way to get the length of a list. If you find yourself wanting to do this kind |
| 95 | of thing, you're trying to do too much work in the build. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 96 | |
| 97 | Lists support appending: |
| 98 | |
| 99 | ``` |
| 100 | a = [ "first" ] |
| 101 | a += [ "second" ] # [ "first", "second" ] |
andybons | ee793e5 | 2015-10-14 11:49:30 -0700 | [diff] [blame] | 102 | a += [ "third", "fourth" ] # [ "first", "second", "third", "fourth" ] |
| 103 | b = a + [ "fifth" ] # [ "first", "second", "third", "fourth", "fifth" ] |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 104 | ``` |
| 105 | |
| 106 | Appending a list to another list appends the items in the second list |
| 107 | rather than appending the list as a nested member. |
| 108 | |
| 109 | You can remove items from a list: |
| 110 | |
| 111 | ``` |
| 112 | a = [ "first", "second", "third", "first" ] |
| 113 | b = a - [ "first" ] # [ "second", "third" ] |
Anton Paymyshev | 2c801de | 2020-05-20 12:26:42 +0700 | [diff] [blame] | 114 | a -= [ "second" ] # [ "first", "third", "first" ] |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 115 | ``` |
| 116 | |
| 117 | The - operator on a list searches for matches and removes all matching |
| 118 | items. Subtracting a list from another list will remove each item in the |
| 119 | second list. |
| 120 | |
| 121 | If no matching items are found, an error will be thrown, so you need to |
| 122 | know in advance that the item is there before removing it. Given that |
| 123 | there is no way to test for inclusion, the main use-case is to set up a |
| 124 | master list of files or flags, and to remove ones that don't apply to |
| 125 | the current build based on various conditions. |
| 126 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 127 | Stylistically, prefer to only add to lists and have each source file or |
| 128 | dependency appear once. This is the opposite of the advice Chrome-team used to |
| 129 | give for GYP (GYP would prefer to list all files, and then remove the ones you |
| 130 | didn't want in conditionals). |
| 131 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 132 | Lists support zero-based subscripting to extract values: |
| 133 | |
| 134 | ``` |
| 135 | a = [ "first", "second", "third" ] |
| 136 | b = a[1] # -> "second" |
| 137 | ``` |
| 138 | |
| 139 | The \[\] operator is read-only and can not be used to mutate the |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 140 | list. The primary use-case of this is when an external script returns |
| 141 | several known values and you want to extract them. |
| 142 | |
| 143 | There are some cases where it's easy to overwrite a list when you mean |
| 144 | to append to it instead. To help catch this case, it is an error to |
| 145 | assign a nonempty list to a variable containing an existing nonempty |
| 146 | list. If you want to get around this restriction, first assign the |
| 147 | destination variable to the empty list. |
| 148 | |
| 149 | ``` |
| 150 | a = [ "one" ] |
| 151 | a = [ "two" ] # Error: overwriting nonempty list with a nonempty list. |
| 152 | a = [] # OK |
| 153 | a = [ "two" ] # OK |
| 154 | ``` |
| 155 | |
| 156 | Note that execution of the build script is done without intrinsic |
| 157 | knowledge of the meaning of the underlying data. This means that it |
| 158 | doesn't know that `sources` is a list of file names, for example. So if |
| 159 | you remove an item, it must match the literal string rather than |
| 160 | specifying a different name that will resolve to the same file name. |
| 161 | |
| 162 | ### Conditionals |
| 163 | |
| 164 | Conditionals look like C: |
| 165 | |
| 166 | ``` |
| 167 | if (is_linux || (is_win && target_cpu == "x86")) { |
| 168 | sources -= [ "something.cc" ] |
| 169 | } else if (...) { |
| 170 | ... |
| 171 | } else { |
| 172 | ... |
andybons | ee793e5 | 2015-10-14 11:49:30 -0700 | [diff] [blame] | 173 | } |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 174 | ``` |
| 175 | |
| 176 | You can use them in most places, even around entire targets if the |
| 177 | target should only be declared in certain circumstances. |
| 178 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 179 | ### Looping |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 180 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 181 | You can iterate over a list with `foreach`. This is discouraged. Most things |
| 182 | the build should do can normally be expressed without doing this, and if you |
| 183 | find it necessary it may be an indication you're doing too much work in the |
| 184 | metabuild. |
| 185 | |
| 186 | ``` |
| 187 | foreach(i, mylist) { |
| 188 | print(i) # Note: i is a copy of each element, not a reference to it. |
| 189 | } |
| 190 | ``` |
| 191 | |
| 192 | ### Function calls |
| 193 | |
| 194 | Simple function calls look like most other languages: |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 195 | |
| 196 | ``` |
| 197 | print("hello, world") |
| 198 | assert(is_win, "This should only be executed on Windows") |
| 199 | ``` |
| 200 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 201 | Such functions are built-in and the user can not define new ones. |
| 202 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 203 | Some functions take a block of code enclosed by `{ }` following them: |
| 204 | |
| 205 | ``` |
| 206 | static_library("mylibrary") { |
| 207 | sources = [ "a.cc" ] |
| 208 | } |
| 209 | ``` |
| 210 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 211 | Most of these define targets. The user can define new functions like this |
| 212 | with the template mechanism discussed below. |
| 213 | |
| 214 | Precisely, this expression means that the block becomes an argument to the |
| 215 | function for the function to execute. Most of the block-style functions execute |
| 216 | the block and treat the resulting scope as a dictionary of variables to read. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 217 | |
| 218 | ### Scoping and execution |
| 219 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 220 | Files and function calls followed by `{ }` blocks introduce new scopes. Scopes |
| 221 | are nested. When you read a variable, the containing scopes will be searched in |
| 222 | reverse order until a matching name is found. Variable writes always go to the |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 223 | innermost scope. |
| 224 | |
| 225 | There is no way to modify any enclosing scope other than the innermost |
| 226 | one. This means that when you define a target, for example, nothing you |
| 227 | do inside of the block will "leak out" into the rest of the file. |
| 228 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 229 | `if`/`else`/`foreach` statements, even though they use `{ }`, do not introduce |
| 230 | a new scope so changes will persist outside of the statement. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 231 | |
| 232 | ## Naming things |
| 233 | |
| 234 | ### File and directory names |
| 235 | |
| 236 | File and directory names are strings and are interpreted as relative to |
| 237 | the current build file's directory. There are three possible forms: |
| 238 | |
| 239 | Relative names: |
| 240 | |
| 241 | ``` |
| 242 | "foo.cc" |
| 243 | "src/foo.cc" |
| 244 | "../src/foo.cc" |
| 245 | ``` |
| 246 | |
| 247 | Source-tree absolute names: |
| 248 | |
| 249 | ``` |
| 250 | "//net/foo.cc" |
| 251 | "//base/test/foo.cc" |
| 252 | ``` |
| 253 | |
| 254 | System absolute names (rare, normally used for include directories): |
| 255 | |
| 256 | ``` |
| 257 | "/usr/local/include/" |
| 258 | "/C:/Program Files/Windows Kits/Include" |
| 259 | ``` |
| 260 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 261 | ## Build configuration |
| 262 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 263 | ## Targets |
| 264 | |
| 265 | A target is a node in the build graph. It usually represents some kind |
| 266 | of executable or library file that will be generated. Targets depend on |
| 267 | other targets. The built-in target types (see `gn help <targettype>` for |
| 268 | more help) are: |
| 269 | |
| 270 | * `action`: Run a script to generate a file. |
| 271 | * `action_foreach`: Run a script once for each source file. |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 272 | * `bundle_data`: Declare data to go into a Mac/iOS bundle. |
| 273 | * `create_bundle`: Creates a Mac/iOS bundle. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 274 | * `executable`: Generates an executable file. |
| 275 | * `group`: A virtual dependency node that refers to one or more other |
| 276 | targets. |
| 277 | * `shared_library`: A .dll or .so. |
andybons | ee793e5 | 2015-10-14 11:49:30 -0700 | [diff] [blame] | 278 | * `loadable_module`: A .dll or .so loadable only at runtime. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 279 | * `source_set`: A lightweight virtual static library (usually |
| 280 | preferrable over a real static library since it will build faster). |
| 281 | * `static_library`: A .lib or .a file (normally you'll want a |
andybons | ee793e5 | 2015-10-14 11:49:30 -0700 | [diff] [blame] | 282 | `source_set` instead). |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 283 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 284 | You can extend this to make custom target types using templates (see below). In |
| 285 | Chrome some of the more commonly-used templates are: |
| 286 | |
| 287 | * `component`: Either a source set or shared library, depending on the |
| 288 | build type. |
Quinten Yearsley | 030b729 | 2017-07-18 16:13:31 +0000 | [diff] [blame] | 289 | * `test`: A test executable. On mobile this will create the appropriate |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 290 | native app type for tests. |
| 291 | * `app`: Executable or Mac/iOS application. |
| 292 | * `android_apk`: Make an APK. There are a _lot_ of other Android ones, see |
| 293 | `//build/config/android/rules.gni`. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 294 | |
| 295 | ## Configs |
| 296 | |
| 297 | Configs are named objects that specify sets of flags, include |
| 298 | directories, and defines. They can be applied to a target and pushed to |
| 299 | dependent targets. |
| 300 | |
| 301 | To define a config: |
| 302 | |
| 303 | ``` |
| 304 | config("myconfig") { |
| 305 | includes = [ "src/include" ] |
| 306 | defines = [ "ENABLE_DOOM_MELON" ] |
| 307 | } |
| 308 | ``` |
| 309 | |
| 310 | To apply a config to a target: |
| 311 | |
| 312 | ``` |
| 313 | executable("doom_melon") { |
| 314 | configs = [ ":myconfig" ] |
| 315 | } |
| 316 | ``` |
| 317 | |
| 318 | It is common for the build config file to specify target defaults that |
| 319 | set a default list of configs. Targets can add or remove to this list as |
| 320 | needed. So in practice you would usually use `configs += ":myconfig"` to |
| 321 | append to the list of defaults. |
| 322 | |
| 323 | See `gn help config` for more information about how configs are declared |
| 324 | and applied. |
| 325 | |
| 326 | ### Public configs |
| 327 | |
| 328 | A target can apply settings to other targets that depend on it. The most |
| 329 | common example is a third party target that requires some defines or |
| 330 | include directories for its headers to compile properly. You want these |
| 331 | settings to apply both to the compile of the third party library itself, |
| 332 | as well as all targets that use the library. |
| 333 | |
| 334 | To do this, you write a config with the settings you want to apply: |
| 335 | |
| 336 | ``` |
| 337 | config("my_external_library_config") { |
| 338 | includes = "." |
| 339 | defines = [ "DISABLE_JANK" ] |
| 340 | } |
| 341 | ``` |
| 342 | |
| 343 | Then this config is added to the target as a "public" config. It will |
| 344 | apply both to the target as well as targets that directly depend on it. |
| 345 | |
| 346 | ``` |
| 347 | shared_library("my_external_library") { |
| 348 | ... |
| 349 | # Targets that depend on this get this config applied. |
| 350 | public_configs = [ ":my_external_library_config" ] |
| 351 | } |
| 352 | ``` |
| 353 | |
| 354 | Dependent targets can in turn forward this up the dependency tree |
| 355 | another level by adding your target as a "public" dependency. |
| 356 | |
| 357 | ``` |
| 358 | static_library("intermediate_library") { |
| 359 | ... |
| 360 | # Targets that depend on this one also get the configs from "my external library". |
| 361 | public_deps = [ ":my_external_library" ] |
| 362 | } |
| 363 | ``` |
| 364 | |
| 365 | A target can forward a config to all dependents until a link boundary is |
| 366 | reached by setting it as an `all_dependent_config`. This is strongly |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 367 | discouraged as it can spray flags and defines over more of the build than |
| 368 | necessary. Instead, use public_deps to control which flags apply where. |
| 369 | |
| 370 | In Chrome, prefer the build flag header system (`build/buildflag_header.gni`) |
| 371 | for defines which prevents most screw-ups with compiler defines. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 372 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 373 | ## Templates |
| 374 | |
| 375 | Templates are GN's primary way to re-use code. Typically, a template |
| 376 | would expand to one or more other target types. |
| 377 | |
| 378 | ``` |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 379 | # Declares a script that compiles IDL files to source, and then compiles those |
| 380 | # source files. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 381 | template("idl") { |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 382 | # Always base helper targets on target_name so they're unique. Target name |
| 383 | # will be the string passed as the name when the template is invoked. |
| 384 | idl_target_name = "${target_name}_generate" |
| 385 | action_foreach(idl_target_name) { |
| 386 | ... |
| 387 | } |
| 388 | |
| 389 | # Your template should always define a target with the name target_name. |
| 390 | # When other targets depend on your template invocation, this will be the |
| 391 | # destination of that dependency. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 392 | source_set(target_name) { |
| 393 | ... |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 394 | deps = [ ":$idl_target_name" ] # Require the sources to be compiled. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 395 | } |
| 396 | } |
| 397 | ``` |
| 398 | |
| 399 | Typically your template definition would go in a `.gni` file and users |
| 400 | would import that file to see the template definition: |
| 401 | |
| 402 | ``` |
| 403 | import("//tools/idl_compiler.gni") |
| 404 | |
| 405 | idl("my_interfaces") { |
| 406 | sources = [ "a.idl", "b.idl" ] |
| 407 | } |
| 408 | ``` |
| 409 | |
| 410 | Declaring a template creates a closure around the variables in scope at |
| 411 | that time. When the template is invoked, the magic variable `invoker` is |
| 412 | used to read variables out of the invoking scope. The template would |
| 413 | generally copy the values its interested in into its own scope: |
| 414 | |
| 415 | ``` |
| 416 | template("idl") { |
| 417 | source_set(target_name) { |
| 418 | sources = invoker.sources |
| 419 | } |
| 420 | } |
| 421 | ``` |
| 422 | |
| 423 | The current directory when a template executes will be that of the |
| 424 | invoking build file rather than the template source file. This is so |
| 425 | files passed in from the template invoker will be correct (this |
| 426 | generally accounts for most file handling in a template). However, if |
| 427 | the template has files itself (perhaps it generates an action that runs |
| 428 | a script), you will want to use absolute paths ("//foo/...") to refer to |
| 429 | these files to account for the fact that the current directory will be |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 430 | unpredictable during invocation. See `gn help template` for more |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 431 | information and more complete examples. |
| 432 | |
| 433 | ## Other features |
| 434 | |
| 435 | ### Imports |
| 436 | |
| 437 | You can import `.gni` files into the current scope with the `import` |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 438 | function. This is _not_ an include in the C++ sense. The imported file is |
| 439 | executed independently and the resulting scope is copied into the current file |
| 440 | (C++ executes the included file in the current context of when the |
| 441 | include directive appeared). This allows the results of the import to be |
| 442 | cached, and also prevents some of the more "creative" uses of includes like |
| 443 | multiply-included files. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 444 | |
| 445 | Typically, a `.gni` would define build arguments and templates. See `gn |
| 446 | help import` for more. |
| 447 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 448 | Your `.gni` file can define temporary variables that are not exported files |
| 449 | that include it by using a preceding underscore in the name like `_this`. |
| 450 | |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 451 | ### Path processing |
| 452 | |
| 453 | Often you will want to make a file name or a list of file names relative |
| 454 | to a different directory. This is especially common when running |
| 455 | scripts, which are executed with the build output directory as the |
| 456 | current directory, while build files usually refer to files relative to |
| 457 | their containing directory. |
| 458 | |
| 459 | You can use `rebase_path` to convert directories. See `gn help |
| 460 | rebase_path` for more help and examples. Typical usage to convert a file |
| 461 | name relative to the current directory to be relative to the root build |
| 462 | directory would be: ``` new_paths = rebase_path("myfile.c", |
| 463 | root_build_dir) ``` |
| 464 | |
| 465 | ### Patterns |
| 466 | |
| 467 | Patterns are used to generate the output file names for a given set of |
| 468 | inputs for custom target types, and to automatically remove files from |
Sylvain Defresne | ad0a7ad | 2020-10-15 15:03:44 +0200 | [diff] [blame] | 469 | the list values (see `gn help filter_include` and `gn help filter_exclude`). |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 470 | |
eroman | bd8c922 | 2015-09-11 15:34:41 -0700 | [diff] [blame] | 471 | They are like simple regular expressions. See `gn help label_pattern` |
| 472 | for more. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 473 | |
| 474 | ### Executing scripts |
| 475 | |
| 476 | There are two ways to execute scripts. All external scripts in GN are in |
| 477 | Python. The first way is as a build step. Such a script would take some |
| 478 | input and generate some output as part of the build. Targets that invoke |
| 479 | scripts are declared with the "action" target type (see `gn help |
| 480 | action`). |
| 481 | |
| 482 | The second way to execute scripts is synchronously during build file |
| 483 | execution. This is necessary in some cases to determine the set of files |
| 484 | to compile, or to get certain system configurations that the build file |
| 485 | might depend on. The build file can read the stdout of the script and |
| 486 | act on it in different ways. |
| 487 | |
| 488 | Synchronous script execution is done by the `exec_script` function (see |
| 489 | `gn help exec_script` for details and examples). Because synchronously |
| 490 | executing a script requires that the current buildfile execution be |
| 491 | suspended until a Python process completes execution, relying on |
| 492 | external scripts is slow and should be minimized. |
| 493 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 494 | To prevent abuse, files permitted to call `exec_script` can be whitelisted in |
| 495 | the toplevel `.gn` file. Chrome does this to require additional code review |
| 496 | for such additions. See `gn help dotfile`. |
| 497 | |
| 498 | You can synchronously read and write files which is discouraged but |
| 499 | occasionally necessary when synchronously running scripts. The typical use-case |
| 500 | would be to pass a list of file names longer than the command-line limits of |
| 501 | the current platform. See `gn help read_file` and `gn help write_file` for how |
| 502 | to read and write files. These functions should be avoided if at all possible. |
| 503 | |
| 504 | Actions that exceed command-line length limits can use response files to |
| 505 | get around this limitation without synchronously writing files. See |
| 506 | `gn help response_file_contents`. |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 507 | |
| 508 | # Differences and similarities to Blaze |
| 509 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 510 | Blaze is Google's internal build system, now publicly released as |
| 511 | [Bazel](http://bazel.io/). It has inspired a number of other systems such as |
Quinten Yearsley | 030b729 | 2017-07-18 16:13:31 +0000 | [diff] [blame] | 512 | [Pants](http://www.pantsbuild.org/) and [Buck](http://facebook.github.io/buck/). |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 513 | |
| 514 | In Google's homogeneous environment, the need for conditionals is very |
| 515 | low and they can get by with a few hacks (`abi_deps`). Chrome uses |
| 516 | conditionals all over the place and the need to add these is the main |
| 517 | reason for the files looking different. |
| 518 | |
| 519 | GN also adds the concept of "configs" to manage some of the trickier |
| 520 | dependency and configuration problems which likewise don't arise on the |
| 521 | server. Blaze has a concept of a "configuration" which is like a GN |
| 522 | toolchain, but built into the tool itself. The way that toolchains work |
| 523 | in GN is a result of trying to separate this concept out into the build |
| 524 | files in a clean way. |
| 525 | |
brettw | ad3fccd | 2016-03-29 17:22:42 -0700 | [diff] [blame] | 526 | GN keeps some GYP concept like "all dependent" settings which work a bit |
| 527 | differently in Blaze. This is partially to make conversion from the existing |
| 528 | GYP code easier, and the GYP constructs generally offer more fine-grained |
| 529 | control (which is either good or bad, depending on the situation). |
dpranke | c04440d | 2015-04-06 11:42:23 -0700 | [diff] [blame] | 530 | |
| 531 | GN also uses GYP names like "sources" instead of "srcs" since |
| 532 | abbreviating this seems needlessly obscure, although it uses Blaze's |
| 533 | "deps" since "dependencies" is so hard to type. Chromium also compiles |
| 534 | multiple languages in one target so specifying the language type on the |
| 535 | target name prefix was dropped (e.g. from `cc_library`). |