diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
5 files changed, 183 insertions, 76 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/AutoCpuConverter.java b/src/main/java/com/google/devtools/build/lib/analysis/config/AutoCpuConverter.java new file mode 100644 index 0000000000..d63ffdd630 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/AutoCpuConverter.java @@ -0,0 +1,107 @@ +// 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.analysis.config; + +import com.google.devtools.build.lib.util.CPU; +import com.google.devtools.build.lib.util.OS; +import com.google.devtools.build.lib.util.Pair; +import com.google.devtools.common.options.Converter; +import com.google.devtools.common.options.OptionsParsingException; + +/** + * Converter to auto-detect the cpu of the machine on which Bazel runs. + * + * <p>If the compilation happens remotely then the cpu of the remote machine might be different from + * the auto-detected one and the --cpu and --host_cpu options must be set explicitly. + */ +public class AutoCpuConverter implements Converter<String> { + @Override + public String convert(String input) throws OptionsParsingException { + if (input.isEmpty()) { + // TODO(philwo) - replace these deprecated names with more logical ones (e.g. k8 becomes + // linux-x86_64, darwin includes the CPU architecture, ...). + switch (OS.getCurrent()) { + case DARWIN: + return "darwin"; + case FREEBSD: + return "freebsd"; + case WINDOWS: + switch (CPU.getCurrent()) { + case X86_64: + return "x64_windows"; + default: + // We only support x64 Windows for now. + return "unknown"; + } + case LINUX: + switch (CPU.getCurrent()) { + case X86_32: + return "piii"; + case X86_64: + return "k8"; + case PPC: + return "ppc"; + case ARM: + return "arm"; + case S390X: + return "s390x"; + default: + return "unknown"; + } + default: + return "unknown"; + } + } + return input; + } + + /** Reverses the conversion performed by {@link #convert} to return the matching OS, CPU pair. */ + public static Pair<CPU, OS> reverse(String input) { + if (input == null || input.length() == 0 || "unknown".equals(input)) { + // Use the auto-detected values. + return Pair.of(CPU.getCurrent(), OS.getCurrent()); + } + + // Handle the easy cases. + if (input.startsWith("darwin")) { + return Pair.of(CPU.getCurrent(), OS.DARWIN); + } else if (input.startsWith("freebsd")) { + return Pair.of(CPU.getCurrent(), OS.FREEBSD); + } else if (input.startsWith("x64_windows")) { + return Pair.of(CPU.getCurrent(), OS.WINDOWS); + } + + // Handle the Linux cases. + if (input.equals("piii")) { + return Pair.of(CPU.X86_32, OS.LINUX); + } else if (input.equals("k8")) { + return Pair.of(CPU.X86_64, OS.LINUX); + } else if (input.equals("ppc")) { + return Pair.of(CPU.PPC, OS.LINUX); + } else if (input.equals("arm")) { + return Pair.of(CPU.ARM, OS.LINUX); + } else if (input.equals("s390x")) { + return Pair.of(CPU.S390X, OS.LINUX); + } + + // Use the auto-detected values. + return Pair.of(CPU.getCurrent(), OS.getCurrent()); + } + + @Override + public String getTypeDescription() { + return "a string"; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index 4e37488ad6..9d2f766ac6 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -68,7 +68,6 @@ import com.google.devtools.build.lib.rules.test.TestActionBuilder; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; -import com.google.devtools.build.lib.util.CPU; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.util.Pair; @@ -442,59 +441,6 @@ public final class BuildConfiguration implements BuildEvent { } /** - * Converter to auto-detect the cpu of the machine on which Bazel runs. - * - * <p>If the compilation happens remotely then the cpu of the remote machine might be different - * from the auto-detected one and the --cpu and --host_cpu options must be set explicitly. - */ - public static class AutoCpuConverter implements Converter<String> { - @Override - public String convert(String input) throws OptionsParsingException { - if (input.isEmpty()) { - // TODO(philwo) - replace these deprecated names with more logical ones (e.g. k8 becomes - // linux-x86_64, darwin includes the CPU architecture, ...). - switch (OS.getCurrent()) { - case DARWIN: - return "darwin"; - case FREEBSD: - return "freebsd"; - case WINDOWS: - switch (CPU.getCurrent()) { - case X86_64: - return "x64_windows"; - default: - // We only support x64 Windows for now. - return "unknown"; - } - case LINUX: - switch (CPU.getCurrent()) { - case X86_32: - return "piii"; - case X86_64: - return "k8"; - case PPC: - return "ppc"; - case ARM: - return "arm"; - case S390X: - return "s390x"; - default: - return "unknown"; - } - default: - return "unknown"; - } - } - return input; - } - - @Override - public String getTypeDescription() { - return "a string"; - } - } - - /** * Options that affect the value of a BuildConfiguration instance. * * <p>(Note: any client that creates a view will also need to declare diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java index f8b44d91a8..648dcac0ba 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; +import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.ClassObjectConstructor; @@ -52,14 +53,16 @@ public class PlatformInfo extends SkylarkClassObject { private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE = FunctionSignature.WithValues.create( FunctionSignature.of( - /*numMandatoryPositionals=*/ 1, + /*numMandatoryPositionals=*/ 2, /*numOptionalPositionals=*/ 0, /*numMandatoryNamedOnly*/ 0, /*starArg=*/ false, /*kwArg=*/ false, - /*names=*/ "constraint_values"), + /*names=*/ "label", + "constraint_values"), /*defaultValues=*/ null, /*types=*/ ImmutableList.<SkylarkType>of( + SkylarkType.of(Label.class), SkylarkType.Combination.of( SkylarkType.LIST, SkylarkType.of(ConstraintValueInfo.class)))); @@ -69,12 +72,17 @@ public class PlatformInfo extends SkylarkClassObject { @Override protected PlatformInfo createInstanceFromSkylark(Object[] args, Location loc) throws EvalException { - // Based on SIGNATURE above, the args are constraint_values. + // Based on SIGNATURE above, the args are label, constraint_values. + Label label = (Label) args[0]; SkylarkList<ConstraintValueInfo> constraintValues = - (SkylarkList<ConstraintValueInfo>) args[0]; + (SkylarkList<ConstraintValueInfo>) args[1]; try { - return builder().addConstraints(constraintValues).setLocation(loc).build(); + return builder() + .setLabel(label) + .addConstraints(constraintValues) + .setLocation(loc) + .build(); } catch (DuplicateConstraintException dce) { throw new EvalException( loc, String.format("Cannot create PlatformInfo: %s", dce.getMessage())); @@ -86,21 +94,37 @@ public class PlatformInfo extends SkylarkClassObject { public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + private final Label label; private final ImmutableList<ConstraintValueInfo> constraints; private final ImmutableMap<String, String> remoteExecutionProperties; private PlatformInfo( + Label label, ImmutableList<ConstraintValueInfo> constraints, ImmutableMap<String, String> remoteExecutionProperties, Location location) { super( - SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("constraints", constraints), location); + SKYLARK_CONSTRUCTOR, + ImmutableMap.<String, Object>of( + "label", label, + "constraints", constraints), + location); + this.label = label; this.constraints = constraints; this.remoteExecutionProperties = remoteExecutionProperties; } @SkylarkCallable( + name = "label", + doc = "The label of the target that created this platform.", + structField = true + ) + public Label label() { + return label; + } + + @SkylarkCallable( name = "constraints", doc = "The <a href=\"ConstraintValueInfo.html\">ConstraintValueInfo</a> instances that define " @@ -127,11 +151,23 @@ public class PlatformInfo extends SkylarkClassObject { /** Builder class to facilitate creating valid {@link PlatformInfo} instances. */ public static class Builder { + private Label label; private final List<ConstraintValueInfo> constraints = new ArrayList<>(); private final Map<String, String> remoteExecutionProperties = new HashMap<>(); private Location location = Location.BUILTIN; /** + * Sets the {@link Label} for this {@link PlatformInfo}. + * + * @param label the label identifying this platform + * @return the {@link Builder} instance for method chaining + */ + public Builder setLabel(Label label) { + this.label = label; + return this; + } + + /** * Adds the given constraint value to the constraints that define this {@link PlatformInfo}. * * @param constraint the constraint to add @@ -203,7 +239,7 @@ public class PlatformInfo extends SkylarkClassObject { public PlatformInfo build() throws DuplicateConstraintException { ImmutableList<ConstraintValueInfo> validatedConstraints = validateConstraints(constraints); return new PlatformInfo( - validatedConstraints, ImmutableMap.copyOf(remoteExecutionProperties), location); + label, validatedConstraints, ImmutableMap.copyOf(remoteExecutionProperties), location); } private ImmutableList<ConstraintValueInfo> validateConstraints( 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 87d4b6be7a..31f6dd0530 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 @@ -21,6 +21,7 @@ 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.analysis.config.AutoCpuConverter; import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo; import com.google.devtools.build.lib.analysis.platform.PlatformInfo; import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils; @@ -28,6 +29,7 @@ import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; 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 com.google.devtools.build.lib.util.Pair; import java.util.Map; /** Defines a platform for execution contexts. */ @@ -36,11 +38,16 @@ public class Platform implements RuleConfiguredTargetFactory { public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException { - PlatformInfo.Builder platformBuilder = PlatformInfo.builder(); + PlatformInfo.Builder platformBuilder = PlatformInfo.builder().setLabel(ruleContext.getLabel()); if (ruleContext.attributes().get(PlatformRule.HOST_PLATFORM_ATTR, Type.BOOLEAN)) { + // Create default constraints based on the current host OS and CPU values. + String cpuOption = ruleContext.getConfiguration().getHostCpu(); + autodetectConstraints(cpuOption, ruleContext, platformBuilder); + } else if (ruleContext.attributes().get(PlatformRule.TARGET_PLATFORM_ATTR, Type.BOOLEAN)) { // Create default constraints based on the current OS and CPU values. - autodetectHostConstraints(ruleContext, platformBuilder); + String cpuOption = ruleContext.getConfiguration().getCpu(); + autodetectConstraints(cpuOption, ruleContext, platformBuilder); } else { platformBuilder.addConstraints( PlatformProviderUtils.constraintValues( @@ -68,14 +75,16 @@ public class Platform implements RuleConfiguredTargetFactory { .build(); } - private void autodetectHostConstraints( - RuleContext ruleContext, PlatformInfo.Builder platformBuilder) { + private void autodetectConstraints( + String cpuOption, RuleContext ruleContext, PlatformInfo.Builder platformBuilder) { + + Pair<CPU, OS> cpuValues = AutoCpuConverter.reverse(cpuOption); // Add the CPU. - CPU cpu = CPU.getCurrent(); + CPU cpu = cpuValues.getFirst(); Iterable<ConstraintValueInfo> cpuConstraintValues = PlatformProviderUtils.constraintValues( - ruleContext.getPrerequisites(PlatformRule.HOST_CPU_CONSTRAINTS_ATTR, Mode.DONT_CHECK)); + ruleContext.getPrerequisites(PlatformRule.CPU_CONSTRAINTS_ATTR, Mode.DONT_CHECK)); for (ConstraintValueInfo constraint : cpuConstraintValues) { if (cpu.getCanonicalName().equals(constraint.label().getName())) { platformBuilder.addConstraint(constraint); @@ -84,10 +93,10 @@ public class Platform implements RuleConfiguredTargetFactory { } // Add the OS. - OS os = OS.getCurrent(); + OS os = cpuValues.getSecond(); Iterable<ConstraintValueInfo> osConstraintValues = PlatformProviderUtils.constraintValues( - ruleContext.getPrerequisites(PlatformRule.HOST_OS_CONSTRAINTS_ATTR, Mode.DONT_CHECK)); + ruleContext.getPrerequisites(PlatformRule.OS_CONSTRAINTS_ATTR, Mode.DONT_CHECK)); for (ConstraintValueInfo constraint : osConstraintValues) { if (os.getCanonicalName().equals(constraint.label().getName())) { platformBuilder.addConstraint(constraint); 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 c4c88770a6..10344bb6ea 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 @@ -32,8 +32,9 @@ public class PlatformRule implements RuleDefinition { 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"; + static final String TARGET_PLATFORM_ATTR = "target_platform"; + static final String CPU_CONSTRAINTS_ATTR = "cpu_constraints"; + static final String OS_CONSTRAINTS_ATTR = "os_constraints"; @Override public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { @@ -59,20 +60,28 @@ public class PlatformRule implements RuleDefinition { .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. + // based on the current host 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. + // Undocumented. Indicates that this platform should auto-configure the platform constraints + // based on the current OS and CPU settings. + .add( + attr(TARGET_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 automatic CPU + // mapping. .add( - attr(HOST_CPU_CONSTRAINTS_ATTR, BuildType.LABEL_LIST) + attr(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. + // Undocumented. Indicates to the rule which constraint_values to use for automatic CPU + // mapping. .add( - attr(HOST_OS_CONSTRAINTS_ATTR, BuildType.LABEL_LIST) + attr(OS_CONSTRAINTS_ATTR, BuildType.LABEL_LIST) .allowedFileTypes(FileTypeSet.NO_FILE) .mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER)) .undocumented("Should only be used by internal packages.")) |