aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/platform
diff options
context:
space:
mode:
authorGravatar John Cater <jcater@google.com>2017-03-02 08:55:10 +0000
committerGravatar Yue Gan <yueg@google.com>2017-03-02 13:32:11 +0000
commit4f2b41d3f5fe936833380a0446adb671b8a50b1f (patch)
tree52f22bb8a592b779467b018bb4d2b5e6133f3f65 /src/main/java/com/google/devtools/build/lib/rules/platform
parent30a994102a3b7c856a313325051c10240f0ee3ef (diff)
Add platform rule to define a platform as a collection of constraint values.
Part of ongoing work on #2219. -- Change-Id: Ie4e842a5d8218e47f41a954c2b955ab24237aa65 Reviewed-on: https://cr.bazel.build/9116 PiperOrigin-RevId: 148976893 MOS_MIGRATED_REVID=148976893
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/platform')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/platform/Platform.java101
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/platform/PlatformProvider.java32
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/platform/PlatformRule.java93
3 files changed, 226 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/Platform.java b/src/main/java/com/google/devtools/build/lib/rules/platform/Platform.java
new file mode 100644
index 0000000000..f652383757
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/platform/Platform.java
@@ -0,0 +1,101 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.platform;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.FileProvider;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+
+/** Defines a platform for execution contexts. */
+public class Platform implements RuleConfiguredTargetFactory {
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext)
+ throws InterruptedException, RuleErrorException {
+
+ Iterable<ConstraintValueProvider> constraintValues =
+ ruleContext.getPrerequisites(
+ PlatformRule.CONSTRAINT_VALUES_ATTR, Mode.DONT_CHECK, ConstraintValueProvider.class);
+
+ // Verify the constraints - no two values for the same setting, and construct the map.
+ ImmutableMap<ConstraintSettingProvider, ConstraintValueProvider> constraints =
+ validateConstraints(ruleContext, constraintValues);
+ if (constraints == null) {
+ // An error occurred, return null.
+ return null;
+ }
+
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
+ .addProvider(FileProvider.class, FileProvider.EMPTY)
+ .addProvider(FilesToRunProvider.class, FilesToRunProvider.EMPTY)
+ .addProvider(PlatformProvider.class, PlatformProvider.create(constraints))
+ .build();
+ }
+
+ private ImmutableMap<ConstraintSettingProvider, ConstraintValueProvider> validateConstraints(
+ RuleContext ruleContext, Iterable<ConstraintValueProvider> constraintValues) {
+ Multimap<ConstraintSettingProvider, ConstraintValueProvider> constraints =
+ ArrayListMultimap.create();
+
+ for (ConstraintValueProvider constraintValue : constraintValues) {
+ constraints.put(constraintValue.constraint(), constraintValue);
+ }
+
+ // Are there any settings with more than one value?
+ boolean foundError = false;
+ for (ConstraintSettingProvider constraintSetting : constraints.keySet()) {
+ if (constraints.get(constraintSetting).size() > 1) {
+ foundError = true;
+ // error
+ StringBuilder constraintValuesDescription = new StringBuilder();
+ for (ConstraintValueProvider constraintValue : constraints.get(constraintSetting)) {
+ if (constraintValuesDescription.length() > 0) {
+ constraintValuesDescription.append(", ");
+ }
+ constraintValuesDescription.append(constraintValue.value());
+ }
+ ruleContext.attributeError(
+ PlatformRule.CONSTRAINT_VALUES_ATTR,
+ String.format(
+ "Duplicate constraint_values for constraint_setting %s: %s",
+ constraintSetting.constraintSetting(), constraintValuesDescription.toString()));
+ }
+ }
+
+ if (foundError) {
+ return null;
+ }
+
+ // Convert to a flat map.
+ ImmutableMap.Builder<ConstraintSettingProvider, ConstraintValueProvider> builder =
+ new ImmutableMap.Builder<>();
+ for (ConstraintSettingProvider constraintSetting : constraints.keySet()) {
+ ConstraintValueProvider constraintValue =
+ Iterables.getOnlyElement(constraints.get(constraintSetting));
+ builder.put(constraintSetting, constraintValue);
+ }
+
+ return builder.build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformProvider.java b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformProvider.java
new file mode 100644
index 0000000000..7a06c1f138
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformProvider.java
@@ -0,0 +1,32 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.platform;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/** Provider for a platform, which is a group of constraints and values. */
+@AutoValue
+@Immutable
+public abstract class PlatformProvider implements TransitiveInfoProvider {
+ public abstract ImmutableMap<ConstraintSettingProvider, ConstraintValueProvider> constraints();
+
+ public static PlatformProvider create(
+ ImmutableMap<ConstraintSettingProvider, ConstraintValueProvider> constraints) {
+ return new AutoValue_PlatformProvider(constraints);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformRule.java b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformRule.java
new file mode 100644
index 0000000000..29537a4fb0
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformRule.java
@@ -0,0 +1,93 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.rules.platform;
+
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+/** Rule definition for {@link Platform}. */
+public class PlatformRule implements RuleDefinition {
+ public static final String RULE_NAME = "platform";
+ public static final String CONSTRAINT_VALUES_ATTR = "constraint_values";
+
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
+ /* <!-- #BLAZE_RULE(platform).NAME -->
+ <!-- #END_BLAZE_RULE.NAME --> */
+ return builder
+ .override(
+ attr("tags", Type.STRING_LIST)
+ // No need to show up in ":all", etc. target patterns.
+ .value(ImmutableList.of("manual"))
+ .nonconfigurable("low-level attribute, used in platform configuration"))
+ .add(
+ attr(CONSTRAINT_VALUES_ATTR, BuildType.LABEL_LIST)
+ .allowedFileTypes(FileTypeSet.NO_FILE)
+ .mandatoryNativeProviders(
+ ImmutableList.<Class<? extends TransitiveInfoProvider>>of(
+ ConstraintValueProvider.class)))
+ .removeAttribute("deps")
+ .removeAttribute("data")
+ .exemptFromConstraintChecking("this rule is part of constraint definition")
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return Metadata.builder()
+ .name(RULE_NAME)
+ .ancestors(BaseRuleClasses.RuleBase.class)
+ .factoryClass(Platform.class)
+ .build();
+ }
+}
+/*<!-- #BLAZE_RULE (NAME = platform, TYPE = OTHER, FAMILY = Platform)[GENERIC_RULE] -->
+
+<p>This rule defines a platform, as a collection of constraint_values.
+
+<h4 id="platform_examples">Examples</h4>
+<p>
+ This defines two possible platforms, each targeting a different CPU type.
+</p>
+<pre class="code">
+constraint_setting(name="cpu")
+constraint_value(
+ name="arm64",
+ constraint=":cpu")
+constraint_value(
+ name="k8",
+ constraint=":cpu")
+platform(
+ name="mobile_device",
+ constraints = [
+ ":arm64",
+ ])
+platform(
+ name="devel",
+ constraints = [
+ ":k8",
+ ])
+</pre>
+
+<!-- #END_BLAZE_RULE -->*/