diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java b/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java index 6df4ac7b7c66a7..3a75df94bfc999 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/CoreOptions.java @@ -629,13 +629,37 @@ public OutputDirectoryNamingSchemeConverter() { documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS, effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS}, help = - "The given features will be enabled or disabled by default for all packages. " - + "Specifying - will disable the feature globally. " + "The given features will be enabled or disabled by default for targets " + + "built in the target configuration. " + + "Specifying - will disable the feature. " + "Negative features always override positive ones. " - + "This flag is used to enable rolling out default feature changes without a " - + "Bazel release.") + + "See also --host_features") public List defaultFeatures; + @Option( + name = "host_features", + allowMultiple = true, + defaultValue = "null", + documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS, + effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS}, + help = + "The given features will be enabled or disabled by default for targets " + + "built in the exec configuration. " + + "Specifying - will disable the feature. " + + "Negative features always override positive ones.") + public List hostFeatures; + + @Option( + name = "incompatible_use_host_features", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS, + effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS}, + metadataTags = {OptionMetadataTag.INCOMPATIBLE_CHANGE}, + help = + "If true, use --features only for the target configuration and --host_features for the" + + " exec configuration.") + public boolean incompatibleUseHostFeatures; + @Option( name = "target_environment", converter = LabelListConverter.class, @@ -960,7 +984,12 @@ public FragmentOptions getHost() { host.checkLicenses = checkLicenses; // === Pass on C++ compiler features. - host.defaultFeatures = ImmutableList.copyOf(defaultFeatures); + host.incompatibleUseHostFeatures = incompatibleUseHostFeatures; + if (incompatibleUseHostFeatures) { + host.defaultFeatures = ImmutableList.copyOf(hostFeatures); + } else { + host.defaultFeatures = ImmutableList.copyOf(defaultFeatures); + } // Save host options in case of a further exec->host transition. host.hostCpu = hostCpu; diff --git a/src/test/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetTest.java index f379378004effc..cb7c937564555b 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetTest.java @@ -51,6 +51,38 @@ public void testFeatureEnabledOnCommandLine() throws Exception { assertThat(features).doesNotContain("other"); } + @Test + public void testTargetIgnoresHostFeatures() throws Exception { + useConfiguration("--features=feature", "--host_features=host_feature"); + scratch.file("a/BUILD", "cc_library(name = 'a')"); + ImmutableSet features = getRuleContext(configure("//a")).getFeatures(); + assertThat(features).contains("feature"); + assertThat(features).doesNotContain("host_feature"); + } + + @Test + public void testHostFeatures() throws Exception { + useConfiguration( + "--features=feature", + "--host_features=host_feature", + "--incompatible_use_host_features=true"); + scratch.file("a/BUILD", "cc_library(name = 'a')"); + ImmutableSet features = + getRuleContext(getConfiguredTarget("//a", getExecConfiguration())).getFeatures(); + assertThat(features).contains("host_feature"); + assertThat(features).doesNotContain("feature"); + } + + @Test + public void testHostFeaturesIncompatibleDisabled() throws Exception { + useConfiguration("--features=feature", "--host_features=host_feature"); + scratch.file("a/BUILD", "cc_library(name = 'a')"); + ImmutableSet features = + getRuleContext(getConfiguredTarget("//a", getExecConfiguration())).getFeatures(); + assertThat(features).contains("feature"); + assertThat(features).doesNotContain("host_feature"); + } + @Test public void testFeatureDisabledOnCommandLine() throws Exception { useConfiguration("--features=-feature");