The Chromium Chronicle #15: Restricting Target Visibility
Episode 15: by Joe Mason in Montreal, PQ (November, 2020)
Chrome is a big project with many sub-systems. It's common to find code written for one component that would be useful elsewhere, but might have hidden restrictions. For safety, limit external access to dangerous functionality. For instance, a custom function tuned for specific performance needs:
// Blazing fast for 2-char strings, O(n^3) otherwise.
std::string ConcatShortStringsFast(const std::string& a, const std::string& b);
There are several ways to restrict access. GN visibility rules stop code outside your component from depending on a target. By default targets are visible to all, but you can modify that:
# In components/restricted_component/BUILD.gn
visibility = [
# Applies to all targets in this file.
# Only the given targets can depend on them.
# This dangerous target should be locked down even more.
visibility = [ "//components/restricted_component:privileged_target" ]
Visibility declarations are validated with
gn check, which runs as part of every GN build.
Another mechanism is DEPS
include_rules, which limits access to header files. Every directory inherits
include_rules from its parent, and can modify those rules in its own
DEPS file. All header files included from outside directories must be allowed by the
# In //components/authorized_other_component/DEPS
include_rules = [
# Common directories like //base are inherited from
# //components/DEPS or //DEPS. Also allow includes from
# restricted_component, but not restricted_component/internal.
# But do allow a single header from internal, for testing.
To ensure these dependencies are appropriate, changes that add a directory to
include_rules must be approved by that directory's
OWNERS. No approval is needed to restrict a directory using
include_rules! You can ensure that everyone changing your component remembers not to use certain headers by adding an
include_rule forbidding them.
include_rules are checked by the presubmit, so you won't see any errors until you try to upload a change. To test
include_rules without uploading, run