diff options
author | 2017-07-07 13:28:52 -0400 | |
---|---|---|
committer | 2017-07-07 13:38:08 -0400 | |
commit | c6bd5166d1c558fb8f619b53eb4c56fa7cee8b93 (patch) | |
tree | 0536f626877de940711353e0d70caad173d6571c /src/main/java/com/google | |
parent | 632d96193d51194e6f7bb0d2d9058faf8f2831db (diff) |
Add toolchain() rule for declaring toolchains with type and constraints.
Part of #2219.
Change-Id: Ia0effac6e6c362c04c6501b21dde89e9e5b154a4
PiperOrigin-RevId: 161216492
Diffstat (limited to 'src/main/java/com/google')
5 files changed, 224 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 index e5c4231f14..b8cffdff96 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/platform/BUILD +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/BUILD @@ -18,6 +18,8 @@ java_library( deps = [ "//src/main/java/com/google/devtools/build/lib:packages", "//src/main/java/com/google/devtools/build/lib:skylarkinterface", + "//src/main/java/com/google/devtools/build/lib:transitive-info-provider", + "//third_party:auto_value", "//third_party:guava", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/DeclaredToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/DeclaredToolchainInfo.java new file mode 100644 index 0000000000..30931a4211 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/DeclaredToolchainInfo.java @@ -0,0 +1,57 @@ +// 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.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.cmdline.Label; + +/** + * Provider for a toolchain declaration, which assosiates a toolchain type, the execution and target + * constraints, and the actual toolchain label. The toolchain is then available for use but will be + * lazily resolved only when it is actually needed for toolchain-aware rules. Toolchain definitions + * are exposed to Skylark and Bazel via {@link ToolchainInfo} providers. + */ +@AutoValue +public abstract class DeclaredToolchainInfo implements TransitiveInfoProvider { + + /** + * The type of the toolchain being declared. This will be a label of a toolchain_type() target. + */ + public abstract Label toolchainType(); + + /** The constraints describing the execution environment. */ + public abstract ImmutableList<ConstraintValueInfo> execConstraints(); + + /** The constraints describing the target environment. */ + public abstract ImmutableList<ConstraintValueInfo> targetConstraints(); + + /** The label of the toolchain to resolve for use in toolchain-aware rules. */ + public abstract Label toolchainLabel(); + + /** Returns a new {@link DeclaredToolchainInfo} with the given data. */ + public static DeclaredToolchainInfo create( + Label toolchainType, + Iterable<ConstraintValueInfo> execConstraints, + Iterable<ConstraintValueInfo> targetConstraints, + Label toolchainLabel) { + return new AutoValue_DeclaredToolchainInfo( + toolchainType, + ImmutableList.copyOf(execConstraints), + ImmutableList.copyOf(targetConstraints), + toolchainLabel); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 5dac663dce..54ff50615c 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -155,6 +155,7 @@ import com.google.devtools.build.lib.rules.platform.ConstraintSettingRule; import com.google.devtools.build.lib.rules.platform.ConstraintValueRule; import com.google.devtools.build.lib.rules.platform.PlatformCommon; import com.google.devtools.build.lib.rules.platform.PlatformRule; +import com.google.devtools.build.lib.rules.platform.ToolchainRule; import com.google.devtools.build.lib.rules.proto.BazelProtoLibraryRule; import com.google.devtools.build.lib.rules.proto.ProtoConfiguration; import com.google.devtools.build.lib.rules.proto.ProtoLangToolchainRule; @@ -261,6 +262,8 @@ public class BazelRuleClassProvider { builder.addRuleDefinition(new ConstraintValueRule()); builder.addRuleDefinition(new PlatformRule()); + builder.addRuleDefinition(new ToolchainRule()); + builder.addSkylarkAccessibleTopLevels("platform_common", new PlatformCommon()); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/Toolchain.java b/src/main/java/com/google/devtools/build/lib/rules/platform/Toolchain.java new file mode 100644 index 0000000000..a7512944cc --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/platform/Toolchain.java @@ -0,0 +1,62 @@ +// 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.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.analysis.platform.ConstraintValueInfo; +import com.google.devtools.build.lib.analysis.platform.DeclaredToolchainInfo; +import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; + +/** Defines a toolchain that can be used by rules. */ +public class Toolchain implements RuleConfiguredTargetFactory { + + @Override + public ConfiguredTarget create(RuleContext ruleContext) + throws InterruptedException, RuleErrorException { + + Label toolchainType = + ruleContext.attributes().get(ToolchainRule.TOOLCHAIN_TYPE_ATTR, BuildType.NODEP_LABEL); + Iterable<ConstraintValueInfo> execConstraints = + PlatformProviderUtils.constraintValues( + ruleContext.getPrerequisites(ToolchainRule.EXEC_COMPATIBLE_WITH_ATTR, Mode.DONT_CHECK)); + Iterable<ConstraintValueInfo> targetConstraints = + PlatformProviderUtils.constraintValues( + ruleContext.getPrerequisites( + ToolchainRule.TARGET_COMPATIBLE_WITH_ATTR, Mode.DONT_CHECK)); + // TODO(katre): warn if null. + Label toolchainLabel = + ruleContext.attributes().get(ToolchainRule.TOOLCHAIN_ATTR, BuildType.NODEP_LABEL); + + DeclaredToolchainInfo registeredToolchain = + DeclaredToolchainInfo.create( + toolchainType, execConstraints, targetConstraints, toolchainLabel); + + return new RuleConfiguredTargetBuilder(ruleContext) + .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY) + .addProvider(FileProvider.class, FileProvider.EMPTY) + .addProvider(FilesToRunProvider.class, FilesToRunProvider.EMPTY) + .addProvider(registeredToolchain) + .build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainRule.java new file mode 100644 index 0000000000..8065d35909 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainRule.java @@ -0,0 +1,100 @@ +// 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.platform.ConstraintValueInfo; +import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.syntax.Type; + +/** Rule definition for {@link Toolchain}. */ +public class ToolchainRule implements RuleDefinition { + public static final String RULE_NAME = "toolchain"; + public static final String TOOLCHAIN_TYPE_ATTR = "toolchain_type"; + public static final String EXEC_COMPATIBLE_WITH_ATTR = "exec_compatible_with"; + public static final String TARGET_COMPATIBLE_WITH_ATTR = "target_compatible_with"; + public static final String TOOLCHAIN_ATTR = "toolchain"; + + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { + 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")) + .removeAttribute("deps") + .removeAttribute("data") + .exemptFromConstraintChecking("this rule *defines* a constraint") + + /* <!-- #BLAZE_RULE(toolchain).ATTRIBUTE(toolchain_type) --> + The type of the toolchain, which should be the label of a toolchain_type() target. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add( + attr(TOOLCHAIN_TYPE_ATTR, BuildType.NODEP_LABEL) + // .allowedFileTypes() + .mandatory() + .nonconfigurable("part of toolchain configuration")) + /* <!-- #BLAZE_RULE(toolchain).ATTRIBUTE(exec_compatible_with) --> + The constraints, as defined by constraint_value() and constraint_setting(), that are + required on the execution platform for this toolchain to be selected. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add( + attr(EXEC_COMPATIBLE_WITH_ATTR, BuildType.LABEL_LIST) + .mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER)) + .allowedFileTypes() + .nonconfigurable("part of toolchain configuration")) + /* <!-- #BLAZE_RULE(toolchain).ATTRIBUTE(target_compatible_with) --> + The constraints, as defined by constraint_value() and constraint_setting(), that are + required on the target platform for this toolchain to be selected. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + .add( + attr(TARGET_COMPATIBLE_WITH_ATTR, BuildType.LABEL_LIST) + .mandatoryProviders(ImmutableList.of(ConstraintValueInfo.SKYLARK_IDENTIFIER)) + .allowedFileTypes() + .nonconfigurable("part of toolchain configuration")) + /* <!-- #BLAZE_RULE(toolchain).ATTRIBUTE(toolchain) --> + The label of the actual toolchain data to be used when this toolchain is selected. + <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ + // This needs to not introduce a dependency so that we can load the toolchain only if it is + // needed. + .add( + attr(TOOLCHAIN_ATTR, BuildType.NODEP_LABEL) + .mandatory() + .nonconfigurable("part of toolchain configuration")) + .build(); + } + + @Override + public RuleDefinition.Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name(RULE_NAME) + .ancestors(BaseRuleClasses.RuleBase.class) + .factoryClass(Toolchain.class) + .build(); + } +} +/*<!-- #BLAZE_RULE (NAME = toolchain, TYPE = OTHER, FAMILY = Platform)[GENERIC_RULE] --> + +<p>This rule declares a specific toolchain's type and constraints so that it can be selected +during toolchain resolution.</p> + +<!-- #END_BLAZE_RULE -->*/ |