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