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
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.
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", ] }
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.
In order to include a header from target Y in a file that is part of target X:
visibility
list (or B must have no visibility
defined).public
headers (or Y must have no public
variable defined).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/*"