summaryrefslogtreecommitdiffstats
path: root/tools/gn/docs/check.md
blob: e99f6a4879a0e1eaa8bf060db0eb3e88952858ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# GN Check

GN has several different ways to check dependencies. Many of them are checked by
the `gn check` command. Running checks involve opening and scanning all source
files so this isn't run every time a build is updated. To run check on an
existing build:

    gn check out/mybuild

To run the check as part of the "gen" command to update the build (this is what
the bots do):

    gn gen out/mybuild --check

[TOC]

## Concepts

### Visibility

Targets can control which other targets may depend on them by specifying
`visibility`. Visibility is always checked when running any GN command (not just
`gn check`.

By default, targets are "public" meaning any target can depend on them. If you
supply a list, visibility will be listed to those targets (possibly including
wildcards):

```
visibility = [
  ":*",  # All targets in this file.
  "//content/*",  # All targets in content and any subdirectory thereof.
  "//tools:doom_melon",  # This specific target.
]
```

See `gn help visibility` for more details and examples.

### Public header files

Targets can control which headers may be included by dependent targets so as to
define a public API. If your target specifies only `sources`, then all headers
listed there are public and can be included by all dependents.

If your target defines a `public` variable, only the files listed in that list
will be public. Files in `sources` but not `public` (they can be in both or only
one) may not be included by dependent targets.

```
source_set("foo") {
  public = [
    "foo.h",
    "foo_config.h",
  ]
  sources = [
    "foo.cc",
    "foo.h",
    "bar.cc",
    "bar.h",
  ]
}
```

### Public dependencies

In order to include files from your target, that target must be listed in your
target's dependencies. By default, transitively depending on a target doesn't
give your files this privilege.

If a target exposes a dependency as part of its public API, then it can list
that dependency as a `public_deps`:

```
source_set("foo") {
  sources = [ ... ]
  public_deps = [
    "//base",
  ]
  deps = [
    "//tools/doom_melon",
  ]
}
```

Targets that depend on `foo` can include files from `base` but not from
`doom_melon`. To include public headers from `doom\_melon, a target would need
to depend directly on it.

Public dependencies work transitively, so listing a target as a public
dependency also exposes that target's public dependencies. Along with the
ability to include headers, public dependencies forward the `public_configs`
which allow settings like defines and include directories to apply to
dependents.

## Putting it all together

In order to include a header from target Y in a file that is part of target X:

*   X must be in Y's `visibility` list (or B must have no `visibility` defined).
*   The header must be in Y's `public` headers (or Y must have no `public`
    variable defined).
*   X must depend directly on Y, or there must be a path from X to Y following
    only public dependencies.

### What gets checked

Chrome currently doesn't come close to passing a `gn check` pass. You can check
specific targets or subtrees for issues:

    gn check out/mybuild //base

    gn check out/mybuild "//mojo/*"