diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD b/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD index 4ae0f8cfcababf..2d4ed50ac7e7d5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD +++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/BUILD @@ -26,11 +26,14 @@ java_library( "//src/main/java/com/google/devtools/build/lib/analysis:file_provider", "//src/main/java/com/google/devtools/build/lib/analysis:make_variable_supplier", "//src/main/java/com/google/devtools/build/lib/analysis:rule_definition_environment", + "//src/main/java/com/google/devtools/build/lib/analysis:template_variable_info", "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_collection", + "//src/main/java/com/google/devtools/build/lib/analysis/platform", "//src/main/java/com/google/devtools/build/lib/analysis/stringtemplate", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/collect/nestedset", "//src/main/java/com/google/devtools/build/lib/packages", + "//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_and_data", "//src/main/java/com/google/devtools/build/lib/util", "//src/main/java/com/google/devtools/build/lib/util:filetype", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java index 9bb899f4a05232..9ed01ef86b6969 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java +++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBase.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.genrule; +import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.ImmutableMap.toImmutableMap; import com.google.common.collect.ImmutableList; @@ -47,6 +48,7 @@ import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.packages.TriState; import com.google.devtools.build.lib.packages.Type; +import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; import com.google.devtools.build.lib.util.FileTypeSet; import com.google.devtools.build.lib.util.OnDemandString; import com.google.devtools.build.lib.util.Pair; @@ -90,12 +92,17 @@ public final ConfiguredTarget create(RuleContext ruleContext) labelMap.values().forEach(resolvedSrcsBuilder::addTransitive); NestedSet resolvedSrcs = resolvedSrcsBuilder.build(); + ImmutableList toolchainPrerequisites = + ruleContext.getToolchainContext().prerequisiteTargets().stream() + .map(ConfiguredTargetAndData::getConfiguredTarget) + .collect(toImmutableList()); // The CommandHelper class makes an explicit copy of this in the constructor, so flattening // here should be benign. CommandHelper commandHelper = CommandHelper.builder(ruleContext) .addToolDependencies("tools") .addToolDependencies("toolchains") + .addToolDependencies(toolchainPrerequisites) .addLabelMap( labelMap.entrySet().stream() .collect(toImmutableMap(Map.Entry::getKey, e -> e.getValue().toList()))) diff --git a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java index 1da01f19d2115c..ebf77bf84dd76b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/genrule/GenRuleBaseRule.java @@ -20,10 +20,13 @@ import static com.google.devtools.build.lib.packages.Type.BOOLEAN; import static com.google.devtools.build.lib.packages.Type.STRING; +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.TemplateVariableInfo; import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory; +import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.BuildType; @@ -302,6 +305,32 @@ public Object getDefault(AttributeMap rule) { // This is a misfeature, so don't document it. We would like to get rid of it, but that // would require a cleanup of existing rules. .add(attr("heuristic_label_expansion", BOOLEAN).value(false)) + + /* +

+ The set of targets whose Make variables this genrule + is allowed to access, or the toolchain_type + targets that this genrule will access. +

+ +

+ Toolchains accessed via toolchain_type must also provide a + TemplateVariableInfo provider, which the target can use to access toolchain + details. +

+ */ + // Override `toolchains` to allow make variables and toolchain types. Toolchain types are + // handled specially in ToolchainContextUtil. + .override( + attr("toolchains", LABEL_LIST) + .allowedFileTypes(FileTypeSet.NO_FILE) + // Accept TemplateVariableInfo and/or ToolchainTypeInfo. + .mandatoryProvidersList( + ImmutableList.of( + ImmutableList.of(TemplateVariableInfo.PROVIDER.id()), + ImmutableList.of(ToolchainTypeInfo.PROVIDER.id()))) + .dontCheckConstraints() + .nonconfigurable("Don't allow dynamic toolchain types")) .removeAttribute("data") .removeAttribute("deps") .build(); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainContextUtil.java b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainContextUtil.java index 8ae7594a675b57..2ed4ed00c65008 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainContextUtil.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/toolchains/ToolchainContextUtil.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.skyframe.config.BuildConfigurationKey; +import java.util.List; import javax.annotation.Nullable; /** Utility methods for toolchain context creation. */ @@ -49,11 +50,18 @@ public static UnloadedToolchainContextsInputs getUnloadedToolchainContextsInputs .getAutoExecGroupsMode() .isEnabled(RawAttributeMapper.of(rule), coreOptions.useAutoExecGroups); var defaultExecConstraintLabels = getExecutionPlatformConstraints(rule, platformConfig); + ImmutableSet toolchainTypes = ruleClass.getToolchainTypes(); + + if (!ruleClass.isStarlark() && ruleClass.getName().equals("genrule")) { + // Override the toolchain types based on the target-level "toolchains" attribute. + toolchainTypes = updateToolchainTypesFromAttribute(rule, toolchainTypes); + } + var processedExecGroups = ExecGroupCollection.process( ruleClass.getExecGroups(), defaultExecConstraintLabels, - ruleClass.getToolchainTypes(), + toolchainTypes, useAutoExecGroups); if (platformConfig == null || !rule.useToolchainResolution()) { @@ -68,10 +76,35 @@ public static UnloadedToolchainContextsInputs getUnloadedToolchainContextsInputs defaultExecConstraintLabels, /* debugTarget= */ platformConfig.debugToolchainResolution(rule.getLabel()), /* useAutoExecGroups= */ useAutoExecGroups, - ruleClass.getToolchainTypes(), + toolchainTypes, parentExecutionPlatformLabel)); } + private static ImmutableSet updateToolchainTypesFromAttribute( + Rule rule, ImmutableSet toolchainTypes) { + NonconfigurableAttributeMapper attributes = NonconfigurableAttributeMapper.of(rule); + List