diff options
author | John Cater <jcater@google.com> | 2018-06-05 11:09:01 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-06-05 11:10:48 -0700 |
commit | ee45c6610ae213c12d57bf9e8e5ff674d7a9d7fc (patch) | |
tree | a564f798205c25ec3987b00fdc38a19e4bbfdd65 /src/main/java/com/google/devtools/build/lib/packages | |
parent | 41bf88da4e4bf7d0ecfba2d935736cae9f93cf19 (diff) |
Allow rules and targets to specify extra execution platform constraints.
RuleClass.Builder now allows authors to specify whether a rule's targets
can add additional constraints on the execution platform, and to declare
additional constraints for all targets of that rule.
Targets which support this now have an attribute,
"exec_compatible_with", which supports specifying additional constraints
that the execution platform used must match.
This attribute is non-configurable. It will only affect execution
platforms used during toolchain resolution.
Part of #5217.
Change-Id: Id2400dbf869a00aa2be3e3d2f085c2850cd6dc00
Closes #5227.
Change-Id: If7d55f08f7f44bc7d7f6dfec86a3e6bcd68574b9
PiperOrigin-RevId: 199326255
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/packages')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/packages/RuleClass.java | 110 |
1 files changed, 106 insertions, 4 deletions
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 d83246871d..330278f1aa 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 @@ -202,6 +202,23 @@ public class RuleClass { } /** + * Describes in which way a rule implementation allows additional execution platform constraints. + */ + public enum ExecutionPlatformConstraintsAllowed { + /** + * Allows additional execution platform constraints to be added in the rule definition, which + * apply to all targets of that rule. + */ + PER_RULE, + /** + * 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; + } + + /** * For Bazel's constraint system: the attribute that declares the set of environments a rule * supports, overriding the defaults for their respective groups. */ @@ -615,6 +632,9 @@ public class RuleClass { private final Map<String, Attribute> attributes = new LinkedHashMap<>(); private final Set<Label> requiredToolchains = new HashSet<>(); private boolean supportsPlatforms = true; + private ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed = + ExecutionPlatformConstraintsAllowed.PER_RULE; + private Set<Label> executionPlatformConstraints = new HashSet<>(); private OutputFile.Kind outputFileKind = OutputFile.Kind.FILE; /** @@ -648,6 +668,8 @@ public class RuleClass { addRequiredToolchains(parent.getRequiredToolchains()); supportsPlatforms = parent.supportsPlatforms; + // executionPlatformConstraintsAllowed is not inherited and takes the default. + addExecutionPlatformConstraints(parent.getExecutionPlatformConstraints()); for (Attribute attribute : parent.getAttributes()) { String attrName = attribute.getName(); @@ -656,6 +678,13 @@ public class RuleClass { "Attribute %s is inherited multiple times in %s ruleclass", attrName, name); + if (attrName.equals("exec_compatible_with") + && parent.executionPlatformConstraintsAllowed + == ExecutionPlatformConstraintsAllowed.PER_TARGET) { + // This attribute should not be inherited because executionPlatformConstraintsAllowed is + // not inherited. + continue; + } attributes.put(attrName, attribute); } @@ -708,6 +737,19 @@ public class RuleClass { if (type == RuleClassType.PLACEHOLDER) { Preconditions.checkNotNull(ruleDefinitionEnvironmentHashCode, this.name); } + if (executionPlatformConstraintsAllowed == ExecutionPlatformConstraintsAllowed.PER_TARGET) { + // Only rules that allow per target execution constraints need this attribute. + Preconditions.checkState( + !this.attributes.containsKey("exec_compatible_with"), + "Rule should not already define the attribute \"exec_compatible_with\"" + + " if executionPlatformConstraintsAllowed is set to PER_TARGET"); + this.add( + attr("exec_compatible_with", BuildType.LABEL_LIST) + .allowedFileTypes() + .nonconfigurable("Used in toolchain resolution") + .value(ImmutableList.of())); + } + return new RuleClass( name, key, @@ -735,6 +777,8 @@ public class RuleClass { supportsConstraintChecking, requiredToolchains, supportsPlatforms, + executionPlatformConstraintsAllowed, + executionPlatformConstraints, outputFileKind, attributes.values()); } @@ -912,8 +956,8 @@ public class RuleClass { /** * Applies the given transition factory to all incoming edges for this rule class. * - * <p>Unlike{@link #cfg(PatchTransition)}, the factory can examine the rule when - * deciding what transition to use. + * <p>Unlike {@link #cfg(PatchTransition)}, the factory can examine the rule when deciding what + * transition to use. */ public Builder cfg(RuleTransitionFactory transitionFactory) { Preconditions.checkState(type != RuleClassType.ABSTRACT, @@ -1161,22 +1205,66 @@ public class RuleClass { return this; } + /** + * Causes rules of this type to require the specified toolchains be available via toolchain + * resolution when a target is configured. + */ public Builder addRequiredToolchains(Iterable<Label> toolchainLabels) { Iterables.addAll(this.requiredToolchains, toolchainLabels); return this; } + /** + * Causes rules of this type to require the specified toolchains be available via toolchain + * resolution when a target is configured. + */ public Builder addRequiredToolchains(Label... toolchainLabels) { - Iterables.addAll(this.requiredToolchains, Lists.newArrayList(toolchainLabels)); - return this; + return this.addRequiredToolchains(Lists.newArrayList(toolchainLabels)); } + /** + * Rules that support platforms can use toolchains and execution platforms. Rules that are part + * of configuring toolchains and platforms should set this to {@code false}. + */ public Builder supportsPlatforms(boolean flag) { this.supportsPlatforms = flag; return this; } /** + * Specifies whether targets of this rule can add additional constraints on the execution + * platform selected. If this is {@link ExecutionPlatformConstraintsAllowed#PER_TARGET}, there + * will be an attribute named {@code exec_compatible_with} that can be used to add these + * constraints. + * + * <p>Please note that this value is not inherited by child rules, and must be re-set on them if + * the same behavior is required. + */ + public Builder executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed value) { + this.executionPlatformConstraintsAllowed = value; + return this; + } + + /** + * Adds additional execution platform constraints that apply for all targets from this rule. + * + * <p>Please note that this value is inherited by child rules. + */ + public Builder addExecutionPlatformConstraints(Label... constraints) { + return this.addExecutionPlatformConstraints(Lists.newArrayList(constraints)); + } + + /** + * Adds additional execution platform constraints that apply for all targets from this rule. + * + * <p>Please note that this value is inherited by child rules. + */ + public Builder addExecutionPlatformConstraints(Iterable<Label> constraints) { + Iterables.addAll(this.executionPlatformConstraints, constraints); + return this; + } + + /** * Returns an Attribute.Builder object which contains a replica of the * same attribute in the parent rule if exists. * @@ -1294,6 +1382,8 @@ public class RuleClass { private final ImmutableSet<Label> requiredToolchains; private final boolean supportsPlatforms; + private final ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed; + private final ImmutableSet<Label> executionPlatformConstraints; /** * Constructs an instance of RuleClass whose name is 'name', attributes are 'attributes'. The @@ -1343,6 +1433,8 @@ public class RuleClass { boolean supportsConstraintChecking, Set<Label> requiredToolchains, boolean supportsPlatforms, + ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed, + Set<Label> executionPlatformConstraints, OutputFile.Kind outputFileKind, Collection<Attribute> attributes) { this.name = name; @@ -1375,6 +1467,8 @@ public class RuleClass { this.supportsConstraintChecking = supportsConstraintChecking; this.requiredToolchains = ImmutableSet.copyOf(requiredToolchains); this.supportsPlatforms = supportsPlatforms; + this.executionPlatformConstraintsAllowed = executionPlatformConstraintsAllowed; + this.executionPlatformConstraints = ImmutableSet.copyOf(executionPlatformConstraints); // Create the index and collect non-configurable attributes. int index = 0; @@ -2191,6 +2285,14 @@ public class RuleClass { return supportsPlatforms; } + public ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed() { + return executionPlatformConstraintsAllowed; + } + + public ImmutableSet<Label> getExecutionPlatformConstraints() { + return executionPlatformConstraints; + } + @Nullable public OutputFile.Kind getOutputFileKind() { return outputFileKind; |