Add a undocumented way to define a platform that is autodetected from
the host.
Also add a single instance of that platform for standard usage.
Change-Id: I0e7a8eb3a44099076540c8d955fc0c0c70447583
PiperOrigin-RevId: 153878880
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
index c396605..d1c48e9 100644
--- 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
@@ -24,6 +24,8 @@
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.platform.PlatformInfo.DuplicateConstraintException;
import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.CPU;
+import com.google.devtools.build.lib.util.OS;
import java.util.Map;
/** Defines a platform for execution contexts. */
@@ -32,12 +34,16 @@
public ConfiguredTarget create(RuleContext ruleContext)
throws InterruptedException, RuleErrorException {
- Iterable<ConstraintValueInfo> constraintValues =
- ConstraintValueInfo.fromTargets(
- ruleContext.getPrerequisites(PlatformRule.CONSTRAINT_VALUES_ATTR, Mode.DONT_CHECK));
-
PlatformInfo.Builder platformBuilder = PlatformInfo.builder();
- platformBuilder.addConstraints(constraintValues);
+
+ if (ruleContext.attributes().get(PlatformRule.HOST_PLATFORM_ATTR, Type.BOOLEAN)) {
+ // Create default constraints based on the current OS and CPU values.
+ autodetectHostConstraints(ruleContext, platformBuilder);
+ } else {
+ platformBuilder.addConstraints(
+ ConstraintValueInfo.fromTargets(
+ ruleContext.getPrerequisites(PlatformRule.CONSTRAINT_VALUES_ATTR, Mode.DONT_CHECK)));
+ }
Map<String, String> remoteExecutionProperties =
ruleContext.attributes().get(PlatformRule.REMOTE_EXECUTION_PROPS_ATTR, Type.STRING_DICT);
@@ -59,4 +65,32 @@
.addNativeDeclaredProvider(platformInfo)
.build();
}
+
+ private void autodetectHostConstraints(
+ RuleContext ruleContext, PlatformInfo.Builder platformBuilder) {
+
+ // Add the CPU.
+ CPU cpu = CPU.getCurrent();
+ Iterable<ConstraintValueInfo> cpuConstraintValues =
+ ConstraintValueInfo.fromTargets(
+ ruleContext.getPrerequisites(PlatformRule.HOST_CPU_CONSTRAINTS_ATTR, Mode.DONT_CHECK));
+ for (ConstraintValueInfo constraint : cpuConstraintValues) {
+ if (cpu.getCanonicalName().equals(constraint.label().getName())) {
+ platformBuilder.addConstraint(constraint);
+ break;
+ }
+ }
+
+ // Add the OS.
+ OS os = OS.getCurrent();
+ Iterable<ConstraintValueInfo> osConstraintValues =
+ ConstraintValueInfo.fromTargets(
+ ruleContext.getPrerequisites(PlatformRule.HOST_OS_CONSTRAINTS_ATTR, Mode.DONT_CHECK));
+ for (ConstraintValueInfo constraint : osConstraintValues) {
+ if (os.getCanonicalName().equals(constraint.label().getName())) {
+ platformBuilder.addConstraint(constraint);
+ break;
+ }
+ }
+ }
}
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
index cd33243..126cd9d 100644
--- 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
@@ -30,6 +30,9 @@
public static final String RULE_NAME = "platform";
public static final String CONSTRAINT_VALUES_ATTR = "constraint_values";
public static final String REMOTE_EXECUTION_PROPS_ATTR = "remote_execution_properties";
+ static final String HOST_PLATFORM_ATTR = "host_platform";
+ static final String HOST_CPU_CONSTRAINTS_ATTR = "host_cpu_constraints";
+ static final String HOST_OS_CONSTRAINTS_ATTR = "host_os_constraints";
@Override
public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
@@ -41,11 +44,37 @@
// No need to show up in ":all", etc. target patterns.
.value(ImmutableList.of("manual"))
.nonconfigurable("low-level attribute, used in platform configuration"))
+ /* <!-- #BLAZE_RULE(platform).ATTRIBUTE(constraint_values) -->
+ The constraint_values that define this platform.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(
attr(CONSTRAINT_VALUES_ATTR, BuildType.LABEL_LIST)
.allowedFileTypes(FileTypeSet.NO_FILE)
.mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER)))
+
+ /* <!-- #BLAZE_RULE(platform).ATTRIBUTE(remote_execution_properties) -->
+ A key/value dict of values that will be sent to a remote execution platform.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr(REMOTE_EXECUTION_PROPS_ATTR, Type.STRING_DICT))
+
+ // Undocumented. Indicates that this platform should auto-configure the platform constraints
+ // based on the current OS and CPU settings.
+ .add(
+ attr(HOST_PLATFORM_ATTR, Type.BOOLEAN)
+ .value(false)
+ .undocumented("Should only be used by internal packages."))
+ // Undocumented. Indicates to the rule which constraint_values to use for host CPU mapping.
+ .add(
+ attr(HOST_CPU_CONSTRAINTS_ATTR, BuildType.LABEL_LIST)
+ .allowedFileTypes(FileTypeSet.NO_FILE)
+ .mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER))
+ .undocumented("Should only be used by internal packages."))
+ // Undocumented. Indicates to the rule which constraint_values to use for host OS mapping.
+ .add(
+ attr(HOST_OS_CONSTRAINTS_ATTR, BuildType.LABEL_LIST)
+ .allowedFileTypes(FileTypeSet.NO_FILE)
+ .mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER))
+ .undocumented("Should only be used by internal packages."))
.removeAttribute("deps")
.removeAttribute("data")
.exemptFromConstraintChecking("this rule is part of constraint definition")
diff --git a/src/test/java/com/google/devtools/build/lib/rules/platform/BUILD b/src/test/java/com/google/devtools/build/lib/rules/platform/BUILD
index 82e48b0..39b1617 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/platform/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/rules/platform/BUILD
@@ -10,7 +10,9 @@
test_class = "com.google.devtools.build.lib.AllTests",
deps = [
"//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:os_util",
"//src/main/java/com/google/devtools/build/lib:syntax",
+ "//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/rules/platform",
"//src/test/java/com/google/devtools/build/lib:analysis_testutil",
diff --git a/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformTest.java b/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformTest.java
index d07fe4d..5cb0991 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/platform/PlatformTest.java
@@ -22,6 +22,8 @@
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.platform.PlatformInfo.DuplicateConstraintException;
+import com.google.devtools.build.lib.util.CPU;
+import com.google.devtools.build.lib.util.OS;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -66,6 +68,39 @@
}
@Test
+ public void testPlatform_host() throws Exception {
+ String currentCpu = CPU.getCurrent().getCanonicalName();
+ String currentOs = OS.getCurrent().getCanonicalName();
+ scratch.file(
+ "host/BUILD",
+ "constraint_setting(name = 'cpu')",
+ "constraint_value(name = '" + currentCpu + "', constraint_setting = ':cpu')",
+ "constraint_value(name = 'another_cpu', constraint_setting = ':cpu')",
+ "constraint_setting(name = 'os')",
+ "constraint_value(name = '" + currentOs + "', constraint_setting = ':os')",
+ "constraint_value(name = 'another_os', constraint_setting = ':os')",
+ "platform(name = 'host_platform',",
+ " host_platform = True,",
+ " host_cpu_constraints = [':" + currentCpu + "', ':another_cpu'],",
+ " host_os_constraints = [':" + currentOs + "', ':another_os'],",
+ ")");
+
+ ConfiguredTarget platform = getConfiguredTarget("//host:host_platform");
+ assertThat(platform).isNotNull();
+
+ PlatformInfo provider = PlatformInfo.fromTarget(platform);
+ assertThat(provider).isNotNull();
+
+ // Check the CPU and OS.
+ ConstraintSettingInfo cpuConstraint = ConstraintSettingInfo.create(makeLabel("//host:cpu"));
+ ConstraintSettingInfo osConstraint = ConstraintSettingInfo.create(makeLabel("//host:os"));
+ assertThat(provider.constraints())
+ .containsExactly(
+ ConstraintValueInfo.create(cpuConstraint, makeLabel("//host:" + currentCpu)),
+ ConstraintValueInfo.create(osConstraint, makeLabel("//host:" + currentOs)));
+ }
+
+ @Test
public void testPlatform_overlappingConstraintValueError() throws Exception {
checkError(
"constraint/overlap",