diff options
author | brandjon <brandjon@google.com> | 2018-02-26 07:20:00 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-26 07:22:00 -0800 |
commit | 4d1425910e757334d5f6c6ed9eb71916dc97fd6e (patch) | |
tree | 3c0b56783cde9c2d34ffb429767ec5a8b24cb531 /site | |
parent | af24688e4e0c8c359a2ec7af3fffaa1c825ef7ed (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.md | 121 |
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) |