From edbeafe6d58c6525b2392301a3ed208783228b8e Mon Sep 17 00:00:00 2001 From: John Cater Date: Thu, 6 Apr 2017 19:24:53 +0000 Subject: Adding toolchain provider and function to Skylark. Change-Id: Ied06efd4bc68f604975b1e8e3fc70817a577d563 PiperOrigin-RevId: 152412538 --- .../build/lib/rules/platform/PlatformCommon.java | 82 +++++++++++++ .../build/lib/rules/platform/ToolchainInfo.java | 131 +++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainInfo.java (limited to 'src/main/java/com/google/devtools/build/lib/rules/platform') diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java index ff4b0c3dfe..147d872296 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformCommon.java @@ -14,9 +14,20 @@ package com.google.devtools.build.lib.rules.platform; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.events.Location; import com.google.devtools.build.lib.packages.ClassObjectConstructor; +import com.google.devtools.build.lib.skylarkinterface.Param; import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature; +import com.google.devtools.build.lib.syntax.BuiltinFunction; +import com.google.devtools.build.lib.syntax.EvalException; +import com.google.devtools.build.lib.syntax.SkylarkDict; +import com.google.devtools.build.lib.syntax.SkylarkList; +import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor; +import com.google.devtools.build.lib.syntax.Type.ConversionException; /** Skylark namespace used to interact with Blaze's platform APIs. */ @SkylarkModule( @@ -51,4 +62,75 @@ public class PlatformCommon { public ClassObjectConstructor getConstraintValueInfoConstructor() { return ConstraintValueInfo.SKYLARK_CONSTRUCTOR; } + + @SkylarkCallable( + name = ToolchainInfo.SKYLARK_NAME, + doc = "The key used to retrieve the provider containing toolchain data.", + structField = true + ) + public ClassObjectConstructor getToolchainInfoConstructor() { + return ToolchainInfo.SKYLARK_CONSTRUCTOR; + } + + @SkylarkSignature( + name = "toolchain", + doc = + "(Experimental) " + + "Returns a toolchain provider that can be configured to provide rule implementations " + + "access to needed configuration.", + objectType = PlatformCommon.class, + returnType = ToolchainInfo.class, + parameters = { + @Param(name = "self", type = PlatformCommon.class, doc = "the platform_rules instance"), + @Param( + name = "exec_compatible_with", + type = SkylarkList.class, + defaultValue = "[]", + named = true, + positional = false, + doc = "Constraints the platform must fulfill to execute this toolchain." + ), + @Param( + name = "target_compatible_with", + type = SkylarkList.class, + defaultValue = "[]", + named = true, + positional = false, + doc = "Constraints fulfilled by the target platform for this toolchain." + ), + }, + extraKeywords = + @Param( + name = "toolchainData", + doc = "Extra information stored for the consumer of the toolchain." + ), + useLocation = true + ) + private static final BuiltinFunction createToolchain = + new BuiltinFunction("toolchain") { + @SuppressWarnings("unchecked") + public ToolchainInfo invoke( + PlatformCommon self, + SkylarkList execCompatibleWith, + SkylarkList targetCompatibleWith, + SkylarkDict skylarkToolchainData, + Location loc) + throws ConversionException, EvalException { + + Iterable execConstraints = + ConstraintValueInfo.fromTargets(execCompatibleWith); + Iterable targetConstraints = + ConstraintValueInfo.fromTargets(targetCompatibleWith); + ImmutableMap toolchainData = + ImmutableMap.copyOf( + SkylarkDict.castSkylarkDictOrNoneToDict( + skylarkToolchainData, String.class, Object.class, "toolchainData")); + + return new ToolchainInfo(execConstraints, targetConstraints, toolchainData, loc); + } + }; + + static { + SkylarkSignatureProcessor.configureSkylarkFunctions(PlatformCommon.class); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainInfo.java new file mode 100644 index 0000000000..320ee5e9df --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainInfo.java @@ -0,0 +1,131 @@ +// 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.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +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 com.google.devtools.build.lib.util.Preconditions; +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 implements TransitiveInfoProvider { + + /** Name used in Skylark for accessing this provider. */ + static final String SKYLARK_NAME = "ToolchainInfo"; + + /** Skylark constructor and identifier for this provider. */ + static final ClassObjectConstructor SKYLARK_CONSTRUCTOR = + new NativeClassObjectConstructor(SKYLARK_NAME) {}; + + /** Identifier used to retrieve this provider from rules which export it. */ + private static final SkylarkProviderIdentifier SKYLARK_IDENTIFIER = + SkylarkProviderIdentifier.forKey(SKYLARK_CONSTRUCTOR.getKey()); + + private final ImmutableList execConstraints; + private final ImmutableList targetConstraints; + + public ToolchainInfo( + Iterable execConstraints, + Iterable targetConstraints, + Map toolchainData, + Location loc) { + this( + ImmutableList.copyOf(execConstraints), + ImmutableList.copyOf(targetConstraints), + toolchainData, + loc); + } + + public ToolchainInfo( + ImmutableList execConstraints, + ImmutableList targetConstraints, + Map toolchainData, + Location loc) { + super( + SKYLARK_CONSTRUCTOR, + ImmutableMap.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 execConstraints() { + return execConstraints; + } + + @SkylarkCallable( + name = "target_compatible_with", + doc = "The constraints on the target platforms this toolchain supports.", + structField = true + ) + public ImmutableList targetConstraints() { + return targetConstraints; + } + + /** Retrieves and casts the provider from the given target. */ + public static ToolchainInfo fromTarget(TransitiveInfoCollection target) { + Object provider = target.get(SKYLARK_IDENTIFIER); + if (provider == null) { + return null; + } + Preconditions.checkState(provider instanceof ToolchainInfo); + return (ToolchainInfo) provider; + } + + /** Retrieves and casts the providers from the given targets. */ + public static Iterable fromTargets( + Iterable targets) { + return Iterables.transform( + targets, + new Function() { + @Override + public ToolchainInfo apply(TransitiveInfoCollection target) { + return fromTarget(target); + } + }); + } +} -- cgit v1.2.3