Update AspectFunction to perform toolchain resolution for multiple exec groups.
RELNOTES: Aspects can now define and use exec groups using the same API as rules.
PiperOrigin-RevId: 453177050
Change-Id: Ia84ff906ede72cadfb6b6acf9deac7c55280bbe5
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
index 326b851..bba79c9 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java
@@ -17,6 +17,7 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
@@ -35,6 +36,7 @@
import com.google.devtools.build.lib.analysis.DependencyKey;
import com.google.devtools.build.lib.analysis.DependencyKind;
import com.google.devtools.build.lib.analysis.DuplicateException;
+import com.google.devtools.build.lib.analysis.ExecGroupCollection;
import com.google.devtools.build.lib.analysis.ExecGroupCollection.InvalidExecGroupException;
import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException;
import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
@@ -78,6 +80,7 @@
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ComputeDependenciesState;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ComputedToolchainContexts;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import com.google.devtools.build.skyframe.SkyFunction;
@@ -88,7 +91,9 @@
import com.google.devtools.build.skyframe.SkyframeLookupResult;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.StarlarkSemantics;
@@ -271,19 +276,28 @@
TargetAndConfiguration originalTargetAndConfiguration =
new TargetAndConfiguration(target, configuration);
try {
- UnloadedToolchainContext unloadedToolchainContext =
- getUnloadedToolchainContext(env, key, aspect, configuration);
+ ConfiguredTargetFunction.ComputedToolchainContexts computedToolchainContexts =
+ getUnloadedToolchainContexts(env, key, aspect, configuration);
if (env.valuesMissing()) {
return null;
}
+ ToolchainCollection<UnloadedToolchainContext> unloadedToolchainContexts = null;
+ ExecGroupCollection.Builder execGroupCollectionBuilder = null;
+ if (computedToolchainContexts != null) {
+ unloadedToolchainContexts = computedToolchainContexts.toolchainCollection;
+ execGroupCollectionBuilder = computedToolchainContexts.execGroupCollectionBuilder;
+ }
+
// Get the configuration targets that trigger this rule's configurable attributes.
ConfigConditions configConditions =
ConfiguredTargetFunction.getConfigConditions(
env,
originalTargetAndConfiguration,
state.transitivePackagesForPackageRootResolution,
- unloadedToolchainContext == null ? null : unloadedToolchainContext.targetPlatform(),
+ unloadedToolchainContexts == null
+ ? null
+ : unloadedToolchainContexts.getTargetPlatform(),
state.transitiveRootCauses);
if (configConditions == null) {
// Those targets haven't yet been resolved.
@@ -302,11 +316,9 @@
originalTargetAndConfiguration,
topologicalAspectPath,
configConditions.asProviders(),
- unloadedToolchainContext == null
+ unloadedToolchainContexts == null
? null
- : ToolchainCollection.builder()
- .addDefaultContext(unloadedToolchainContext)
- .build(),
+ : unloadedToolchainContexts.asToolchainContexts(),
ruleClassProvider,
buildViewProvider.getSkyframeBuildView().getHostConfiguration());
} catch (ConfiguredValueCreationException e) {
@@ -326,17 +338,23 @@
}
// Load the requested toolchains into the ToolchainContext, now that we have dependencies.
- ResolvedToolchainContext toolchainContext = null;
- if (unloadedToolchainContext != null) {
+ ToolchainCollection<ResolvedToolchainContext> toolchainContexts = null;
+ if (unloadedToolchainContexts != null) {
String targetDescription =
String.format(
"aspect %s applied to %s", aspect.getDescriptor().getDescription(), target);
- toolchainContext =
- ResolvedToolchainContext.load(
- unloadedToolchainContext,
- targetDescription,
- // TODO(161222568): Support exec groups on aspects.
- depValueMap.get(DependencyKind.defaultExecGroupToolchain()));
+ ToolchainCollection.Builder<ResolvedToolchainContext> contextsBuilder =
+ ToolchainCollection.builder();
+ for (Map.Entry<String, UnloadedToolchainContext> unloadedContext :
+ unloadedToolchainContexts.getContextMap().entrySet()) {
+ Set<ConfiguredTargetAndData> toolchainDependencies =
+ depValueMap.get(DependencyKind.forExecGroup(unloadedContext.getKey()));
+ contextsBuilder.addContext(
+ unloadedContext.getKey(),
+ ResolvedToolchainContext.load(
+ unloadedContext.getValue(), targetDescription, toolchainDependencies));
+ }
+ toolchainContexts = contextsBuilder.build();
}
return createAspect(
@@ -349,7 +367,8 @@
associatedTarget, target, configuration, /*transitionKeys=*/ null),
configuration,
configConditions,
- toolchainContext,
+ toolchainContexts,
+ execGroupCollectionBuilder,
depValueMap,
state.transitivePackagesForPackageRootResolution);
} catch (DependencyEvaluationException e) {
@@ -537,36 +556,34 @@
}
@Nullable
- private static UnloadedToolchainContext getUnloadedToolchainContext(
+ private static ComputedToolchainContexts getUnloadedToolchainContexts(
Environment env,
AspectKey key,
Aspect aspect,
@Nullable BuildConfigurationValue configuration)
throws InterruptedException, AspectCreationException {
- // Determine what toolchains are needed by this target.
- UnloadedToolchainContext unloadedToolchainContext = null;
- if (configuration != null) {
+ if (configuration == null) {
// Configuration can be null in the case of aspects applied to input files. In this case,
// there are no chances of toolchains being used, so skip it.
- try {
- unloadedToolchainContext =
- (UnloadedToolchainContext)
- env.getValueOrThrow(
- ToolchainContextKey.key()
- .configurationKey(configuration.getKey())
- .toolchainTypes(aspect.getDefinition().getToolchainTypes())
- .build(),
- ToolchainException.class);
- } catch (ToolchainException e) {
- // TODO(katre): better error handling
- throw new AspectCreationException(
- e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode()));
- }
- }
- if (env.valuesMissing()) {
return null;
}
- return unloadedToolchainContext;
+ // Determine what toolchains are needed by this target.
+ try {
+ return ConfiguredTargetFunction.computeUnloadedToolchainContexts(
+ env,
+ key.getLabel(),
+ true,
+ Predicates.alwaysFalse(),
+ configuration.getKey(),
+ aspect.getDefinition().getToolchainTypes(),
+ aspect.getDefinition().execCompatibleWith(),
+ aspect.getDefinition().execGroups(),
+ null);
+ } catch (ToolchainException e) {
+ // TODO(katre): better error handling
+ throw new AspectCreationException(
+ e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode()));
+ }
}
/**
@@ -613,12 +630,15 @@
// Compute the Dependency from originalTarget to aliasedLabel
Dependency dep;
try {
- UnloadedToolchainContext unloadedToolchainContext =
- getUnloadedToolchainContext(env, originalKey, aspect, originalTarget.getConfiguration());
+ ConfiguredTargetFunction.ComputedToolchainContexts computedToolchainContexts =
+ getUnloadedToolchainContexts(env, originalKey, aspect, originalTarget.getConfiguration());
if (env.valuesMissing()) {
return null;
}
+ ToolchainCollection<UnloadedToolchainContext> unloadedToolchainContexts =
+ computedToolchainContexts.toolchainCollection;
+
// See comment in compute() above for why we pair target with aspectConfiguration here
TargetAndConfiguration originalTargetAndAspectConfiguration =
new TargetAndConfiguration(originalTarget.getTarget(), aspectConfiguration);
@@ -629,7 +649,9 @@
env,
originalTargetAndAspectConfiguration,
transitivePackagesForPackageRootResolution,
- unloadedToolchainContext == null ? null : unloadedToolchainContext.targetPlatform(),
+ unloadedToolchainContexts == null
+ ? null
+ : unloadedToolchainContexts.getTargetPlatform(),
transitiveRootCauses);
if (configConditions == null) {
// Those targets haven't yet been resolved.
@@ -800,7 +822,8 @@
ConfiguredTargetAndData associatedTarget,
BuildConfigurationValue configuration,
ConfigConditions configConditions,
- ResolvedToolchainContext toolchainContext,
+ @Nullable ToolchainCollection<ResolvedToolchainContext> toolchainContexts,
+ @Nullable ExecGroupCollection.Builder execGroupCollectionBuilder,
OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> directDeps,
@Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
throws AspectFunctionException, InterruptedException {
@@ -842,7 +865,8 @@
aspect,
directDeps,
configConditions,
- toolchainContext,
+ toolchainContexts,
+ execGroupCollectionBuilder,
configuration,
view.getHostConfiguration(),
key);