aboutsummaryrefslogtreecommitdiffhomepage
path: root/site
diff options
context:
space:
mode:
authorGravatar brandjon <brandjon@google.com>2018-07-03 10:51:35 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-03 10:53:13 -0700
commitbbc8ed16aee07c3ba9321d58aa4c0ffc55fa2ba9 (patch)
treedc1689d1b783b628525920010d8b2333f844b316 /site
parentffc192f0bfb240711ceab874258810f6d3671a23 (diff)
Clarify attr documentation
Fixes #5335 RELNOTES: None PiperOrigin-RevId: 203148338
Diffstat (limited to 'site')
-rw-r--r--site/docs/skylark/rules.md126
1 files changed, 74 insertions, 52 deletions
diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md
index 8715a68574..4327199404 100644
--- a/site/docs/skylark/rules.md
+++ b/site/docs/skylark/rules.md
@@ -16,11 +16,30 @@ executable file (the output).
Note that, from Bazel's perspective, `g++` and the standard C++ libraries are
also inputs to this rule. As a rule writer, you must consider not only the
user-provided inputs to a rule, but also all of the tools and libraries required
-to execute the actions (called _implicit inputs_).
+to execute the actions (called _implicit dependencies_).
Before creating or modifying any rule, make sure you are familiar with the
-[evaluation model](concepts.md) (understand the three phases of execution and the
-differences between macros and rules).
+[evaluation model](concepts.md). You must understand the three phases of
+execution and the differences between macros and rules.
+
+A few rules are built into Bazel itself. These *native rules*, such as
+`cc_library` and `java_binary`, provide some core support for certain languages.
+By defining your own rules, you can add similar support for languages and tools
+that Bazel does not support natively.
+
+Rules defined in .bzl files work just like native rules. For example, their
+targets have labels, can appear in `bazel query`, and get built whenever they
+are needed for a `bazel build` command or similar. When defining your own rule,
+you get to decide what attributes it supports and how it generates its outputs.
+
+The exact behavior of a rule during the
+[analysis phase](concepts.md#evaluation-model) is governed by its
+`implementation` function. This function does not run any external commands.
+Rather, it registers [actions](#actions) that will be used later during the
+execution phase to build the rule's outputs, if they are needed. Rules also
+produce and pass along information that may be useful to other rules, in the
+form of [providers](#providers).
+
<!-- [TOC] -->
@@ -39,24 +58,13 @@ The rule can then be loaded in `BUILD` files:
load('//some/pkg:whatever.bzl', 'my_rule')
```
-A custom rule can be used just like a native rule. It has a mandatory `name`
-attribute, you can refer to it with a label, and you can see it in
-`bazel query`.
-
-The rule is analyzed when you explicitly build it, or if it is a dependency of
-the build. In this case, Bazel will execute its `implementation` function. This
-function decides what the outputs of the rule are and how to build them (using
-[actions](#actions)). During the [analysis phase](concepts.md#evaluation-model),
-no external command can be executed. Instead, actions are registered and
-will be run in the execution phase, if their output is needed for the build.
-
[See example](https://github.com/bazelbuild/examples/tree/master/rules/empty).
## Attributes
-An attribute is a rule argument, such as `srcs` or `deps`. You must list
-the attributes and their types when you define a rule. Create attributes using
-the [attr](lib/attr.html) module.
+An attribute is a rule argument, such as `srcs` or `deps`. You must list the
+names and schemas of all attributes when you define a rule. Attribute schemas
+are created using the [attr](lib/attr.html) module.
```python
sum = rule(
@@ -68,11 +76,6 @@ sum = rule(
)
```
-The following attributes are implicitly added to every rule: `deprecation`,
-`features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the
-following attributes: `args`, `flaky`, `local`, `shard_count`, `size`,
-`timeout`.
-
In a `BUILD` file, call the rule to create targets of this type:
```python
@@ -86,10 +89,32 @@ sum(
)
```
-Label attributes like `deps` above are used to declare dependencies. The target
-whose label is mentioned becomes a dependency of the target with the attribute.
-Therefore, `other-target` will be analyzed before `my-target`.
+Here `other-target` is a dependency of `my-target`, and therefore `other-target`
+will be analyzed first.
+
+There are two special kinds of attributes:
+
+* *Dependency attributes*, such as `attr.label` and `attr.label_list`,
+ declare a dependency from the target that owns the attribute to the target
+ whose label appears in the attribute's value. This kind of attribute forms the
+ basis of the target graph.
+
+* *Output attributes*, such as `attr.output` and `attr.output_list`, declare an
+ output file that the target generates. Although they refer to the output file
+ by label, they do not create a dependency relationship between targets. Output
+ attributes are used relatively rarely, in favor of other ways of declaring
+ output files that do not require the user to specify a label.
+
+Both dependency attributes and output attributes take in label values. These may
+be specified as either [`Label`](lib/Label.html) objects or as simple strings.
+If a string is given, it will be converted to a `Label` using the
+[constructor](lib/Label.html#Label). The repository, and possibly the path, will
+be resolved relative to the defined target.
+The following attributes are implicitly added to every rule: `deprecation`,
+`features`, `name`, `tags`, `testonly`, `visibility`. Test rules also have the
+following attributes: `args`, `flaky`, `local`, `shard_count`, `size`,
+`timeout`.
### <a name="private-attributes"></a> Private Attributes
@@ -152,11 +177,11 @@ of declaring and accessing attributes.
## Targets
-Each call to a build rule has the side effect of defining a new target (also
-called instantiating the rule). The dependencies of the new target are any other
-targets whose labels are mentioned in an attribute of type `attr.label` or
-`attr.label_list`. In the following example, the target `//mypkg:y` depends on
-the targets `//mypkg:x` and `//mypkg:z.foo`.
+Each call to a build rule returns no value but has the side effect of defining a
+new target; this is called instantiating the rule. The dependencies of the new
+target are any other targets whose labels are mentioned in its dependency
+attributes. In the following example, the target `//mypkg:y` depends on the
+targets `//mypkg:x` and `//mypkg:z.foo`.
```python
# //mypkg:BUILD
@@ -165,6 +190,8 @@ my_rule(
name = "x",
)
+# Assuming that my_rule has attributes "deps" and "srcs",
+# of type attr.label_list()
my_rule(
name = "y",
deps = [":x"],
@@ -172,16 +199,11 @@ my_rule(
)
```
-Targets are represented at analysis time as [`Target`](lib/Target.html) objects.
-These objects contain the information produced by analyzing a target -- in
-particular, its [providers](#providers).
-
-In a rule's implementation function, the current target's dependencies are
-accessed using `ctx.attr`, just like any other attribute's value. However,
-unlike other types, attributes of type `attr.label` and `attr.label_list` have
-the special behavior that each label value is replaced by its corresponding
-`Target` object. This allows the current target being analyzed to consume the
-providers of its dependencies.
+Dependencies are represented at analysis time as [`Target`](lib/Target.html)
+objects. These objects contain the information produced by analyzing a target --
+in particular, its [providers](#providers). The current target can access its
+dependencies' `Target` objects within its rule implementation function by using
+`ctx.attr`.
## Files
@@ -196,9 +218,9 @@ be an output of exactly one action. Source files cannot be the output of any
action.
Some files, including all source files, are addressable by labels. These files
-have `Target` objects associated with them. If a file's label is used in a
-`attr.label` or `attr.label_list` attribute (for example, in a `srcs`
-attribute), the `ctx.attr.<attr_name>` entry for it will contain the
+have `Target` objects associated with them. If a file's label appears within a
+dependency attribute (for example, in a `srcs` attribute of type
+`attr.label_list`), the `ctx.attr.<attr_name>` entry for it will contain the
corresponding `Target`. The `File` object can be obtained from this `Target`'s
`files` field. This allows the file to be referenced in both the target graph
and the action graph.
@@ -241,12 +263,12 @@ analysis using the [`ctx.actions.declare_file`](lib/actions.html#declare_file)
and [`ctx.actions.declare_directory`](lib/actions.html#declare_directory)
functions. Both kinds of outputs may be passed along in providers.
-Although the input files of a target -- those files passed through attributes of
-`attr.label` and `attr.label_list` type -- can be accessed indirectly via
-`ctx.attr`, it is more convenient to use `ctx.file` and `ctx.files`. For output
-files that are predeclared using attributes of `attr.output` or
-`attr.output_list` type, `ctx.attr` will only return the label, and you must use
-`ctx.outputs` to get the actual `File` object.
+Although the input files of a target -- those files passed through dependency
+attributes -- can be accessed indirectly via `ctx.attr`, it is more convenient
+to use `ctx.file` and `ctx.files`. For output files that are predeclared using
+output attributes (attributes of type `attr.output` or `attr.output_list`),
+`ctx.attr` will only return the label, and you must use `ctx.outputs` to get the
+actual `File` object.
[See example of predeclared outputs](https://github.com/bazelbuild/examples/blob/master/rules/predeclared_outputs/hash.bzl)
@@ -327,9 +349,9 @@ tool, the label attribute will specify a transition to the host configuration.
This causes the tool and all of its dependencies to be built for the host
machine, assuming those dependencies do not themselves have transitions.
-For each [label attribute](lib/attr.html#label), you can decide whether the
-dependency should be built in the same configuration, or transition to the host
-configuration (using `cfg`). If a label attribute has the flag
+For each dependency attribute, you can decide whether the dependency target
+should be built in the same configuration, or transition to the host
+configuration (using `cfg`). If a dependency attribute has the flag
`executable=True`, the configuration must be set explicitly.
[See example](https://github.com/bazelbuild/examples/blob/master/rules/actions_run/execute.bzl)