diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java index 83bc9ce5bf0d85..c10dfa2669d9e0 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java @@ -41,6 +41,7 @@ import com.google.devtools.build.lib.packages.Type; import com.google.devtools.build.lib.packages.Type.ConversionException; import com.google.devtools.build.lib.packages.Type.LabelClass; +import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; import com.google.devtools.build.lib.starlarkbuildapi.NativeComputedDefaultApi; import com.google.devtools.build.lib.starlarkbuildapi.StarlarkAttrModuleApi; import com.google.devtools.build.lib.util.FileType; @@ -229,6 +230,15 @@ && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) { } // TODO(b/203203933): Officially deprecate HOST transition and remove this. if (trans.equals("host")) { + boolean disableStarlarkHostTransitions = + thread + .getSemantics() + .getBool(BuildLanguageOptions.INCOMPATIBLE_DISABLE_STARLARK_HOST_TRANSITIONS); + if (disableStarlarkHostTransitions) { + throw new EvalException( + "'cfg = \"host\"' is deprecated and should no longer be used. Please use " + + "'cfg = \"exec\"' instead."); + } builder.cfg(ExecutionTransitionFactory.create()); } else if (trans.equals("exec")) { builder.cfg(ExecutionTransitionFactory.create()); @@ -255,8 +265,8 @@ && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) { // android_split_transition because users of those transitions should already know about // them. throw Starlark.errorf( - "cfg must be either 'host', 'target', 'exec' or a starlark defined transition defined" - + " by the exec() or transition() functions."); + "cfg must be either 'target', 'exec' or a starlark defined transition defined by the " + + "exec() or transition() functions."); } } diff --git a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java index 9fe676d398aef6..5636dca8870513 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java +++ b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java @@ -532,6 +532,17 @@ public final class BuildLanguageOptions extends OptionsBase { + " providers of the aspect.") public boolean incompatibleTopLevelAspectsRequireProviders; + @Option( + name = "incompatible_disable_starlark_host_transitions", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS, + metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE}, + effectTags = {OptionEffectTag.LOADING_AND_ANALYSIS}, + help = + "If set to true, rule attributes cannot set 'cfg = \"host\"'. Rules should set " + + "'cfg = \"exec\"' instead.") + public boolean incompatibleDisableStarlarkHostTransitions; + /** * An interner to reduce the number of StarlarkSemantics instances. A single Blaze instance should * never accumulate a large number of these and being able to shortcut on object identity makes a @@ -599,6 +610,9 @@ public StarlarkSemantics toStarlarkSemantics() { .setBool( INCOMPATIBLE_TOP_LEVEL_ASPECTS_REQUIRE_PROVIDERS, incompatibleTopLevelAspectsRequireProviders) + .setBool( + INCOMPATIBLE_DISABLE_STARLARK_HOST_TRANSITIONS, + incompatibleDisableStarlarkHostTransitions) .build(); return INTERNER.intern(semantics); } @@ -666,6 +680,8 @@ public StarlarkSemantics toStarlarkSemantics() { "-incompatible_visibility_private_attributes_at_definition"; public static final String INCOMPATIBLE_TOP_LEVEL_ASPECTS_REQUIRE_PROVIDERS = "-incompatible_top_level_aspects_require_providers"; + public static final String INCOMPATIBLE_DISABLE_STARLARK_HOST_TRANSITIONS = + "-incompatible_disable_starlark_host_transitions"; // non-booleans public static final StarlarkSemantics.Key EXPERIMENTAL_BUILTINS_BZL_PATH = diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/StarlarkAttrModuleApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/StarlarkAttrModuleApi.java index c2603408be9fad..8e6bb52f4cf0c0 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/StarlarkAttrModuleApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/StarlarkAttrModuleApi.java @@ -92,8 +92,13 @@ public interface StarlarkAttrModuleApi extends StarlarkValue { // TODO(b/151742236): Update when new Starlark-based configuration framework is implemented. String CONFIGURATION_DOC = "" - + "Configuration of the attribute. It can be either \"host\", " - + "\"exec\", or \"target\"."; + + "Configuration of the attribute. It can be either \"exec\", which " + + "indicates that the dependency is built for the execution platform, or " + + "\"target\", which indicates that the dependency is build for the " + + "target platform. A typical example of the difference is when building " + + "mobile apps, where the target platform is Android or " + + "iOS while the execution platform is Linux, " + + "macOS, or Windows."; String DEFAULT_ARG = "default"; // A trailing space is required because it's often prepended to other sentences diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java index 88d06f3171bd04..da9c01c90eecb6 100644 --- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleClassFunctionsTest.java @@ -781,6 +781,14 @@ public void testAttrCfgNoMoreHost() throws Exception { assertThat(attr.getTransitionFactory().isTool()).isTrue(); } + @Test + public void testAttrCfgHostDisabled() throws Exception { + setBuildLanguageOptions("--incompatible_disable_starlark_host_transitions"); + + EvalException ex = assertThrows(EvalException.class, () -> ev.eval("attr.label(cfg = 'host')")); + assertThat(ex).hasMessageThat().contains("Please use 'cfg = \"exec\"' instead"); + } + @Test public void testAttrCfgTarget() throws Exception { Attribute attr = buildAttribute("a1", "attr.label(cfg = 'target', allow_files = True)"); @@ -791,7 +799,7 @@ public void testAttrCfgTarget() throws Exception { public void incompatibleDataTransition() throws Exception { EvalException expected = assertThrows(EvalException.class, () -> ev.eval("attr.label(cfg = 'data')")); - assertThat(expected).hasMessageThat().contains("cfg must be either 'host', 'target'"); + assertThat(expected).hasMessageThat().contains("cfg must be either 'target', 'exec'"); } @Test