diff --git a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm
index 24d31883910a2f..a8c6d3fc54c705 100644
--- a/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm
+++ b/src/main/java/com/google/devtools/build/docgen/templates/be/functions.vm
@@ -616,10 +616,8 @@ sh_binary(
If multiple conditions match and one is a specialization of the others,
the specialization takes precedence. Condition B is considered a
- specialization of condition A if B has all the same flags as A plus some
- additional flags. However, the number of constraint values that A and B have
- are not considered in this comparison -- one condition cannot match a
- platform more than another condition does.
+ specialization of condition A if B has all the same flags and constraint
+ values as A plus some additional flags and constraint values.
If multiple conditions match and one is not a specialization of all the
others, Bazel fails with an error.
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigMatchingProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigMatchingProvider.java
index a70351e5414508..2784da50265026 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigMatchingProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigMatchingProvider.java
@@ -50,9 +50,15 @@ public static ConfigMatchingProvider create(
ImmutableMultimap settingsMap,
ImmutableMap flagSettingsMap,
RequiredConfigFragmentsProvider requiredFragmentOptions,
+ ImmutableSet constraintValueSettings,
boolean matches) {
return new AutoValue_ConfigMatchingProvider(
- label, settingsMap, flagSettingsMap, requiredFragmentOptions, matches);
+ label,
+ settingsMap,
+ flagSettingsMap,
+ requiredFragmentOptions,
+ constraintValueSettings,
+ matches);
}
/** The target's label. */
@@ -64,6 +70,8 @@ public static ConfigMatchingProvider create(
public abstract RequiredConfigFragmentsProvider requiredFragmentOptions();
+ abstract ImmutableSet constraintValuesSetting();
+
/**
* Whether or not the configuration criteria defined by this target match its actual
* configuration.
@@ -81,11 +89,18 @@ public boolean refines(ConfigMatchingProvider other) {
ImmutableSet> flagSettings = flagSettingsMap().entrySet();
ImmutableSet> otherFlagSettings = other.flagSettingsMap().entrySet();
- if (!settings.containsAll(otherSettings) || !flagSettings.containsAll(otherFlagSettings)) {
+ ImmutableSet constraintValueSettings = constraintValuesSetting();
+ ImmutableSet otherConstraintValueSettings = other.constraintValuesSetting();
+
+ if (!settings.containsAll(otherSettings)
+ || !flagSettings.containsAll(otherFlagSettings)
+ || !constraintValueSettings.containsAll(otherConstraintValueSettings)) {
return false; // Not a superset.
}
- return settings.size() > otherSettings.size() || flagSettings.size() > otherFlagSettings.size();
+ return settings.size() > otherSettings.size()
+ || flagSettings.size() > otherFlagSettings.size()
+ || constraintValueSettings.size() > otherConstraintValueSettings.size();
}
/** Format this provider as its label. */
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
index f36231b84b144c..f7bb04f3225ea6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
@@ -16,6 +16,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.cmdline.Label;
@@ -82,6 +83,7 @@ public ConfigMatchingProvider configMatchingProvider(PlatformInfo platformInfo)
// the owning target already depends on PlatformConfiguration. And we can't reference
// PlatformConfiguration.class here without a build dependency cycle.
RequiredConfigFragmentsProvider.EMPTY,
+ ImmutableSet.of(),
platformInfo.constraints().hasConstraintValue(this));
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
index 361bd2766a10ce..301429a883cd1a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/config/ConfigSetting.java
@@ -23,6 +23,7 @@
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
@@ -130,6 +131,7 @@ public ConfiguredTarget create(RuleContext ruleContext)
ruleContext.shouldIncludeRequiredConfigFragmentsProvider()
? ruleContext.getRequiredConfigFragments()
: RequiredConfigFragmentsProvider.EMPTY,
+ ImmutableSet.copyOf(constraintValueSettings),
nativeFlagsMatch && userDefinedFlags.matches() && constraintValuesMatch);
return new RuleConfiguredTargetBuilder(ruleContext)
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
index 19315ffd9dae72..d01358d47a92cd 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/ConfigSettingTest.java
@@ -841,13 +841,16 @@ public void doesNotMatchIfDefaultIsSpecifiedAndFlagValueIsNotDefault() throws Ex
}
@Test
- public void doesNotRefineSettingWithSameValuesAndSameFlagValues() throws Exception {
+ public void doesNotRefineSettingWithSameValuesAndSameFlagValuesAndSameConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -858,6 +861,9 @@ public void doesNotRefineSettingWithSameValuesAndSameFlagValues() throws Excepti
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -870,6 +876,9 @@ public void doesNotRefineSettingWithSameValuesAndSameFlagValues() throws Excepti
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_feature_flag(",
@@ -889,13 +898,16 @@ public void doesNotRefineSettingWithSameValuesAndSameFlagValues() throws Excepti
}
@Test
- public void doesNotRefineSettingWithDifferentValuesAndSameFlagValues() throws Exception {
+ public void doesNotRefineSettingWithDifferentValuesAndSameFlagValuesAndSameConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -905,6 +917,9 @@ public void doesNotRefineSettingWithDifferentValuesAndSameFlagValues() throws Ex
" values = {",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -916,6 +931,9 @@ public void doesNotRefineSettingWithDifferentValuesAndSameFlagValues() throws Ex
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_feature_flag(",
@@ -935,13 +953,16 @@ public void doesNotRefineSettingWithDifferentValuesAndSameFlagValues() throws Ex
}
@Test
- public void doesNotRefineSettingWithSameValuesAndDifferentFlagValues() throws Exception {
+ public void doesNotRefineSettingWithSameValuesAndSameConstraintValuesAndDifferentFlagValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -951,6 +972,9 @@ public void doesNotRefineSettingWithSameValuesAndDifferentFlagValues() throws Ex
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_setting(",
@@ -962,6 +986,9 @@ public void doesNotRefineSettingWithSameValuesAndDifferentFlagValues() throws Ex
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag2'],",
")",
"config_feature_flag(",
@@ -981,13 +1008,19 @@ public void doesNotRefineSettingWithSameValuesAndDifferentFlagValues() throws Ex
}
@Test
- public void doesNotRefineSettingWithDifferentValuesAndDifferentFlagValues() throws Exception {
+ public void
+ doesNotRefineSettingWithDifferentValuesAndDifferentFlagValuesAndDifferentConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -996,6 +1029,9 @@ public void doesNotRefineSettingWithDifferentValuesAndDifferentFlagValues() thro
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_setting(",
@@ -1006,6 +1042,9 @@ public void doesNotRefineSettingWithDifferentValuesAndDifferentFlagValues() thro
" values = {",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag2'],",
")",
"config_feature_flag(",
@@ -1025,13 +1064,18 @@ public void doesNotRefineSettingWithDifferentValuesAndDifferentFlagValues() thro
}
@Test
- public void doesNotRefineSettingWithDifferentValuesAndSubsetFlagValues() throws Exception {
+ public void doesNotRefineSettingWithDifferentValuesAndSubsetFlagValuesAndSubsetConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -1041,6 +1085,10 @@ public void doesNotRefineSettingWithDifferentValuesAndSubsetFlagValues() throws
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -1051,6 +1099,9 @@ public void doesNotRefineSettingWithDifferentValuesAndSubsetFlagValues() throws
" values = {",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_feature_flag(",
@@ -1070,22 +1121,89 @@ public void doesNotRefineSettingWithDifferentValuesAndSubsetFlagValues() throws
}
@Test
- public void doesNotRefineSettingWithSubsetValuesAndDifferentFlagValues() throws Exception {
+ public void doesNotRefineSettingWithSubsetValuesAndSubsetFlagValuesAndDifferentConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
" ':flag': 'right',",
+ " ':flag2': 'good',",
" },",
" values = {",
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
+ " transitive_configs = [':flag', ':flag2'],",
+ ")",
+ "config_setting(",
+ " name = 'other',",
+ " flag_values = {",
+ " ':flag': 'right',",
+ " ':flag2': 'good',",
+ " },",
+ " values = {",
+ " 'copt': '-Dright',",
+ " },",
+ " constraint_values = [",
+ " ':value_b',",
+ " ],",
+ " transitive_configs = [':flag', ':flag2'],",
+ ")",
+ "config_feature_flag(",
+ " name = 'flag',",
+ " allowed_values = ['right', 'wrong'],",
+ " default_value = 'right',",
+ ")",
+ "config_feature_flag(",
+ " name = 'flag2',",
+ " allowed_values = ['good', 'bad'],",
+ " default_value = 'good',",
+ ")");
+ assertThat(
+ getConfigMatchingProvider("//test:refined")
+ .refines(getConfigMatchingProvider("//test:other")))
+ .isFalse();
+ }
+
+ @Test
+ public void doesNotRefineSettingWithSubsetValuesAndSubsetConstraintValuesAndDifferentFlagValues()
+ throws Exception {
+ useConfiguration(
+ "--copt=-Dright",
+ "--javacopt=-Dgood",
+ "--enforce_transitive_configs_for_config_feature_flag");
+ scratch.file(
+ "test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
+ "config_setting(",
+ " name = 'refined',",
+ " flag_values = {",
+ " ':flag': 'right',",
+ " },",
+ " values = {",
+ " 'copt': '-Dright',",
+ " 'javacopt': '-Dgood',",
+ " },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_setting(",
@@ -1096,6 +1214,9 @@ public void doesNotRefineSettingWithSubsetValuesAndDifferentFlagValues() throws
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag2'],",
")",
"config_feature_flag(",
@@ -1115,13 +1236,18 @@ public void doesNotRefineSettingWithSubsetValuesAndDifferentFlagValues() throws
}
@Test
- public void refinesSettingWithSubsetValuesAndSameFlagValues() throws Exception {
+ public void refinesSettingWithSubsetValuesAndSubsetConstraintValuesAndSameFlagValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -1132,6 +1258,10 @@ public void refinesSettingWithSubsetValuesAndSameFlagValues() throws Exception {
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -1143,6 +1273,9 @@ public void refinesSettingWithSubsetValuesAndSameFlagValues() throws Exception {
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_feature_flag(",
@@ -1162,13 +1295,18 @@ public void refinesSettingWithSubsetValuesAndSameFlagValues() throws Exception {
}
@Test
- public void refinesSettingWithSameValuesAndSubsetFlagValues() throws Exception {
+ public void refinesSettingWithSameValuesAndSubsetFlagValuesAndSubsetConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -1179,6 +1317,10 @@ public void refinesSettingWithSameValuesAndSubsetFlagValues() throws Exception {
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -1190,6 +1332,9 @@ public void refinesSettingWithSameValuesAndSubsetFlagValues() throws Exception {
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_feature_flag(",
@@ -1209,13 +1354,18 @@ public void refinesSettingWithSameValuesAndSubsetFlagValues() throws Exception {
}
@Test
- public void refinesSettingWithSubsetValuesAndSubsetFlagValues() throws Exception {
+ public void refinesSettingWithSubsetValuesAndSubsetFlagValuesAndConstraintValues()
+ throws Exception {
useConfiguration(
"--copt=-Dright",
"--javacopt=-Dgood",
"--enforce_transitive_configs_for_config_feature_flag");
scratch.file(
"test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
"config_setting(",
" name = 'refined',",
" flag_values = {",
@@ -1226,6 +1376,10 @@ public void refinesSettingWithSubsetValuesAndSubsetFlagValues() throws Exception
" 'copt': '-Dright',",
" 'javacopt': '-Dgood',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
" transitive_configs = [':flag', ':flag2'],",
")",
"config_setting(",
@@ -1236,6 +1390,9 @@ public void refinesSettingWithSubsetValuesAndSubsetFlagValues() throws Exception
" values = {",
" 'copt': '-Dright',",
" },",
+ " constraint_values = [",
+ " ':value_a',",
+ " ],",
" transitive_configs = [':flag'],",
")",
"config_feature_flag(",
@@ -1254,6 +1411,53 @@ public void refinesSettingWithSubsetValuesAndSubsetFlagValues() throws Exception
.isTrue();
}
+ @Test
+ public void refinesSettingWithSubsetConstraintValues() throws Exception {
+ scratch.file(
+ "test/BUILD",
+ "constraint_setting(name = 'setting_a')",
+ "constraint_value(name = 'value_a', constraint_setting = 'setting_a')",
+ "constraint_setting(name = 'setting_b')",
+ "constraint_value(name = 'value_b', constraint_setting = 'setting_b')",
+ "constraint_setting(name = 'setting_c')",
+ "constraint_value(name = 'value_c', constraint_setting = 'setting_c')",
+ "platform(",
+ " name = 'refined_platform',",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ':value_c',",
+ " ],",
+ ")",
+ "platform(",
+ " name = 'other_platform',",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
+ ")",
+ "config_setting(",
+ " name = 'refined',",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ':value_c',",
+ " ],",
+ ")",
+ "config_setting(",
+ " name = 'other',",
+ " constraint_values = [",
+ " ':value_a',",
+ " ':value_b',",
+ " ],",
+ ");");
+ useConfiguration("--platforms=//test:refined_platform");
+ assertThat(
+ getConfigMatchingProvider("//test:refined")
+ .refines(getConfigMatchingProvider("//test:other")))
+ .isTrue();
+ }
+
@Test
public void matchesAliasedFlagsInFlagValues() throws Exception {
useConfiguration("--enforce_transitive_configs_for_config_feature_flag");