Skip to content

Commit

Permalink
Simplify visibility docs
Browse files Browse the repository at this point in the history
Correct legacy uses of "rule" terminology to "target". Eliminate extra example verbosity.

Follow-up work to #8982.

RELNOTES: None
PiperOrigin-RevId: 311414362
  • Loading branch information
brandjon authored and copybara-github committed May 13, 2020
1 parent 5d98324 commit 3faaf03
Showing 1 changed file with 43 additions and 58 deletions.
101 changes: 43 additions & 58 deletions site/docs/visibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,79 +2,64 @@
layout: documentation
title: Visibility
---
All rule targets have a `visibility` attribute that takes a list of labels. One
target is visible to another if they are in the same package, or if they are
granted visibility by one of the labels.

# Visibility
Each label has one of the following forms:

Visibility controls whether a target can be used by other packages. It is an
important tool to structure the code when a codebase grows: it lets developers
distinguish between implementation details and libraries other people can depend
on.
* `"//visibility:public"`: Anyone can use this target. (May not be combined
with any other specification.)

If you need to disable the visibility check (for example when experimenting),
use `--check_visibility=false`.
* `"//visibility:private"`: Only targets in this package can use this
target. (May not be combined with any other specification.)

## Visibility labels
* `"//foo/bar:__pkg__"`: Grants access to targets defined in `//foo/bar` (but
not its subpackages). Here, `__pkg__` is a special piece of syntax
representing all of the targets in a package.

There are five forms a visibility label can take:
* `"//foo/bar:__subpackages__"`: Grants access to targets defined in
`//foo/bar`, or any of its direct or indirect subpackages. Again,
`__subpackages__` is special syntax.

* `["//visibility:public"]`: Anyone can use this rule.
* `["//visibility:private"]`: Only rules in this package can use this rule.
* `"//foo/bar:my_package_group"`: Grants access to all of the packages named
by the given [package group](be/functions.html#package_group). This can be
used to allow access to an entire subtree, such as `//myproj/...`.

* `["//some/package:__pkg__", "//other/package:__pkg__"]`: Only rules in
`some/package/BUILD` and `other/package/BUILD` have access to this rule.
Note that sub-packages do not have access to the rule; for example,
`//some/package/foo:bar` or `//other/package/testing:bla` wouldn't have
access. `__pkg__` is a special target and must be used verbatim. It
represents all of the rules in the package.
* `["//project:__subpackages__", "//other:__subpackages__"]`: Only rules in
packages `project` or `other` or in one of their sub-packages have access to
this rule. For example, `//project:rule`, `//project/library:lib` or
`//other/testing/internal:munge` are allowed to depend on this rule (but not
`//independent:evil`)
* `["//some/package:my_package_group"]`: A
[package group](be/functions.html#package_group) is a named set of package
names. Package groups can also grant access rights to entire subtrees,
e.g.`//myproj/...`.
For example, if `//some/package:mytarget` has its `visibility` set to
`[":__subpackages__", "//tests:__pkg__"]`, then it could be used by any target
that is part of the `//some/package/...` source tree, as well as targets defined
in `//tests/BUILD`, but not by targets defined in `//tests/integration/BUILD`.

The visibility specifications of `//visibility:public` and
`//visibility:private` can not be combined with any other visibility
specifications.
## Visibility of a rule target

A visibility specification may contain a combination of package labels (i.e.
`//foo:__pkg__`) and `package_group`s.

## Visibility of a rule

If a rule does specify the visibility attribute, that specification overrides
any [`default_visibility`](be/functions.html#package.default_visibility)
attribute of the [`package`](functions.html#package) statement in the BUILD
file containing the rule.

Otherwise, if a rule does not specify the visibility attribute, the
default_visibility of the package is used.

Otherwise, if the default_visibility for the package is not specified,
`//visibility:private` is used.
If a rule target does not set the `visibility` attribute, its visibility is
given by the
[`default_visibility`](be/functions.html#package.default_visibility) that was
specified in the [`package`](functions.html#package) statement of the target's
BUILD file. If there is no such `default_visibility` declaration, the visibility
is `//visibility:private`.

### Example

File `//frobber/bin/BUILD`:

```python
# This rule is visible to everyone
# This target is visible to everyone
cc_binary(
name = "executable",
visibility = ["//visibility:public"],
deps = [":library"],
)

# This rule is visible only to rules declared in the same package
# This target is visible only to targets declared in the same package
cc_library(
name = "library",
visibility = ["//visibility:private"],
# No visibility -- defaults to private since no
# package(default_visibility = ...) was used.
)

# This rule is visible to rules in package //object and //noun
# This target is visible to targets in package //object and //noun
cc_library(
name = "subject",
visibility = [
Expand All @@ -84,7 +69,7 @@ cc_library(
)

# See package group "//frobber:friends" (below) for who can
# access this rule.
# access this target.
cc_library(
name = "thingy",
visibility = ["//frobber:friends"],
Expand All @@ -94,7 +79,7 @@ cc_library(
File `//frobber/BUILD`:

```python
# This is the package group declaration to which rule
# This is the package group declaration to which target
# //frobber/bin:thingy refers.
#
# Our friends are packages //frobber, //fribber and any
Expand All @@ -108,20 +93,20 @@ package_group(
)
```

## Visibility of a file
## Visibility of a file target

By default, files are visible only from the same package. To make a file
By default, file targets are visible only from the same package. To make a file
accessible from another package, use
[`exports_files`](be/functions.html#exports_files).

If the call to `exports_files` rule does specify the visibility attribute, that
specification applies. Otherwise, the file is public (the `default_visibility`
If the call to `exports_files` specifies the visibility attribute, that
visibility applies. Otherwise, the file is public (the `default_visibility`
is ignored).

When possible, prefer exposing a library or another type of rule instead of a
source file. For example, declare a `java_library` instead of exporting a
`.java` file. It's good form for a target to only directly include sources in
its own package.
`.java` file. It's good form for a rule target to only directly include sources
in its own package.

### Example

Expand All @@ -145,8 +130,8 @@ cc_binary(
If the flag [`--incompatible_no_implicit_file_export`](https://github.com/bazelbuild/bazel/issues/10225)
is not set, a legacy behavior applies instead.

With the legacy behavior, files used by at least one rule in the file are
implicitly exported using the `default_visibility` specification. See the
With the legacy behavior, files used by at least one rule target in the package
are implicitly exported using the `default_visibility` specification. See the
[design proposal](https://github.com/bazelbuild/proposals/blob/master/designs/2019-10-24-file-visibility.md#example-and-description-of-the-problem)
for more details.

Expand Down

0 comments on commit 3faaf03

Please sign in to comment.