Skip to content

Commit

Permalink
Use toolchain resolution in rule creation.
Browse files Browse the repository at this point in the history
Part of #2219.

Change-Id: Id4929d5ddcd57b4635af5e513eb9a09f16a78e71
PiperOrigin-RevId: 162634398
  • Loading branch information
katre authored and aehlig committed Jul 21, 2017
1 parent 520bbbc commit 2e56f06
Show file tree
Hide file tree
Showing 11 changed files with 839 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -205,20 +205,34 @@ public static BuildConfiguration getArtifactOwnerConfiguration(SkyFunction.Envir

/**
* Invokes the appropriate constructor to create a {@link ConfiguredTarget} instance.
*
* <p>For use in {@code ConfiguredTargetFunction}.
*
* <p>Returns null if Skyframe deps are missing or upon certain errors.
*/
@Nullable
public final ConfiguredTarget createConfiguredTarget(AnalysisEnvironment analysisEnvironment,
ArtifactFactory artifactFactory, Target target, BuildConfiguration config,
public final ConfiguredTarget createConfiguredTarget(
AnalysisEnvironment analysisEnvironment,
ArtifactFactory artifactFactory,
Target target,
BuildConfiguration config,
BuildConfiguration hostConfig,
OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap,
ImmutableMap<Label, ConfigMatchingProvider> configConditions)
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
@Nullable ToolchainContext toolchainContext)
throws InterruptedException {
if (target instanceof Rule) {
return createRule(analysisEnvironment, (Rule) target, config, hostConfig,
prerequisiteMap, configConditions);
Preconditions.checkArgument(
toolchainContext != null,
"ToolchainContext should never be null when creating a ConfiguredTarget for a Rule");
return createRule(
analysisEnvironment,
(Rule) target,
config,
hostConfig,
prerequisiteMap,
configConditions,
toolchainContext);
}

// Visibility, like all package groups, doesn't have a configuration
Expand Down Expand Up @@ -271,10 +285,18 @@ public final ConfiguredTarget createConfiguredTarget(AnalysisEnvironment analysi
*/
@Nullable
private ConfiguredTarget createRule(
AnalysisEnvironment env, Rule rule, BuildConfiguration configuration,
AnalysisEnvironment env,
Rule rule,
BuildConfiguration configuration,
BuildConfiguration hostConfiguration,
OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap,
ImmutableMap<Label, ConfigMatchingProvider> configConditions) throws InterruptedException {
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
ToolchainContext toolchainContext)
throws InterruptedException {

// Load the requested toolchains into the ToolchainContext.
toolchainContext.resolveToolchains(prerequisiteMap);

// Visibility computation and checking is done for every rule.
RuleContext ruleContext =
new RuleContext.Builder(
Expand All @@ -289,9 +311,7 @@ private ConfiguredTarget createRule(
.setPrerequisites(prerequisiteMap)
.setConfigConditions(configConditions)
.setUniversalFragment(ruleClassProvider.getUniversalFragment())
// TODO(katre): Populate the actual selected toolchains.
.setToolchainContext(
new ToolchainContext(rule.getRuleClassObject().getRequiredToolchains(), null))
.setToolchainContext(toolchainContext)
.build();
if (ruleContext.hasErrors()) {
return null;
Expand Down Expand Up @@ -365,9 +385,10 @@ public AspectDescriptor apply(Aspect aspect) {
return aspect.getDescriptor();
}
};

/**
* Constructs an {@link ConfiguredAspect}. Returns null if an error occurs; in that case,
* {@code aspectFactory} should call one of the error reporting methods of {@link RuleContext}.
* Constructs an {@link ConfiguredAspect}. Returns null if an error occurs; in that case, {@code
* aspectFactory} should call one of the error reporting methods of {@link RuleContext}.
*/
public ConfiguredAspect createAspect(
AnalysisEnvironment env,
Expand All @@ -377,9 +398,14 @@ public ConfiguredAspect createAspect(
Aspect aspect,
OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
ToolchainContext toolchainContext,
BuildConfiguration aspectConfiguration,
BuildConfiguration hostConfiguration)
throws InterruptedException {

// Load the requested toolchains into the ToolchainContext.
toolchainContext.resolveToolchains(prerequisiteMap);

RuleContext.Builder builder = new RuleContext.Builder(
env,
associatedTarget.getTarget().getAssociatedRule(),
Expand All @@ -397,9 +423,7 @@ public ConfiguredAspect createAspect(
.setAspectAttributes(aspect.getDefinition().getAttributes())
.setConfigConditions(configConditions)
.setUniversalFragment(ruleClassProvider.getUniversalFragment())
// TODO(katre): Populate the actual selected toolchains.
.setToolchainContext(
new ToolchainContext(aspect.getDefinition().getRequiredToolchains(), null))
.setToolchainContext(toolchainContext)
.build();
if (ruleContext.hasErrors()) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.config.PatchTransition;
import com.google.devtools.build.lib.cmdline.Label;
Expand Down Expand Up @@ -93,12 +94,16 @@ public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(
@Nullable Aspect aspect,
ImmutableMap<Label, ConfigMatchingProvider> configConditions)
throws EvalException, InvalidConfigurationException, InterruptedException,
InconsistentAspectOrderException {
InconsistentAspectOrderException {
NestedSetBuilder<Label> rootCauses = NestedSetBuilder.<Label>stableOrder();
OrderedSetMultimap<Attribute, Dependency> outgoingEdges = dependentNodeMap(
node, hostConfig,
aspect != null ? ImmutableList.of(aspect) : ImmutableList.<Aspect>of(),
configConditions, rootCauses);
OrderedSetMultimap<Attribute, Dependency> outgoingEdges =
dependentNodeMap(
node,
hostConfig,
aspect != null ? ImmutableList.of(aspect) : ImmutableList.<Aspect>of(),
configConditions,
/*toolchainContext=*/ null,
rootCauses);
if (!rootCauses.isEmpty()) {
throw new IllegalStateException(rootCauses.build().iterator().next().toString());
}
Expand All @@ -113,14 +118,13 @@ public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(
* <p>If {@code aspects} is empty, returns the dependent nodes of the configured target node
* representing the given target and configuration.
*
* Otherwise {@code aspects} represents an aspect path. The function returns dependent nodes
* of the entire path applied to given target and configuration. These are the depenent nodes
* of the last aspect in the path.
* <p>Otherwise {@code aspects} represents an aspect path. The function returns dependent nodes of
* the entire path applied to given target and configuration. These are the depenent nodes of the
* last aspect in the path.
*
* <p>This also implements the first step of applying
* configuration transitions, namely, split transitions. This needs to be done before the labels
* are resolved because late bound attributes depend on the configuration. A good example for this
* is @{code :cc_toolchain}.
* <p>This also implements the first step of applying configuration transitions, namely, split
* transitions. This needs to be done before the labels are resolved because late bound attributes
* depend on the configuration. A good example for this is @{code :cc_toolchain}.
*
* <p>The long-term goal is that most configuration transitions be applied here. However, in order
* to do that, we first have to eliminate transitions that depend on the rule class of the
Expand All @@ -131,17 +135,19 @@ public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(
* This is needed to support {@link LateBoundDefault#useHostConfiguration()}.
* @param aspects the aspects applied to this target (if any)
* @param configConditions resolver for config_setting labels
* @param rootCauses collector for dep labels that can't be (loading phase) loaded
* @return a mapping of each attribute in this rule or aspects to its dependent nodes
* @param toolchainContext context information for required toolchains
* @param rootCauses collector for dep labels that can't be (loading phase) loaded @return a
* mapping of each attribute in this rule or aspects to its dependent nodes
*/
public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(
TargetAndConfiguration node,
BuildConfiguration hostConfig,
Iterable<Aspect> aspects,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
@Nullable ToolchainContext toolchainContext,
NestedSetBuilder<Label> rootCauses)
throws EvalException, InvalidConfigurationException, InterruptedException,
InconsistentAspectOrderException {
InconsistentAspectOrderException {
Target target = node.getTarget();
BuildConfiguration config = node.getConfiguration();
OrderedSetMultimap<Attribute, Dependency> outgoingEdges = OrderedSetMultimap.create();
Expand All @@ -155,7 +161,8 @@ public final OrderedSetMultimap<Attribute, Dependency> dependentNodeMap(
} else if (target instanceof EnvironmentGroup) {
visitTargetVisibility(node, rootCauses, outgoingEdges.get(null));
} else if (target instanceof Rule) {
visitRule(node, hostConfig, aspects, configConditions, rootCauses, outgoingEdges);
visitRule(
node, hostConfig, aspects, configConditions, toolchainContext, rootCauses, outgoingEdges);
} else if (target instanceof PackageGroup) {
visitPackageGroup(node, (PackageGroup) target, rootCauses, outgoingEdges.get(null));
} else {
Expand All @@ -170,10 +177,11 @@ private void visitRule(
BuildConfiguration hostConfig,
Iterable<Aspect> aspects,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
@Nullable ToolchainContext toolchainContext,
NestedSetBuilder<Label> rootCauses,
OrderedSetMultimap<Attribute, Dependency> outgoingEdges)
throws EvalException, InvalidConfigurationException, InconsistentAspectOrderException,
InterruptedException{
InterruptedException {
Preconditions.checkArgument(node.getTarget() instanceof Rule);
BuildConfiguration ruleConfig = Preconditions.checkNotNull(node.getConfiguration());
Rule rule = (Rule) node.getTarget();
Expand All @@ -186,6 +194,12 @@ private void visitRule(
visitTargetVisibility(node, rootCauses, outgoingEdges.get(null));
resolveEarlyBoundAttributes(depResolver);
resolveLateBoundAttributes(depResolver, ruleConfig, hostConfig);

if (toolchainContext != null) {
Attribute toolchainsAttribute =
attributeMap.getAttributeDefinition(PlatformSemantics.TOOLCHAINS_ATTR);
resolveToolchainDependencies(outgoingEdges.get(toolchainsAttribute), toolchainContext);
}
}

/**
Expand Down Expand Up @@ -396,6 +410,16 @@ private void resolveLateBoundAttributes(
}
}

private void resolveToolchainDependencies(
Set<Dependency> dependencies, ToolchainContext toolchainContext) {
for (Label label : toolchainContext.getResolvedToolchainLabels()) {
Dependency dependency =
Dependency.withTransitionAndAspects(
label, HostTransition.INSTANCE, AspectCollection.EMPTY);
dependencies.add(dependency);
}
}

/**
* Returns the BuildOptions if the rule's attribute triggers a split in this configuration, or
* the empty collection if the attribute does not trigger a split transition or if the split
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
Expand All @@ -33,22 +32,7 @@ public class PlatformSemantics {

public static final String TARGET_PLATFORMS_ATTR = ":target_platforms";
public static final String EXECUTION_PLATFORM_ATTR = ":execution_platform";

public Iterable<PlatformInfo> getTargetPlatforms(RuleContext ruleContext) {
Iterable<PlatformInfo> platform =
PlatformProviderUtils.platforms(
ruleContext.getPrerequisites(
TARGET_PLATFORMS_ATTR, RuleConfiguredTarget.Mode.DONT_CHECK));
return platform;
}

public PlatformInfo getExecutionPlatform(RuleContext ruleContext) {
PlatformInfo platform =
PlatformProviderUtils.platform(
ruleContext.getPrerequisite(
EXECUTION_PLATFORM_ATTR, RuleConfiguredTarget.Mode.DONT_CHECK));
return platform;
}
public static final String TOOLCHAINS_ATTR = "$toolchains";

/** Implementation for the :target_platform attribute. */
public static final Attribute.LateBoundLabelList<BuildConfiguration> TARGET_PLATFORM =
Expand All @@ -62,6 +46,7 @@ public List<Label> resolve(
return configuration.getFragment(PlatformConfiguration.class).getTargetPlatforms();
}
};

/** Implementation for the :execution_platform attribute. */
public static final Attribute.LateBoundLabel<BuildConfiguration> EXECUTION_PLATFORM =
new Attribute.LateBoundLabel<BuildConfiguration>(PlatformConfiguration.class) {
Expand All @@ -83,6 +68,10 @@ public static RuleClass.Builder platformAttributes(RuleClass.Builder builder) {
.add(
attr(EXECUTION_PLATFORM_ATTR, LABEL)
.value(EXECUTION_PLATFORM)
.nonconfigurable("Used in toolchain resolution"));
.nonconfigurable("Used in toolchain resolution"))
.add(
attr(TOOLCHAINS_ATTR, LABEL_LIST)
.nonconfigurable("Used in toolchain resolution")
.value(ImmutableList.of()));
}
}
Loading

0 comments on commit 2e56f06

Please sign in to comment.