Clarify why `cfg` is mandatory for `executable=True` attributes.
I was originally considering removing `cfg = "target"` support in the name of API cleanup, since that's a semantic no-op. But the reasoning is fair for when `cfg` is mandatory (shared in a Google doc by @laurentlb):
> "When an input is executable, we often want to run it on the host. So I suggest that cfg is mandatory when input is executable".
But I don't think we should set `cfg = "target"` casually when it's not helpful - that'll just litter code bases. I tried to address these issues in this PR.
Also note, for posterity, that `cfg = "host"` is due for deprecation: https://github.com/bazelbuild/proposals/blob/master/designs/2019-02-12-execution-transitions.md
Closes #8025.
PiperOrigin-RevId: 245316460
diff --git a/site/docs/skylark/rules.md b/site/docs/skylark/rules.md
index b38d1a3..1676c2a 100644
--- a/site/docs/skylark/rules.md
+++ b/site/docs/skylark/rules.md
@@ -353,11 +353,11 @@
## Configurations
-Imagine that you want to build a C++ binary and target a different architecture.
-The build can be complex and involve multiple steps. Some of the intermediate
-binaries, like the compilers and code generators, have to run on your machine
-(the host); some of the binaries such the final output must be built for the
-target architecture.
+Imagine that you want to build a C++ binary for a different architecture. The
+build can be complex and involve multiple steps. Some of the intermediate
+binaries, like compilers and code generators, have to run on your machine (the
+host). Some binaries like the final output must be built for the target
+architecture.
For this reason, Bazel has a concept of "configurations" and transitions. The
topmost targets (the ones requested on the command line) are built in the
@@ -368,17 +368,17 @@
configurations. If this happens, it will be analyzed and potentially built
multiple times.
-By default, Bazel builds the dependencies of a target in the same configuration
-as the target itself, i.e. without transitioning. When a target depends on a
-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.
+By default, Bazel builds a target's dependencies in the same configuration as
+the target itself, in other words without transitions. When a dependency is a tool
+that's needed to help build the target, the corresponding attribute should
+specify a transition to the host configuration. This causes the tool and all its
+dependencies to build for the host machine.
-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)
+For each dependency attribute, you can use `cfg` to decide if dependencies
+should build in the same configuration or transition to the host configuration.
+If a dependency attribute has the flag `executable=True`, `cfg` must be set
+explicitly. This is to guard against accidentally building a host tool for the
+wrong configuration. [See example](https://github.com/bazelbuild/examples/blob/master/rules/actions_run/execute.bzl)
In general, sources, dependent libraries, and executables that will be needed at
runtime can use the same configuration.
@@ -391,6 +391,10 @@
be built for the target configuration. In this case, specify `cfg="target"` in
the attribute.
+`cfg="target"` doesn't actually do anything: it's purely a convenience value to
+help rule designers be explicit about their intentions. When `executable=False`,
+which means `cfg` is optional, only set this when it truly helps readability.
+
<a name="fragments"></a>
## Configuration Fragments
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
index d4b0974..5c7b8d1 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
@@ -350,7 +350,11 @@
positional = false,
doc =
CONFIGURATION_DOC
- + " This parameter is required if <code>executable</code> is True."),
+ + " This parameter is required if <code>executable</code> is True "
+ + "to guard against accidentally building host tools in the "
+ + "target configuration. <code>\"target\"</code> has no semantic "
+ + "effect, so don't set it when <code>executable</code> is False "
+ + "unless it really helps clarify your intentions."),
@Param(
name = ASPECTS_ARG,
type = SkylarkList.class,