aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--site/docs/skylark/rules.md98
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java62
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java20
3 files changed, 96 insertions, 84 deletions
diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md
index 797c94ae47..2c7e696e68 100644
--- a/site/docs/skylark/rules.md
+++ b/site/docs/skylark/rules.md
@@ -212,7 +212,7 @@ 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
+A generated file that is addressable by a label 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
@@ -247,37 +247,6 @@ 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
-
-Every rule has a set of default outputs. This is used:
-
-* When the user runs `bazel build` on your target. Bazel will build the default
- outputs of the rule.
-
-* When the target is used as a dependency of another rule. A rule can access
- the default outputs by using [target.files](lib/Target.html#files).
- This is the case, for example, if you use a rule in the `srcs` attribute of a
- `genrule`.
-
-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 predeclared outputs.
-
-```python
-def _impl(ctx):
- # ...
- return DefaultInfo(files=depset([file1, file2]))
-```
-
-This can be useful for exposing files generated with
-[ctx.actions.declare_file](lib/actions.html#declare_file).
-
-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)
-
## Actions
An action describes how to generate a set of outputs from a set of inputs, for
@@ -559,19 +528,44 @@ with an error describing the conflict. To fix, you will need to modify your
any targets using your rule, as well as targets of any kind that depend on those
targets.
-## Output groups
-
-By default Bazel builds a target's
-[default outputs](#default-outputs). However, a rule can also create
- other outputs that are not part of a typical build but might still be useful,
- such as debug information files. The facility for this is _output groups_.
-
-A rule can declare that a certain file belongs to a certain output group by returning
-the [OutputGroupInfo](lib/globals.html#OutputGroupInfo) provider. Fields of
-that provider are output group names:
+## Requesting output files
+
+A single target can have several output files. When a `bazel build` command is
+run, some of the outputs of the targets given to the command are considered to
+be *requested*. Bazel only builds these requested files and the files that they
+directly or indirectly depend on. (In terms of the action graph, Bazel only
+executes the actions that are reachable as transitive dependencies of the
+requested files.)
+
+Every target has a set of *default outputs*, which are the output files that
+normally get requested when that target appears on the command line. For
+example, a target `//pkg:foo` of `java_library` type has in its default outputs
+a file `foo.jar`, which will be built by the command `bazel build //pkg:foo`.
+
+Any predeclared output can be explicitly requested on the command line. This can
+be used to build outputs that are not default outputs, or to build some but not
+all default outputs. For example, `bazel build //pkg:foo_deploy.jar` and
+`bazel build //pkg:foo.jar` will each just build that one file (along with
+its dependencies). See an [example](https://github.com/bazelbuild/examples/blob/master/rules/implicit_output/hash.bzl)
+of a rule with non-default predeclared outputs.
+
+In addition to default outputs, there are *output groups*, which are collections
+of output files that may be requested together. For example, if a target
+`//pkg:mytarget` is of a rule type that has a `debug_files` output group, these
+files can be built by running
+`bazel build //pkg:mytarget --output_groups=debug_files`. See the [command line
+reference](../command-line-reference.html#build) for details on the
+`--output_groups` argument. Since non-predeclared outputs don't have labels,
+they can only be requested by appearing in the default outputs or an output
+group.
+
+You can specify the default outputs and output groups of a rule by returning the
+[`DefaultInfo`](lib/globals.html#DefaultInfo) and
+[`OutputGroupInfo`](lib/globals.html#OutputGroupInfo) providers from its
+implementation function.
```python
-def _impl(ctx):
+def _myrule_impl(ctx):
name = ...
binary = ctx.actions.declare_file(name)
debug_file = ctx.actions.declare_file(name + ".pdb")
@@ -581,14 +575,14 @@ def _impl(ctx):
all_files = depset([binary, debug_file]))]
```
-By default, only the `binary` file will be built.
-The user can specify an [`--output_groups=debug_files`](../command-line-reference.html#build)
-flag on the command line. In that case, only `debug_file` will be built. If the user
-specifies `--output_groups=all_files`, both `binary` and `debug_file` will be build.
+These providers can also be retrieved from dependencies using the usual syntax
+`<target>[DefaultInfo]` and `<target>[OutputGroupInfo]`, where `<target>` is a
+`Target` object.
-> Note: [OutputGroupInfo](skylark/lib/globals.html#OutputGroupInfo) is a regular
-> [provider](#providers), and dependencies of a target can examine it using
-> the `target[OutputGroupInfo]` syntax.
+Note that even if a file is in the default outputs or an output group, you may
+still want to return it in a custom provider in order to make it available in a
+more structured way. For instance, you could pass headers and sources along in
+separate fields of your provider.
## Code coverage instrumentation
@@ -683,7 +677,7 @@ _example_test = rule(
Bazel executes an action only when at least one of its outputs are requested. If
the target is built directly, make sure the output you need is in the [default
-outputs](#default-outputs).
+outputs](#requesting-output-files).
When the target is used as a dependency, check which providers are used and consumed.
@@ -703,7 +697,7 @@ you may need to [specify the runfiles](#runfiles).
### How to choose which files are shown in the output of `bazel build`?
Use the [`DefaultInfo`](lib/globals.html#DefaultInfo) provider to
-[set the default outputs](#default-outputs).
+[set the default outputs](#requesting-output-files).
### How to run a program in the analysis phase?
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index 6f7a1bfd62..5e30bb4abe 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -232,23 +232,33 @@ public class SkylarkRuleClassFunctions {
name = "DefaultInfo",
returnType = Provider.class,
doc =
- "A provider that is provided by every rule, even if it is not returned explicitly. "
- + "A <code>DefaultInfo</code> accepts the following parameters:"
+ "A provider that gives general information about a target's direct and transitive files. "
+ + "Every rule type has this provider, even if it is not returned explicitly by the "
+ + "rule's implementation function."
+ + "<p>The <code>DefaultInfo</code> constructor accepts the following parameters:"
+ "<ul>"
- + "<li><code>executable</code></li>"
- + "<li><code>files</code></li>"
- + "<li><code>runfiles</code></li>"
- + "<li><code>data_runfiles</code></li>"
- + "<li><code>default_runfiles</code></li>"
+ + "<li><code>executable</code>: If this rule is marked "
+ + "<a href='globals.html#rule.executable'><code>executable</code></a> or "
+ + "<a href='globals.html#rule.test'><code>test</code></a>, this is a "
+ + "<a href='File.html'><code>File</code></a> object representing the file that should "
+ + "be executed to run the target. By default it is the predeclared output "
+ + "<code>ctx.outputs.executable</code>."
+ + "<li><code>files</code>: A <a href='depset.html'><code>depset<code></a> of "
+ + "<a href='File.html'><code>File</code></a> objects representing the default outputs "
+ + "to build when this target is specified on the blaze command line. By default it is "
+ + "all predeclared outputs."
+ + "<li><code>runfiles</code>"
+ + "<li><code>data_runfiles</code>"
+ + "<li><code>default_runfiles</code>"
+ "</ul>"
- + "Each instance of the default provider contains the following standard "
- + "fields: "
+ + "Each <code>DefaultInfo</code> instance has the following fields: "
+ "<ul>"
- + "<li><code>files</code></li>"
- + "<li><code>files_to_run</code></li>"
- + "<li><code>data_runfiles</code></li>"
- + "<li><code>default_runfiles</code></li>"
+ + "<li><code>files</code>"
+ + "<li><code>files_to_run</code>"
+ + "<li><code>data_runfiles</code>"
+ + "<li><code>default_runfiles</code>"
+ "</ul>"
+ + "See the <a href='../rules.$DOC_EXT'>rules</a> page for more information."
)
private static final Provider defaultInfo = DefaultInfo.PROVIDER;
@@ -256,12 +266,12 @@ public class SkylarkRuleClassFunctions {
name = "OutputGroupInfo",
returnType = Provider.class,
doc =
- "Provides information about output groups the rule provides.<br>"
+ "A provider that indicates what output groups a rule has.<br>"
+ "Instantiate this provider with <br>"
+ "<pre class=language-python>"
+ "OutputGroupInfo(group1 = &lt;files&gt;, group2 = &lt;files&gt;...)</pre>"
- + "See <a href=\"../rules.$DOC_EXT#output-groups\">Output Groups</a> "
- + "for more information."
+ + "See <a href=\"../rules.$DOC_EXT#requesting-output-files\">Requesting output files"
+ + "</a> for more information."
)
private static final Provider outputGroupInfo = OutputGroupInfo.SKYLARK_CONSTRUCTOR;
@@ -374,10 +384,14 @@ public class SkylarkRuleClassFunctions {
type = Boolean.class,
defaultValue = "False",
doc =
- "Whether this rule is a test rule. "
- + "If True, the rule must end with <code>_test</code> (otherwise it must "
- + "not), and there must be an action that generates "
- + "<code>ctx.outputs.executable</code>."
+ "Whether this rule is a test rule, that is, whether it may be the subject of a "
+ + "<code>blaze test</code> or <code>blaze run</code> command. All test rules are "
+ + "automatically considered <a href='#rule.executable'>executable</a>; it is "
+ + "unnecessary (and discouraged) to explicitly set <code>executable = True</code> "
+ + "for a test rule."
+ + "<p>Test rules must have names ending in the suffix <code>\"_test\"</code>; "
+ + "non-test rules must not use this suffix. (Note that this applies only to the "
+ + "name of the rule, not its targets.)"
),
@Param(
name = "attrs",
@@ -418,9 +432,11 @@ public class SkylarkRuleClassFunctions {
type = Boolean.class,
defaultValue = "False",
doc =
- "whether this rule is marked as executable or not. If True, "
- + "there must be an action that generates "
- + "<code>ctx.outputs.executable</code>."
+ "Whether this rule is considered executable, that is, whether it may be the subject of "
+ + "a <code>blaze run</code> command. Executable rules automatically get a "
+ + "predeclared output that is addressable as <code>ctx.outputs.executable</code>. "
+ + "See the <a href='../rules.$DOC_EXT#output-files'>Rules page</a> for more "
+ + "information."
),
@Param(
name = "output_to_genfiles",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
index ce082a3aea..fe468845c5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
@@ -118,8 +118,8 @@ public final class SkylarkRuleContext implements SkylarkValue {
+ "<code>None</code>. If an optional attribute is not specified in the rule "
+ "then the corresponding struct value is <code>None</code>. If a label type is not "
+ "marked as <code>executable=True</code>, no corresponding struct field is generated. "
- + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/actions_run/execute.bzl\">"
- + "See example of use</a>.";
+ + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/actions_run/"
+ + "execute.bzl\">See example of use</a>.";
public static final String FILES_DOC =
"A <code>struct</code> containing files defined in label or label list "
+ "type attributes. The struct fields correspond to the attribute names. The struct "
@@ -127,7 +127,8 @@ public final class SkylarkRuleContext implements SkylarkValue {
+ "It is a shortcut for:"
+ "<pre class=language-python>[f for t in ctx.attr.&lt;ATTR&gt; for f in t.files]</pre> "
+ "In other words, use <code>files</code> to access the "
- + "<a href=\"../rules.$DOC_EXT#default-outputs\">default output</a> of dependencies. "
+ + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default outputs</a> of a "
+ + "dependency. "
+ "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/depsets/foo.bzl\">"
+ "See example of use</a>.";
public static final String FILE_DOC =
@@ -139,17 +140,18 @@ public final class SkylarkRuleContext implements SkylarkValue {
+ "marked as <code>allow_single_file</code>, no corresponding struct field is generated. "
+ "It is a shortcut for:"
+ "<pre class=language-python>list(ctx.attr.&lt;ATTR&gt;.files)[0]</pre>"
- + "In other words, use <code>file</code> to access the "
- + "<a href=\"../rules.$DOC_EXT#default-outputs\">default output</a> of a dependency. "
- + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/hello.bzl\">"
- + "See example of use</a>.";
+ + "In other words, use <code>file</code> to access the (singular) "
+ + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default output</a> of a "
+ + "dependency. "
+ + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/"
+ + "hello.bzl\">See example of use</a>.";
public static final String ATTR_DOC =
"A struct to access the values of the attributes. The values are provided by "
+ "the user (if not, a default value is used). The attributes of the struct and the "
+ "types of their values correspond to the keys and values of the <code>attrs</code> "
+ "dict provided to the <code>rule</code> function. "
- + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/attributes/printer.bzl\">"
- + "See example of use</a>.";
+ + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/attributes/"
+ + "printer.bzl\">See example of use</a>.";
public static final String SPLIT_ATTR_DOC =
"A struct to access the values of attributes with split configurations. If the attribute is "
+ "a label list, the value of split_attr is a dict of the keys of the split (as strings) "