Enable rules to inherit the ExecutionPlatformConstraintsAllowed value. PiperOrigin-RevId: 200247872
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index 330278f..78abb6f 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -209,13 +209,34 @@ * Allows additional execution platform constraints to be added in the rule definition, which * apply to all targets of that rule. */ - PER_RULE, + PER_RULE(1), /** * Users are allowed to specify additional execution platform constraints for each target, using * the 'exec_compatible_with' attribute. This also allows setting constraints in the rule * definition, like PER_RULE. */ - PER_TARGET; + PER_TARGET(2); + + private final int priority; + + ExecutionPlatformConstraintsAllowed(int priority) { + this.priority = priority; + } + + public int priority() { + return priority; + } + + public static ExecutionPlatformConstraintsAllowed highestPriority( + ExecutionPlatformConstraintsAllowed first, ExecutionPlatformConstraintsAllowed... rest) { + ExecutionPlatformConstraintsAllowed result = first; + for (ExecutionPlatformConstraintsAllowed value : rest) { + if (result == null || result.priority() < value.priority()) { + result = value; + } + } + return result; + } } /** @@ -668,7 +689,11 @@ addRequiredToolchains(parent.getRequiredToolchains()); supportsPlatforms = parent.supportsPlatforms; - // executionPlatformConstraintsAllowed is not inherited and takes the default. + + // Make sure we use the highest priority value from all parents. + executionPlatformConstraintsAllowed( + ExecutionPlatformConstraintsAllowed.highestPriority( + executionPlatformConstraintsAllowed, parent.executionPlatformConstraintsAllowed())); addExecutionPlatformConstraints(parent.getExecutionPlatformConstraints()); for (Attribute attribute : parent.getAttributes()) {
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java index 088e7db..bc9d068 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -1139,11 +1139,58 @@ RuleClass.Builder childRuleClassBuilder = new RuleClass.Builder("childRuleClass", RuleClassType.NORMAL, false, parentRuleClass) + .factory(DUMMY_CONFIGURED_TARGET_FACTORY); + + RuleClass childRuleClass = childRuleClassBuilder.build(); + + assertThat(childRuleClass.executionPlatformConstraintsAllowed()) + .isEqualTo(ExecutionPlatformConstraintsAllowed.PER_TARGET); + assertThat(childRuleClass.hasAttr("exec_compatible_with", LABEL_LIST)).isTrue(); + } + + @Test + public void testExecutionPlatformConstraints_inherit_multipleParents() { + RuleClass parentRuleClass1 = + new RuleClass.Builder("parentRuleClass1", RuleClassType.NORMAL, false) + .factory(DUMMY_CONFIGURED_TARGET_FACTORY) + .add(attr("tags", STRING_LIST)) + .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_TARGET) + .build(); + RuleClass parentRuleClass2 = + new RuleClass.Builder("$parentRuleClass2", RuleClassType.ABSTRACT, false) + .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_RULE) + .build(); + + RuleClass.Builder childRuleClassBuilder = + new RuleClass.Builder( + "childRuleClass", RuleClassType.NORMAL, false, parentRuleClass1, parentRuleClass2) + .factory(DUMMY_CONFIGURED_TARGET_FACTORY); + + RuleClass childRuleClass = childRuleClassBuilder.build(); + + assertThat(childRuleClass.executionPlatformConstraintsAllowed()) + .isEqualTo(ExecutionPlatformConstraintsAllowed.PER_TARGET); + assertThat(childRuleClass.hasAttr("exec_compatible_with", LABEL_LIST)).isTrue(); + } + + @Test + public void testExecutionPlatformConstraints_inherit_parentAllowsPerTarget_override() { + RuleClass parentRuleClass = + new RuleClass.Builder("parentRuleClass", RuleClassType.NORMAL, false) + .factory(DUMMY_CONFIGURED_TARGET_FACTORY) + .add(attr("tags", STRING_LIST)) + .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_TARGET) + .build(); + + RuleClass.Builder childRuleClassBuilder = + new RuleClass.Builder("childRuleClass", RuleClassType.NORMAL, false, parentRuleClass) .factory(DUMMY_CONFIGURED_TARGET_FACTORY) .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_RULE); RuleClass childRuleClass = childRuleClassBuilder.build(); + assertThat(childRuleClass.executionPlatformConstraintsAllowed()) + .isEqualTo(ExecutionPlatformConstraintsAllowed.PER_RULE); assertThat(childRuleClass.hasAttr("exec_compatible_with", LABEL_LIST)).isFalse(); } @@ -1162,6 +1209,8 @@ RuleClass childRuleClass = childRuleClassBuilder.build(); + assertThat(childRuleClass.executionPlatformConstraintsAllowed()) + .isEqualTo(ExecutionPlatformConstraintsAllowed.PER_TARGET); assertThat(childRuleClass.hasAttr("exec_compatible_with", LABEL_LIST)).isTrue(); }