diff options
author | 2017-05-01 17:41:12 +0200 | |
---|---|---|
committer | 2017-05-02 11:25:44 +0200 | |
commit | 248581e8c72687c85b5c41edaea6780c8701aa55 (patch) | |
tree | f62dd1831c79c9c886cbeeebefedb1e3319f155a /src/main/java/com/google/devtools/build/lib/analysis | |
parent | 38b835097f9ae9a6062172b8a33ec2e2d1edde20 (diff) |
Move platform providers to a new package to break cyclic dependencies.
Part of #2219.
Change-Id: I87c7bc9fbfb38d3dbdf193b46247901d0f2a838d
PiperOrigin-RevId: 154719063
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis')
5 files changed, 470 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/platform/BUILD new file mode 100644 index 0000000000..ce3a69d759 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/BUILD @@ -0,0 +1,24 @@ +# Description: +# Providers defined for platforms, constraints, and toolchains. + +package( + default_visibility = ["//src:__subpackages__"], +) + +java_library( + name = "platform", + srcs = glob([ + "*.java", + ]), + deps = [ + "//src/main/java/com/google/devtools/build/lib:packages", + "//src/main/java/com/google/devtools/build/lib:skylarkinterface", + "//third_party:guava", + ], +) + +filegroup( + name = "srcs", + testonly = 0, # All srcs should be not test only, overwrite package default. + srcs = glob(["**"]), +) diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java new file mode 100644 index 0000000000..817580e8fa --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java @@ -0,0 +1,63 @@ +// 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.platform; + +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.ClassObjectConstructor; +import com.google.devtools.build.lib.packages.NativeClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkClassObject; +import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; + +/** Provider for a platform constraint setting that is available to be fulfilled. */ +@SkylarkModule( + name = "ConstraintSettingInfo", + doc = "A specific constraint setting that may be used to define a platform.", + category = SkylarkModuleCategory.PROVIDER +) +@Immutable +public class ConstraintSettingInfo extends SkylarkClassObject { + + /** Name used in Skylark for accessing this provider. */ + public static final String SKYLARK_NAME = "ConstraintSettingInfo"; + + /** Skylark constructor and identifier for this provider. */ + public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + /** Identifier used to retrieve this provider from rules which export it. */ + public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = + SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + + private final Label label; + + private ConstraintSettingInfo(Label label) { + super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("label", label)); + + this.label = label; + } + + public Label label() { + return label; + } + + /** Returns a new {@link ConstraintSettingInfo} with the given data. */ + public static ConstraintSettingInfo create(Label constraintSetting) { + return new ConstraintSettingInfo(constraintSetting); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java new file mode 100644 index 0000000000..9e58126264 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java @@ -0,0 +1,73 @@ +// 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.platform; + +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.ClassObjectConstructor; +import com.google.devtools.build.lib.packages.NativeClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkClassObject; +import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; + +/** Provider for a platform constraint value that fulfills a {@link ConstraintSettingInfo}. */ +@SkylarkModule( + name = "ConstraintValueProvider", + doc = "A value for a constraint setting that can be used to define a platform.", + category = SkylarkModuleCategory.PROVIDER +) +@Immutable +public class ConstraintValueInfo extends SkylarkClassObject { + + /** Name used in Skylark for accessing this provider. */ + public static final String SKYLARK_NAME = "ConstraintValueInfo"; + + /** Skylark constructor and identifier for this provider. */ + public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + /** Identifier used to retrieve this provider from rules which export it. */ + public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = + SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + + private final ConstraintSettingInfo constraint; + private final Label label; + + private ConstraintValueInfo(ConstraintSettingInfo constraint, Label label) { + super( + SKYLARK_CONSTRUCTOR, + ImmutableMap.<String, Object>of( + "constraint", constraint, + "label", label)); + + this.constraint = constraint; + this.label = label; + } + + public ConstraintSettingInfo constraint() { + return constraint; + } + + public Label label() { + return label; + } + + /** Returns a new {@link ConstraintValueInfo} with the given data. */ + public static ConstraintValueInfo create(ConstraintSettingInfo constraint, Label value) { + return new ConstraintValueInfo(constraint, value); + } +} 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 new file mode 100644 index 0000000000..64b9262adb --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java @@ -0,0 +1,207 @@ +// 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.platform; + +import com.google.common.collect.ArrayListMultimap; +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.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.ClassObjectConstructor; +import com.google.devtools.build.lib.packages.NativeClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkClassObject; +import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** Provider for a platform, which is a group of constraints and values. */ +@SkylarkModule( + name = "PlatformInfo", + doc = "Provides access to data about a specific platform.", + category = SkylarkModuleCategory.PROVIDER +) +@Immutable +public class PlatformInfo extends SkylarkClassObject { + + /** Name used in Skylark for accessing this provider. */ + public static final String SKYLARK_NAME = "PlatformInfo"; + + /** Skylark constructor and identifier for this provider. */ + public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + /** Identifier used to retrieve this provider from rules which export it. */ + public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = + SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + + private final ImmutableList<ConstraintValueInfo> constraints; + private final ImmutableMap<String, String> remoteExecutionProperties; + + private PlatformInfo( + ImmutableList<ConstraintValueInfo> constraints, + ImmutableMap<String, String> remoteExecutionProperties) { + super(SKYLARK_CONSTRUCTOR, ImmutableMap.<String, Object>of("constraints", constraints)); + + this.constraints = constraints; + this.remoteExecutionProperties = remoteExecutionProperties; + } + + public ImmutableList<ConstraintValueInfo> constraints() { + return constraints; + } + + @SkylarkCallable( + name = "remoteExecutionProperties", + doc = "Properties that are available for the use of remote execution.", + structField = true + ) + public ImmutableMap<String, String> remoteExecutionProperties() { + return remoteExecutionProperties; + } + + /** Returns a new {@link Builder} for creating a fresh {@link PlatformInfo} instance. */ + public static Builder builder() { + return new Builder(); + } + + /** Builder class to facilitate creating valid {@link PlatformInfo} instances. */ + public static class Builder { + private final List<ConstraintValueInfo> constraints = new ArrayList<>(); + private final Map<String, String> remoteExecutionProperties = new HashMap<>(); + + /** + * Adds the given constraint value to the constraints that define this {@link PlatformInfo}. + * + * @param constraint the constraint to add + * @return the {@link Builder} instance for method chaining + */ + public Builder addConstraint(ConstraintValueInfo constraint) { + this.constraints.add(constraint); + return this; + } + + /** + * Adds the given constraint values to the constraints that define this {@link PlatformInfo}. + * + * @param constraints the constraints to add + * @return the {@link Builder} instance for method chaining + */ + public Builder addConstraints(Iterable<ConstraintValueInfo> constraints) { + for (ConstraintValueInfo constraint : constraints) { + this.addConstraint(constraint); + } + + return this; + } + + /** + * Adds the given key/value pair to the data being sent to a potential remote executor. If the + * key already exists in the map, the previous value will be overwritten. + * + * @param key the key to be used + * @param value the value to be used + * @return the {@link Builder} instance for method chaining + */ + public Builder addRemoteExecutionProperty(String key, String value) { + this.remoteExecutionProperties.put(key, value); + return this; + } + + /** + * Adds the given properties to the data being sent to a potential remote executor. If any key + * already exists in the map, the previous value will be overwritten. + * + * @param properties the properties to be added + * @return the {@link Builder} instance for method chaining + */ + public Builder addRemoteExecutionProperties(Map<String, String> properties) { + for (Map.Entry<String, String> entry : properties.entrySet()) { + this.addRemoteExecutionProperty(entry.getKey(), entry.getValue()); + } + return this; + } + + /** + * Returns the new {@link PlatformInfo} instance. + * + * @throws DuplicateConstraintException if more than one constraint value exists for the same + * constraint setting + */ + public PlatformInfo build() throws DuplicateConstraintException { + ImmutableList<ConstraintValueInfo> validatedConstraints = validateConstraints(constraints); + return new PlatformInfo(validatedConstraints, ImmutableMap.copyOf(remoteExecutionProperties)); + } + + private ImmutableList<ConstraintValueInfo> validateConstraints( + Iterable<ConstraintValueInfo> constraintValues) throws DuplicateConstraintException { + Multimap<ConstraintSettingInfo, ConstraintValueInfo> constraints = ArrayListMultimap.create(); + + for (ConstraintValueInfo constraintValue : constraintValues) { + constraints.put(constraintValue.constraint(), constraintValue); + } + + // Are there any settings with more than one value? + for (ConstraintSettingInfo constraintSetting : constraints.keySet()) { + if (constraints.get(constraintSetting).size() > 1) { + // Only reports the first case of this error. + throw new DuplicateConstraintException( + constraintSetting, constraints.get(constraintSetting)); + } + } + + return ImmutableList.copyOf(constraints.values()); + } + } + + /** + * Exception class used when more than one {@link ConstraintValueInfo} for the same {@link + * ConstraintSettingInfo} is added to a {@link Builder}. + */ + public static class DuplicateConstraintException extends Exception { + private final ImmutableSet<ConstraintValueInfo> duplicateConstraints; + + public DuplicateConstraintException( + ConstraintSettingInfo constraintSetting, + Iterable<ConstraintValueInfo> duplicateConstraintValues) { + super(formatError(constraintSetting, duplicateConstraintValues)); + this.duplicateConstraints = ImmutableSet.copyOf(duplicateConstraintValues); + } + + public ImmutableSet<ConstraintValueInfo> duplicateConstraints() { + return duplicateConstraints; + } + + private static String formatError( + ConstraintSettingInfo constraintSetting, + Iterable<ConstraintValueInfo> duplicateConstraints) { + StringBuilder constraintValuesDescription = new StringBuilder(); + for (ConstraintValueInfo constraintValue : duplicateConstraints) { + if (constraintValuesDescription.length() > 0) { + constraintValuesDescription.append(", "); + } + constraintValuesDescription.append(constraintValue.label()); + } + return String.format( + "Duplicate constraint_values for constraint_setting %s: %s", + constraintSetting.label(), constraintValuesDescription.toString()); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java new file mode 100644 index 0000000000..1e5e45f462 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainInfo.java @@ -0,0 +1,103 @@ +// 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.platform; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +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; +import com.google.devtools.build.lib.packages.NativeClassObjectConstructor; +import com.google.devtools.build.lib.packages.SkylarkClassObject; +import com.google.devtools.build.lib.packages.SkylarkProviderIdentifier; +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 java.util.Map; + +/** + * A provider that supplied information about a specific language toolchain, including what platform + * constraints are required for execution and for the target platform. + */ +@SkylarkModule( + name = "ToolchainInfo", + doc = "Provides access to data about a specific toolchain.", + category = SkylarkModuleCategory.PROVIDER +) +@Immutable +public class ToolchainInfo extends SkylarkClassObject { + + /** Name used in Skylark for accessing this provider. */ + public static final String SKYLARK_NAME = "ToolchainInfo"; + + /** Skylark constructor and identifier for this provider. */ + public static final ClassObjectConstructor SKYLARK_CONSTRUCTOR = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + /** Identifier used to retrieve this provider from rules which export it. */ + public static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = + SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + + private final ImmutableList<ConstraintValueInfo> execConstraints; + private final ImmutableList<ConstraintValueInfo> targetConstraints; + + public ToolchainInfo( + Iterable<ConstraintValueInfo> execConstraints, + Iterable<ConstraintValueInfo> targetConstraints, + Map<String, Object> toolchainData, + Location loc) { + this( + ImmutableList.copyOf(execConstraints), + ImmutableList.copyOf(targetConstraints), + toolchainData, + loc); + } + + public ToolchainInfo( + ImmutableList<ConstraintValueInfo> execConstraints, + ImmutableList<ConstraintValueInfo> targetConstraints, + Map<String, Object> toolchainData, + Location loc) { + super( + SKYLARK_CONSTRUCTOR, + ImmutableMap.<String, Object>builder() + .put("exec_compatible_with", execConstraints) + .put("target_compatible_with", targetConstraints) + .putAll(toolchainData) + .build(), + loc); + + this.execConstraints = execConstraints; + this.targetConstraints = targetConstraints; + } + + @SkylarkCallable( + name = "exec_compatible_with", + doc = "The constraints on the execution platforms this toolchain supports.", + structField = true + ) + public ImmutableList<ConstraintValueInfo> execConstraints() { + return execConstraints; + } + + @SkylarkCallable( + name = "target_compatible_with", + doc = "The constraints on the target platforms this toolchain supports.", + structField = true + ) + public ImmutableList<ConstraintValueInfo> targetConstraints() { + return targetConstraints; + } +} |