blob: 49f16ae08be33b2a32e749ad653eb33590518e20 [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
53## Configuring goma
54
55
56Run `gn args out/Default` (substituting your build directory as needed).
57Add:
58
59```
60use_goma = true
61goma_dir = "~/foo/bar/goma"
62```
63
64If your goma is in the default location (`~/goma`) then you can omit the
65`goma_dir` line.
66
67## Configuring component mode
68
69This is a build arg like the goma flags. run `gn args out/Default` and add:
70
71```
72is_component_build = true
73```
74
75## Step-by-step
76
77### Adding a build file
78
79Create a `tools/gn/tutorial/BUILD.gn` file and enter the following:
80
81```
82executable("hello_world") {
83 sources = [
84 "hello_world.cc",
85 ]
86}
87```
88
89There should already be a `hello_world.cc` file in that directory,
90containing what you expect. That's it! Now we just need to tell the
91build about this file. Open the `BUILD.gn` file in the root directory
92and add the label of this target to the dependencies of the root group
93(a "group" target is a meta-target that is just a collection of other
94targets):
95
96```
97group("root") {
98 deps = [
99 ...
100 "//url",
101 "//tools/gn/tutorial:hello_world",
102 ]
103}
104```
105
106You can see the label of your target is "//" (indicating the source
107root), followed by the directory name, a colon, and the target name.
108
109### Testing your addition
110
111From the command line in the source root directory:
112
113```
114gn gen out/Default
115ninja -C out/Default hello_world
116out/Default/hello_world
117```
118
119GN encourages target names for static libraries that aren't globally
120unique. To build one of these, you can pass the label with no leading
121"//" to ninja:
122
123```
124ninja -C out/Default tools/gn/tutorial:hello_world
125```
126
127### Declaring dependencies
128
129Let's make a static library that has a function to say hello to random
130people. There is a source file `hello.cc` in that directory which has a
131function to do this. Open the `tools/gn/tutorial/BUILD.gn` file and add
132the static library to the bottom of the existing file:
133
134```
135static_library("hello") {
136 sources = [
137 "hello.cc",
138 ]
139}
140```
141
142Now let's add an executable that depends on this library:
143
144```
145executable("say_hello") {
146 sources = [
147 "say_hello.cc",
148 ]
149 deps = [
150 ":hello",
151 ]
152}
153```
154
155This executable includes one source file,and depends on the previous
156static library. The static library is referenced by its label in the
157`deps`. You could have used the full label `//tools/gn/tutorial:hello`
158but if you're referencing a target in the same build file, you can use
159the shortcut `:hello`.
160
161### Test the static library version
162
163From the command line in the source root directory:
164
165```
166ninja -C out/Default say_hello
167out/Default/say_hello
168```
169
170Note that you **didn't** need to re-run GN.GN will automatically rebuild
171the ninja files when any build file has changed. You know this happens
172when ninja prints `[1/1] Regenerating ninja files` at the beginning of
173execution.
174
175### Compiler settings
176
177Our hello library has a new feature, the ability to say hello to two
178people at once. This feature is controlled by defining `TWO_PEOPLE`. We
179can add defines like so:
180
181```
182static_library("hello") {
183 sources = [
184 "hello.cc",
185 ]
186 defines = [
187 "TWO_PEOPLE",
188 ]
189}
190```
191
192### Putting settings in a config
193
194However, users of the library also need to know about this define, and
195putting it in the static library target defines it only for the files
196there. If somebody else includes `hello.h`, they won't see the new
197definition. To see the new definition, everybody will have to define
198`TWO_PEOPLE`.
199
200GN has a concept called a "config" which encapsulates settings. Let's
201create one that defines our preprocessor define:
202
203```
204config("hello_config") {
205 defines = [
206 "TWO_PEOPLE",
207 ]
208}
209```
210
211To apply these settings to your target, you only need to add the
212config's label to the list of configs in the target:
213
214```
215static_library("hello") {
216 ...
217 configs += [
218 ":hello_config",
219 ]
220}
221```
222
223Note that you need "+=" here instead of "=" since the build
224configuration has a default set of configs applied to each target that
225set up the default build stuff. You want to add to this list rather than
226overwrite it. To see the default configs, you can use the `print`
227function in the build file or the `desc` command-line subcommand (see
228below for examples of both).
229
230### Dependent configs
231
232This nicely encapsulates our settings, but still requires everybody that
233uses our library to set the config on themselves. It would be nice if
234everybody that depends on our `hello` library can get this
235automatically. Change your library definition to:
236
237```
238static_library("hello") {
239 sources = [
240 "hello.cc",
241 ]
242 all_dependent_configs = [
243 ":hello_config"
244 ]
245}
246```
247
248This applies the `hello_config` to the `hello` target itself, plus all
249targets that depend on transitively depend on the current one. Now
250everybody that depends on us will get our settings. You can also set
251`direct_dependent_configs` which applies only to targets that directly
252depend on your target (not transitively).
253
254Now if you compile and run, you'll see the new version with two people:
255
256```
257> ninja -C out/Default say_hello
258ninja: Entering directory 'out/Default'
259[1/1] Regenerating ninja files
260[4/4] LINK say_hello
261> out/Default/say_hello
262Hello, Bill and Ted.
263```
264
265## Don't know what's going on?
266
267You can run GN in verbose mode to see lots of messages about what it's
268doing. Use `-v` for this.
269
270### Print debugging
271
272There is a `print` command which just writes to stdout:
273
274```
275static_library("hello") {
276 ...
277 print(configs)
278}
279```
280
281This will print all of the configs applying to your target (including
282the default ones).
283
284### The "desc" command
285
286You can run `gn desc <build_dir> <targetname>` to get information about
287a given target:
288
289```
290gn desc out/Default //tools/gn/tutorial:say_hello
291```
292
293will print out lots of exciting information. You can also print just one
294section. Lets say you wanted to know where your `TWO_PEOPLE` define
295came from on the `say_hello` target:
296
297```
298> gn desc out/Default //tools/gn/tutorial:say_hello defines --blame
299...lots of other stuff omitted...
300 From //tools/gn/tutorial:hello_config
301 (Added by //tools/gn/tutorial/BUILD.gn:12)
302 TWO_PEOPLE
303```
304
305You can see that `TWO_PEOPLE` was defined by a config, and you can also
306see the which like caused that config to be applied to your target (in
307this case, the `all_dependent_configs` line).
308
309Another particularly interesting variation:
310
311```
312gn desc out/Default //base:base_i18n deps --tree
313```
314
315See `gn help desc` for more.
316
317### Performance
318
319You can see what took a long time by running it with the --time command
320line flag. This will output a summary of timings for various things.
321
322You can also make a trace of how the build files were executed:
323
324```
325gn --tracelog=mylog.trace
326```
327
328and you can load the resulting file in Chrome's `about:tracing` page to
329look at everything.