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