blob: 8b064deb18d5f0dedc5e71ec9276f7b2fb60403f [file] [log] [blame] [view]
dpranke12a42352015-04-06 18:42:231# GN Quick Start guide
2
3[TOC]
4
5## Running GN
6
7You just run `gn` from the command line. There is a script in
8depot\_tools (which is presumably on your path) with this name. The
9script will find the binary in the source tree containing the current
10directory and run it.
11
12## Setting up a build
13
14In GYP, the system would generate `Debug` and `Release` build
15directories for you and configure them accordingly. GN doesn't do this.
16Instead, you set up whatever build directory you want with whatever
17configuration you want. The Ninja files will be automatically
18regenerated if they're out of date when you build in that directory.
19
20To make a build directory:
21
22```
23gn gen out/my_build
24```
25
26## Passing build arguments
27
28Set build arguments on your build directory by running:
29
30```
31gn args out/my_build
32```
33
34This will bring up an editor. Type build args into that file like this:
35
36```
37is_component_build = true
38is_debug = false
39```
40
41You can see the list of available arguments and their default values by
42typing
43
44```
45gn args --list out/my_build
46```
47
48on the command line. See "Taking build arguments" below for information
49on how to use these in your code. (Note that you have to specify the
50build directory for this command because the available arguments can
51change according to what's set.
52
brettw314880aa2015-09-11 20:09:2753Chrome developers can also read the [Chrome-specific build
54configuration](http://www.chromium.org/developers/gn-build-configuration)
55instructions for more information.
56
dmazzoni925b21632015-07-16 19:46:0557## Cross-compiling to a target OS or architecture
58
59Run `gn args out/Default` (substituting your build directory as needed) and
60add one or more of the following lines for common cross-compiling options.
61
62```
63target_os = "chromeos"
64target_os = "android"
65
66target_cpu = "arm"
67target_cpu = "x86"
68target_cpu = "x64"
69```
70
71See [GNCrossCompiles](cross_compiles.md) for more info.
72
dpranke12a42352015-04-06 18:42:2373## Configuring goma
74
dpranke12a42352015-04-06 18:42:2375Run `gn args out/Default` (substituting your build directory as needed).
76Add:
77
78```
79use_goma = true
andybons19c81c682015-07-30 22:38:0180goma_dir = "~/foo/bar/goma"
dpranke12a42352015-04-06 18:42:2381```
82
83If your goma is in the default location (`~/goma`) then you can omit the
84`goma_dir` line.
85
86## Configuring component mode
87
88This is a build arg like the goma flags. run `gn args out/Default` and add:
89
90```
91is_component_build = true
92```
93
94## Step-by-step
95
96### Adding a build file
97
98Create a `tools/gn/tutorial/BUILD.gn` file and enter the following:
99
100```
101executable("hello_world") {
102 sources = [
103 "hello_world.cc",
104 ]
105}
106```
107
108There should already be a `hello_world.cc` file in that directory,
109containing what you expect. That's it! Now we just need to tell the
110build about this file. Open the `BUILD.gn` file in the root directory
andybons19c81c682015-07-30 22:38:01111and add the label of this target to the dependencies of one of the root
112groups (a "group" target is a meta-target that is just a collection of
113other targets):
dpranke12a42352015-04-06 18:42:23114
115```
116group("root") {
117 deps = [
118 ...
119 "//url",
120 "//tools/gn/tutorial:hello_world",
121 ]
122}
123```
124
125You can see the label of your target is "//" (indicating the source
126root), followed by the directory name, a colon, and the target name.
127
128### Testing your addition
129
130From the command line in the source root directory:
131
132```
133gn gen out/Default
134ninja -C out/Default hello_world
135out/Default/hello_world
136```
137
138GN encourages target names for static libraries that aren't globally
139unique. To build one of these, you can pass the label with no leading
140"//" to ninja:
141
142```
143ninja -C out/Default tools/gn/tutorial:hello_world
144```
145
146### Declaring dependencies
147
148Let's make a static library that has a function to say hello to random
149people. There is a source file `hello.cc` in that directory which has a
150function to do this. Open the `tools/gn/tutorial/BUILD.gn` file and add
151the static library to the bottom of the existing file:
152
153```
154static_library("hello") {
155 sources = [
156 "hello.cc",
157 ]
158}
159```
160
161Now let's add an executable that depends on this library:
162
163```
164executable("say_hello") {
165 sources = [
166 "say_hello.cc",
167 ]
168 deps = [
169 ":hello",
170 ]
171}
172```
173
andybons19c81c682015-07-30 22:38:01174This executable includes one source file and depends on the previous
dpranke12a42352015-04-06 18:42:23175static library. The static library is referenced by its label in the
176`deps`. You could have used the full label `//tools/gn/tutorial:hello`
177but if you're referencing a target in the same build file, you can use
178the shortcut `:hello`.
179
180### Test the static library version
181
182From the command line in the source root directory:
183
184```
185ninja -C out/Default say_hello
186out/Default/say_hello
187```
188
andybons19c81c682015-07-30 22:38:01189Note that you **didn't** need to re-run GN. GN will automatically rebuild
dpranke12a42352015-04-06 18:42:23190the ninja files when any build file has changed. You know this happens
191when ninja prints `[1/1] Regenerating ninja files` at the beginning of
192execution.
193
194### Compiler settings
195
196Our hello library has a new feature, the ability to say hello to two
197people at once. This feature is controlled by defining `TWO_PEOPLE`. We
198can add defines like so:
199
200```
201static_library("hello") {
202 sources = [
203 "hello.cc",
204 ]
205 defines = [
206 "TWO_PEOPLE",
207 ]
208}
209```
210
211### Putting settings in a config
212
213However, users of the library also need to know about this define, and
214putting it in the static library target defines it only for the files
215there. If somebody else includes `hello.h`, they won't see the new
216definition. To see the new definition, everybody will have to define
217`TWO_PEOPLE`.
218
219GN has a concept called a "config" which encapsulates settings. Let's
220create one that defines our preprocessor define:
221
222```
223config("hello_config") {
224 defines = [
225 "TWO_PEOPLE",
226 ]
227}
228```
229
230To apply these settings to your target, you only need to add the
231config's label to the list of configs in the target:
232
233```
234static_library("hello") {
235 ...
236 configs += [
237 ":hello_config",
238 ]
239}
240```
241
242Note that you need "+=" here instead of "=" since the build
243configuration has a default set of configs applied to each target that
244set up the default build stuff. You want to add to this list rather than
245overwrite it. To see the default configs, you can use the `print`
246function in the build file or the `desc` command-line subcommand (see
247below for examples of both).
248
249### Dependent configs
250
251This nicely encapsulates our settings, but still requires everybody that
252uses our library to set the config on themselves. It would be nice if
253everybody that depends on our `hello` library can get this
254automatically. Change your library definition to:
255
256```
257static_library("hello") {
258 sources = [
259 "hello.cc",
260 ]
261 all_dependent_configs = [
262 ":hello_config"
263 ]
264}
265```
266
267This applies the `hello_config` to the `hello` target itself, plus all
machenbachb541f712016-01-14 15:43:09268targets that transitively depend on the current one. Now everybody that
269depends on us will get our settings. You can also set `public_configs`
270which applies only to targets that directly depend on your target (not
271transitively).
dpranke12a42352015-04-06 18:42:23272
273Now if you compile and run, you'll see the new version with two people:
274
275```
276> ninja -C out/Default say_hello
277ninja: Entering directory 'out/Default'
278[1/1] Regenerating ninja files
279[4/4] LINK say_hello
280> out/Default/say_hello
andybons19c81c682015-07-30 22:38:01281Hello, Bill and Joy.
dpranke12a42352015-04-06 18:42:23282```
283
jessicag4a8943a2016-03-11 19:38:17284## Add a new build argument
285
286You declare which arguments you accept and specify default values via
287`declare_args`.
288
289```
290declare_args() {
291 enable_teleporter = true
292 enable_doom_melon = false
293}
294```
295
296See `gn help buildargs` for an overview of how this works.
297See `gn help declare_args` for specifics on declaring them.
298
299It is an error to declare a given argument more than once in a given scope, so
300care should be used in scoping and naming arguments.
301
dpranke12a42352015-04-06 18:42:23302## Don't know what's going on?
303
304You can run GN in verbose mode to see lots of messages about what it's
305doing. Use `-v` for this.
306
307### Print debugging
308
309There is a `print` command which just writes to stdout:
310
311```
312static_library("hello") {
313 ...
314 print(configs)
315}
316```
317
318This will print all of the configs applying to your target (including
319the default ones).
320
321### The "desc" command
322
323You can run `gn desc <build_dir> <targetname>` to get information about
324a given target:
325
326```
327gn desc out/Default //tools/gn/tutorial:say_hello
328```
329
330will print out lots of exciting information. You can also print just one
331section. Lets say you wanted to know where your `TWO_PEOPLE` define
332came from on the `say_hello` target:
333
334```
335> gn desc out/Default //tools/gn/tutorial:say_hello defines --blame
336...lots of other stuff omitted...
337 From //tools/gn/tutorial:hello_config
338 (Added by //tools/gn/tutorial/BUILD.gn:12)
339 TWO_PEOPLE
340```
341
342You can see that `TWO_PEOPLE` was defined by a config, and you can also
machenbachb541f712016-01-14 15:43:09343see the which line caused that config to be applied to your target (in
dpranke12a42352015-04-06 18:42:23344this case, the `all_dependent_configs` line).
345
346Another particularly interesting variation:
347
348```
349gn desc out/Default //base:base_i18n deps --tree
350```
351
352See `gn help desc` for more.
353
354### Performance
355
356You can see what took a long time by running it with the --time command
357line flag. This will output a summary of timings for various things.
358
359You can also make a trace of how the build files were executed:
360
361```
362gn --tracelog=mylog.trace
363```
364
365and you can load the resulting file in Chrome's `about:tracing` page to
366look at everything.