aboutsummaryrefslogtreecommitdiffhomepage
path: root/site
diff options
context:
space:
mode:
authorGravatar brandjon <brandjon@google.com>2018-02-26 07:20:00 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-26 07:22:00 -0800
commit4d1425910e757334d5f6c6ed9eb71916dc97fd6e (patch)
tree3c0b56783cde9c2d34ffb429767ec5a8b24cb531 /site
parentaf24688e4e0c8c359a2ec7af3fffaa1c825ef7ed (diff)
Revamp rules.md documentation for files
Unified "Files" and "Output files" sections. Renamed "declared files" to "predeclared files" to avoid confusion with "declare_file()"/"declare_directory()". RELNOTES: None PiperOrigin-RevId: 187017607
Diffstat (limited to 'site')
-rw-r--r--site/docs/skylark/rules.md121
1 files changed, 79 insertions, 42 deletions
diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md
index ab38202feb..797c94ae47 100644
--- a/site/docs/skylark/rules.md
+++ b/site/docs/skylark/rules.md
@@ -150,22 +150,17 @@ the same as their rule, but suffixed with `_impl`.
See [an example](https://github.com/bazelbuild/examples/blob/master/rules/attributes/printer.bzl)
of declaring and accessing attributes.
-## Files
-
-There are two kinds of files: files stored in the file system and generated
-files. For each generated file, there must be one and only one generating
-action, and each action must generate one or more output files. Bazel will throw
-an error otherwise.
-
-A file is represented with the [File](lib/File.html) object.
-
## Targets
-Every call to a build rule corresponds to exactly one target. A target `y`
-depends on target `x` if `y` has a label- or label-list-type attribute
-that contains `x`'s label:
+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`.
```python
+# //mypkg:BUILD
+
my_rule(
name = "x",
)
@@ -173,42 +168,84 @@ my_rule(
my_rule(
name = "y",
deps = [":x"],
+ srcs = [":z.foo"],
)
```
-In a rule's implementation function, the current target's dependencies can be
-accessed like any other attribute value by using `ctx.attr`. However, each label
-is replaced by a resolved [Target](lib/Target.html) object, which contains the
-additional information obtained during that dependency's analysis step. In
-particular, it contains the [providers](#providers) returned by that dependency.
-
-## <a name="output-files"></a> Output files
+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).
-A target can declare output files, which must be generated by the target's
-actions. Each output file must have exactly one generating action.
+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.
-There are multiple ways to have declared outputs:
-
-* If the rule is marked `executable`, it creates an output file of the same name
- as the rule's. [See example](https://github.com/bazelbuild/examples/blob/master/rules/executable/executable.bzl)
-
-* The rule can declare outputs using the `outputs` argument of the
- [rule](lib/globals.html#rule) function.
- [See example](https://github.com/bazelbuild/examples/blob/master/rules/default_outputs/extension.bzl)
+## Files
-* The rule can have [output](lib/attr.html#output) or [output_list](lib/attr.html#output_list)
- attributes. In that case the output files come from the actual attribute values.
+Files are represented by the [`File`](lib/File.html) type. Since Bazel does not
+perform file I/O during the analysis phase, these objects cannot be used to
+directly read or write file content. Rather, they are passed to action-emitting
+functions to construct pieces of the action graph. See
+[`ctx.actions`](lib/actions.html) for the available kinds of actions.
+
+A file can either be a source file or a generated file. Each generated file must
+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
+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.
+
+During the analysis phase, a rule's implementation function can create
+additional output files. Since all labels have to be known during the loading
+phase, these additional output files are not associated with labels or
+`Target`s. Generally these are intermediate files needed for a later compilation
+step, or auxiliary outputs that don't need to be referenced in the target graph.
+Even though these files don't have a label, they can still be passed along in a
+[`provider`](#providers) to make them available to other depending targets at
+analysis time.
+
+A file that is both a target and a generated file is called a *predeclared
+output*. There are multiple ways for a rule to introduce a predeclared output:
+
+* The rule can have an attribute of type [`output`](lib/attr.html#output) or
+ [`output_list`](lib/attr.html#output_list). In this case the user explicitly
+ chooses the label for the output when they instantiate the rule.
[See example](https://github.com/bazelbuild/examples/blob/master/rules/custom_outputs/extension.bzl)
-We call them "declared outputs" because they are associated with a label. You
-can refer to declared outputs using a label on the command-line or in a `BUILD`
-file. In the implementation function, use [ctx.outputs](lib/ctx.html#outputs)
-for accessing declared outputs.
+* The rule can predeclare outputs using the [`outputs`](lib/globals.html#rule.outputs)
+ argument of the `rule()` function. The label for the output is chosen
+ automatically, usually by substituting into a template.
+ [See example](https://github.com/bazelbuild/examples/blob/master/rules/default_outputs/extension.bzl)
-The rule can also create extra output files during the analysis phase using the
-[ctx.actions.declare_file](lib/actions.html#declare_file) function. This is
-more flexible, but those files are not declared outputs: they don't have any
-associated labels.
+* If the rule is marked [`executable`](lib/globals.html#rule.executable), an
+ output is created with the same name as the rule instance itself.
+ (Technically, the file has no label since it would clash with the rule
+ instance's own label, but it is still considered a predeclared output.) By
+ default, this file serves as the binary to run if the target appears on the
+ command line of a `bazel run` or `bazel test` command. Use the `executable`
+ argument of `DefaultInfo` to override this behavior.
+ [See example](https://github.com/bazelbuild/examples/blob/master/rules/executable/executable.bzl)
+
+All predeclared outputs can be accessed within the rule's implementation
+function under the [`ctx.outputs`](lib/ctx.html#output) struct. Non-predeclared
+outputs are created during 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.
## Default outputs
@@ -224,7 +261,7 @@ Every rule has a set of default outputs. This is used:
In the [`DefaultInfo`](lib/globals.html#DefaultInfo) provider, the `files` field
specifies the default outputs of a rule. If left unspecified, it will contain
-all the declared outputs.
+all the predeclared outputs.
```python
def _impl(ctx):
@@ -235,8 +272,8 @@ def _impl(ctx):
This can be useful for exposing files generated with
[ctx.actions.declare_file](lib/actions.html#declare_file).
-An "implicit output" is a declared output that is not in the default outputs. In
-other words, it is not generated by default. Users can refer to its label to
+An "implicit output" is a predeclared output that is not in the default outputs.
+In other words, it is not generated by default. Users can refer to its label to
build the file explicitly. Use the `files` mentioned above if you need implicit
outputs (like `_deploy.jar` files generated by `java_binary`).
[See example](https://github.com/bazelbuild/examples/blob/master/rules/implicit_output/hash.bzl)