Fix users of toolchain resolution to call the new skyfunction.
Part of work on execution transitions, #7935.
Closes #8102.
PiperOrigin-RevId: 244878862
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java
deleted file mode 100644
index 4a92d5b..0000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java
+++ /dev/null
@@ -1,507 +0,0 @@
-// Copyright 2018 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;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableList.toImmutableList;
-import static java.util.stream.Collectors.joining;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableBiMap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Table;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
-import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
-import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
-import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
-import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
-import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil;
-import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil.InvalidConstraintValueException;
-import com.google.devtools.build.lib.skyframe.PlatformLookupUtil;
-import com.google.devtools.build.lib.skyframe.PlatformLookupUtil.InvalidPlatformException;
-import com.google.devtools.build.lib.skyframe.RegisteredExecutionPlatformsValue;
-import com.google.devtools.build.lib.skyframe.RegisteredToolchainsFunction.InvalidToolchainLabelException;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionFunction;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionFunction.NoToolchainFoundException;
-import com.google.devtools.build.lib.skyframe.SingleToolchainResolutionValue;
-import com.google.devtools.build.lib.skyframe.ToolchainException;
-import com.google.devtools.build.lib.skyframe.UnloadedToolchainContext;
-import com.google.devtools.build.skyframe.SkyFunction.Environment;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.ValueOrException2;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-
-/**
- * Performs the toolchain resolution process to determine the correct toolchain target dependencies
- * for a target being configured, based on the required toolchain types, target platform, and
- * available execution platforms.
- */
-public class ToolchainResolver {
- // Required data.
- private final Environment environment;
- private final BuildConfigurationValue.Key configurationKey;
-
- // Optional data.
- private ImmutableSet<Label> requiredToolchainTypeLabels = ImmutableSet.of();
- private ImmutableSet<Label> execConstraintLabels = ImmutableSet.of();
- private boolean shouldSanityCheckConfiguration = false;
-
- // Determined during execution.
- private boolean debug = false;
-
- /**
- * Creates a new {@link ToolchainResolver} to help find the required toolchains for a configured
- * target.
- *
- * @param env the environment to use to request dependent Skyframe nodes
- * @param configurationKey The build configuration to use for dependent targets
- */
- public ToolchainResolver(Environment env, BuildConfigurationValue.Key configurationKey) {
- this.environment = checkNotNull(env);
- this.configurationKey = checkNotNull(configurationKey);
- }
-
- /**
- * Sets the labels of the required toolchain types that this resolver needs to find toolchains
- * for.
- */
- public ToolchainResolver setRequiredToolchainTypes(Set<Label> requiredToolchainTypeLabels) {
- this.requiredToolchainTypeLabels = ImmutableSet.copyOf(requiredToolchainTypeLabels);
- return this;
- }
-
- /**
- * Sets extra constraints on the execution platform. Targets can use this to ensure that the
- * execution platform has some desired characteristics, such as having enough memory to run tests.
- */
- public ToolchainResolver setExecConstraintLabels(Set<Label> execConstraintLabels) {
- this.execConstraintLabels = ImmutableSet.copyOf(execConstraintLabels);
- return this;
- }
-
- /**
- * Sets whether the experimental retroactive trimming mode is in use. This determines whether
- * sanity checks regarding the fragments in use for the configurations of platforms and toolchains
- * are used - specifically, whether platforms use only the PlatformConfiguration, and toolchains
- * do not use any configuration at all.
- */
- public ToolchainResolver setShouldSanityCheckConfiguration(boolean useSanityChecks) {
- this.shouldSanityCheckConfiguration = useSanityChecks;
- return this;
- }
-
- /**
- * Determines the specific toolchains that are required, given the requested toolchain types,
- * target platform, and configuration.
- *
- * <p>In order to resolve toolchains, first the {@link ToolchainResolver} must be created, and
- * then an {@link UnloadedToolchainContext} generated. The {@link UnloadedToolchainContext} will
- * report the specific toolchain targets to depend on, and those can be found using the typical
- * dependency machinery. Once dependencies, including toolchains, have been loaded, the {@link
- * ResolvedToolchainContext#load} method can be called to generate the final {@link
- * ResolvedToolchainContext} to be used by the target.
- *
- * <p>This makes several SkyFrame calls, particularly to {@link
- * com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction} (to load platforms and
- * toolchains), to {@link
- * com.google.devtools.build.lib.skyframe.RegisteredExecutionPlatformsFunction}, and to {@link
- * SingleToolchainResolutionFunction}. This method returns {@code null} to signal a SkyFrame
- * restart is needed to resolve dependencies.
- */
- @Nullable
- public UnloadedToolchainContext resolve() throws InterruptedException, ToolchainException {
-
- try {
- UnloadedToolchainContext.Builder unloadedToolchainContext =
- UnloadedToolchainContext.builder();
-
- // Determine the configuration being used.
- BuildConfigurationValue value =
- (BuildConfigurationValue) environment.getValue(configurationKey);
- if (value == null) {
- throw new ValueMissingException();
- }
- BuildConfiguration configuration = value.getConfiguration();
- PlatformConfiguration platformConfiguration =
- configuration.getFragment(PlatformConfiguration.class);
- if (platformConfiguration == null) {
- throw new ValueMissingException();
- }
-
- // Check if debug output should be generated.
- this.debug = configuration.getOptions().get(PlatformOptions.class).toolchainResolutionDebug;
-
- // Create keys for all platforms that will be used, and validate them early.
- PlatformKeys platformKeys = loadPlatformKeys(configuration, platformConfiguration);
- if (environment.valuesMissing()) {
- return null;
- }
-
- // Determine the actual toolchain implementations to use.
- determineToolchainImplementations(unloadedToolchainContext, platformKeys);
-
- return unloadedToolchainContext.build();
- } catch (ValueMissingException e) {
- return null;
- }
- }
-
- @AutoValue
- abstract static class PlatformKeys {
- abstract ConfiguredTargetKey hostPlatformKey();
-
- abstract ConfiguredTargetKey targetPlatformKey();
-
- abstract ImmutableList<ConfiguredTargetKey> executionPlatformKeys();
-
- static PlatformKeys create(
- ConfiguredTargetKey hostPlatformKey,
- ConfiguredTargetKey targetPlatformKey,
- List<ConfiguredTargetKey> executionPlatformKeys) {
- return new AutoValue_ToolchainResolver_PlatformKeys(
- hostPlatformKey, targetPlatformKey, ImmutableList.copyOf(executionPlatformKeys));
- }
- }
-
- private PlatformKeys loadPlatformKeys(
- BuildConfiguration configuration, PlatformConfiguration platformConfiguration)
- throws InterruptedException, InvalidPlatformException, ValueMissingException,
- InvalidConstraintValueException {
- // Determine the target and host platform keys.
- Label hostPlatformLabel = platformConfiguration.getHostPlatform();
- Label targetPlatformLabel = platformConfiguration.getTargetPlatform();
-
- ConfiguredTargetKey hostPlatformKey = ConfiguredTargetKey.of(hostPlatformLabel, configuration);
- ConfiguredTargetKey targetPlatformKey =
- ConfiguredTargetKey.of(targetPlatformLabel, configuration);
-
- // Load the host and target platforms early, to check for errors.
- PlatformLookupUtil.getPlatformInfo(
- ImmutableList.of(hostPlatformKey, targetPlatformKey),
- environment,
- shouldSanityCheckConfiguration);
- if (environment.valuesMissing()) {
- throw new ValueMissingException();
- }
-
- ImmutableList<ConfiguredTargetKey> executionPlatformKeys =
- loadExecutionPlatformKeys(configuration, hostPlatformKey);
-
- return PlatformKeys.create(hostPlatformKey, targetPlatformKey, executionPlatformKeys);
- }
-
- private ImmutableList<ConfiguredTargetKey> loadExecutionPlatformKeys(
- BuildConfiguration configuration, ConfiguredTargetKey defaultPlatformKey)
- throws InvalidPlatformException, InterruptedException, InvalidConstraintValueException,
- ValueMissingException {
- RegisteredExecutionPlatformsValue registeredExecutionPlatforms =
- (RegisteredExecutionPlatformsValue)
- environment.getValueOrThrow(
- RegisteredExecutionPlatformsValue.key(configurationKey),
- InvalidPlatformException.class);
- if (registeredExecutionPlatforms == null) {
- throw new ValueMissingException();
- }
-
- ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys =
- new ImmutableList.Builder<ConfiguredTargetKey>()
- .addAll(registeredExecutionPlatforms.registeredExecutionPlatformKeys())
- .add(defaultPlatformKey)
- .build();
-
- // Filter out execution platforms that don't satisfy the extra constraints.
- ImmutableList<ConfiguredTargetKey> execConstraintKeys =
- execConstraintLabels.stream()
- .map(label -> ConfiguredTargetKey.of(label, configuration))
- .collect(toImmutableList());
-
- return filterAvailablePlatforms(availableExecutionPlatformKeys, execConstraintKeys);
- }
-
- /** Returns only the platform keys that match the given constraints. */
- private ImmutableList<ConfiguredTargetKey> filterAvailablePlatforms(
- ImmutableList<ConfiguredTargetKey> platformKeys,
- ImmutableList<ConfiguredTargetKey> constraintKeys)
- throws InterruptedException, InvalidPlatformException, InvalidConstraintValueException,
- ValueMissingException {
-
- // Short circuit if not needed.
- if (constraintKeys.isEmpty()) {
- return platformKeys;
- }
-
- // At this point the host and target platforms have been loaded, but not necessarily the chosen
- // execution platform (it might be the same as the host platform, and might not).
- //
- // It's not worth trying to optimize away this call, since in the optimizable case (the exec
- // platform is the host platform), Skyframe will return the correct results immediately without
- // need of a restart.
- Map<ConfiguredTargetKey, PlatformInfo> platformInfoMap =
- PlatformLookupUtil.getPlatformInfo(
- platformKeys, environment, shouldSanityCheckConfiguration);
- if (platformInfoMap == null) {
- throw new ValueMissingException();
- }
- List<ConstraintValueInfo> constraints =
- ConstraintValueLookupUtil.getConstraintValueInfo(constraintKeys, environment);
- if (constraints == null) {
- throw new ValueMissingException();
- }
-
- return platformKeys.stream()
- .filter(key -> filterPlatform(platformInfoMap.get(key), constraints))
- .collect(toImmutableList());
- }
-
- /** Returns {@code true} if the given platform has all of the constraints. */
- private boolean filterPlatform(PlatformInfo platformInfo, List<ConstraintValueInfo> constraints) {
- ImmutableList<ConstraintValueInfo> missingConstraints =
- platformInfo.constraints().findMissing(constraints);
- if (debug) {
- for (ConstraintValueInfo constraint : missingConstraints) {
- // The value for this setting is not present in the platform, or doesn't match the expected
- // value.
- environment
- .getListener()
- .handle(
- Event.info(
- String.format(
- "ToolchainResolver: Removed execution platform %s from"
- + " available execution platforms, it is missing constraint %s",
- platformInfo.label(), constraint.label())));
- }
- }
-
- return missingConstraints.isEmpty();
- }
-
- private void determineToolchainImplementations(
- UnloadedToolchainContext.Builder unloadedToolchainContext, PlatformKeys platformKeys)
- throws InterruptedException, ToolchainException, ValueMissingException {
-
- // Find the toolchains for the required toolchain types.
- List<SingleToolchainResolutionValue.Key> registeredToolchainKeys = new ArrayList<>();
- for (Label toolchainTypeLabel : requiredToolchainTypeLabels) {
- registeredToolchainKeys.add(
- SingleToolchainResolutionValue.key(
- configurationKey,
- toolchainTypeLabel,
- platformKeys.targetPlatformKey(),
- platformKeys.executionPlatformKeys()));
- }
-
- Map<SkyKey, ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>>
- results =
- environment.getValuesOrThrow(
- registeredToolchainKeys,
- NoToolchainFoundException.class,
- InvalidToolchainLabelException.class);
- boolean valuesMissing = false;
-
- // Determine the potential set of toolchains.
- Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains =
- HashBasedTable.create();
- ImmutableSet.Builder<ToolchainTypeInfo> requiredToolchainTypesBuilder = ImmutableSet.builder();
- List<Label> missingToolchains = new ArrayList<>();
- for (Map.Entry<
- SkyKey, ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>>
- entry : results.entrySet()) {
- try {
- ValueOrException2<NoToolchainFoundException, InvalidToolchainLabelException>
- valueOrException = entry.getValue();
- SingleToolchainResolutionValue singleToolchainResolutionValue =
- (SingleToolchainResolutionValue) valueOrException.get();
- if (singleToolchainResolutionValue == null) {
- valuesMissing = true;
- continue;
- }
-
- ToolchainTypeInfo requiredToolchainType = singleToolchainResolutionValue.toolchainType();
- requiredToolchainTypesBuilder.add(requiredToolchainType);
- resolvedToolchains.putAll(
- findPlatformsAndLabels(requiredToolchainType, singleToolchainResolutionValue));
- } catch (NoToolchainFoundException e) {
- // Save the missing type and continue looping to check for more.
- missingToolchains.add(e.missingToolchainTypeLabel());
- }
- }
-
- if (!missingToolchains.isEmpty()) {
- throw new UnresolvedToolchainsException(missingToolchains);
- }
-
- if (valuesMissing) {
- throw new ValueMissingException();
- }
-
- ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes = requiredToolchainTypesBuilder.build();
-
- // Find and return the first execution platform which has all required toolchains.
- Optional<ConfiguredTargetKey> selectedExecutionPlatformKey;
- if (requiredToolchainTypeLabels.isEmpty()
- && platformKeys.executionPlatformKeys().contains(platformKeys.hostPlatformKey())) {
- // Fall back to the legacy behavior: use the host platform if it's available, otherwise the
- // first execution platform.
- selectedExecutionPlatformKey = Optional.of(platformKeys.hostPlatformKey());
- } else {
- // If there are no toolchains, this will return the first execution platform.
- selectedExecutionPlatformKey =
- findExecutionPlatformForToolchains(
- requiredToolchainTypes, platformKeys.executionPlatformKeys(), resolvedToolchains);
- }
-
- if (!selectedExecutionPlatformKey.isPresent()) {
- throw new NoMatchingPlatformException(
- requiredToolchainTypeLabels,
- platformKeys.executionPlatformKeys(),
- platformKeys.targetPlatformKey());
- }
-
- Map<ConfiguredTargetKey, PlatformInfo> platforms =
- PlatformLookupUtil.getPlatformInfo(
- ImmutableList.of(selectedExecutionPlatformKey.get(), platformKeys.targetPlatformKey()),
- environment,
- shouldSanityCheckConfiguration);
- if (platforms == null) {
- throw new ValueMissingException();
- }
-
- unloadedToolchainContext.setRequiredToolchainTypes(requiredToolchainTypes);
- unloadedToolchainContext.setExecutionPlatform(
- platforms.get(selectedExecutionPlatformKey.get()));
- unloadedToolchainContext.setTargetPlatform(platforms.get(platformKeys.targetPlatformKey()));
-
- Map<ToolchainTypeInfo, Label> toolchains =
- resolvedToolchains.row(selectedExecutionPlatformKey.get());
- unloadedToolchainContext.setToolchainTypeToResolved(ImmutableBiMap.copyOf(toolchains));
- }
-
- /**
- * Adds all of toolchain labels from{@code toolchainResolutionValue} to {@code
- * resolvedToolchains}.
- */
- private static Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> findPlatformsAndLabels(
- ToolchainTypeInfo requiredToolchainType,
- SingleToolchainResolutionValue singleToolchainResolutionValue) {
-
- Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains =
- HashBasedTable.create();
- for (Map.Entry<ConfiguredTargetKey, Label> entry :
- singleToolchainResolutionValue.availableToolchainLabels().entrySet()) {
- resolvedToolchains.put(entry.getKey(), requiredToolchainType, entry.getValue());
- }
- return resolvedToolchains;
- }
-
- /**
- * Finds the first platform from {@code availableExecutionPlatformKeys} that is present in {@code
- * resolvedToolchains} and has all required toolchain types.
- */
- private Optional<ConfiguredTargetKey> findExecutionPlatformForToolchains(
- ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes,
- ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
- Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains) {
- for (ConfiguredTargetKey executionPlatformKey : availableExecutionPlatformKeys) {
- Map<ToolchainTypeInfo, Label> toolchains = resolvedToolchains.row(executionPlatformKey);
-
- if (!toolchains.keySet().containsAll(requiredToolchainTypes)) {
- // Not all toolchains are present, keep going
- continue;
- }
-
- if (debug) {
- String selectedToolchains =
- toolchains.entrySet().stream()
- .map(
- e ->
- String.format(
- "type %s -> toolchain %s", e.getKey().typeLabel(), e.getValue()))
- .collect(joining(", "));
- environment
- .getListener()
- .handle(
- Event.info(
- String.format(
- "ToolchainResolver: Selected execution platform %s, %s",
- executionPlatformKey.getLabel(), selectedToolchains)));
- }
- return Optional.of(executionPlatformKey);
- }
-
- return Optional.empty();
- }
-
- private static final class ValueMissingException extends Exception {
- private ValueMissingException() {
- super();
- }
- }
-
- /** Exception used when no execution platform can be found. */
- static final class NoMatchingPlatformException extends ToolchainException {
- NoMatchingPlatformException(
- Set<Label> requiredToolchainTypeLabels,
- ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
- ConfiguredTargetKey targetPlatformKey) {
- super(
- formatError(
- requiredToolchainTypeLabels, availableExecutionPlatformKeys, targetPlatformKey));
- }
-
- private static String formatError(
- Set<Label> requiredToolchainTypeLabels,
- ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
- ConfiguredTargetKey targetPlatformKey) {
- if (requiredToolchainTypeLabels.isEmpty()) {
- return String.format(
- "Unable to find an execution platform for target platform %s"
- + " from available execution platforms [%s]",
- targetPlatformKey.getLabel(),
- availableExecutionPlatformKeys.stream()
- .map(key -> key.getLabel().toString())
- .collect(Collectors.joining(", ")));
- }
- return String.format(
- "Unable to find an execution platform for toolchains [%s] and target platform %s"
- + " from available execution platforms [%s]",
- requiredToolchainTypeLabels.stream().map(Label::toString).collect(joining(", ")),
- targetPlatformKey.getLabel(),
- availableExecutionPlatformKeys.stream()
- .map(key -> key.getLabel().toString())
- .collect(Collectors.joining(", ")));
- }
- }
-
- /** Exception used when a toolchain type is required but no matching toolchain is found. */
- static final class UnresolvedToolchainsException extends ToolchainException {
- UnresolvedToolchainsException(List<Label> missingToolchainTypes) {
- super(
- String.format(
- "no matching toolchains found for types %s",
- missingToolchainTypes.stream().map(Label::toString).collect(joining(", "))));
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
index dff58a5..edefd40 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/PostAnalysisQueryEnvironment.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.query2;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -368,17 +369,26 @@
protected abstract RuleConfiguredTarget getRuleConfiguredTarget(T target);
+ protected Collection<T> targetifyValues(Iterable<SkyKey> dependencies)
+ throws InterruptedException {
+ Collection<T> values = new ArrayList<>();
+ for (SkyKey key : dependencies) {
+ if (key.functionName().equals(SkyFunctions.CONFIGURED_TARGET)) {
+ values.add(getValueFromKey(key));
+ } else if (key.functionName().equals(SkyFunctions.TOOLCHAIN_RESOLUTION)) {
+ // Also fetch these dependencies.
+ Collection<T> toolchainDeps = targetifyValues(graph.getDirectDeps(key));
+ values.addAll(toolchainDeps);
+ }
+ }
+ return values;
+ }
+
protected Map<SkyKey, Collection<T>> targetifyValues(
Map<SkyKey, ? extends Iterable<SkyKey>> input) throws InterruptedException {
Map<SkyKey, Collection<T>> result = new HashMap<>();
for (Map.Entry<SkyKey, ? extends Iterable<SkyKey>> entry : input.entrySet()) {
- Collection<T> value = new ArrayList<>();
- for (SkyKey key : entry.getValue()) {
- if (key.functionName().equals(SkyFunctions.CONFIGURED_TARGET)) {
- value.add(getValueFromKey(key));
- }
- }
- result.put(entry.getKey(), value);
+ result.put(entry.getKey(), targetifyValues(entry.getValue()));
}
return result;
}
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 743c7d2..d278350 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
@@ -31,7 +31,6 @@
import com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException;
import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
-import com.google.devtools.build.lib.analysis.ToolchainResolver;
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;
@@ -413,9 +412,15 @@
try {
ImmutableSet<Label> requiredToolchains = aspect.getDefinition().getRequiredToolchains();
unloadedToolchainContext =
- new ToolchainResolver(env, BuildConfigurationValue.key(configuration))
- .setRequiredToolchainTypes(requiredToolchains)
- .resolve();
+ (UnloadedToolchainContext)
+ env.getValueOrThrow(
+ UnloadedToolchainContext.key()
+ .configurationKey(BuildConfigurationValue.key(configuration))
+ .requiredToolchainTypeLabels(requiredToolchains)
+ .shouldSanityCheckConfiguration(
+ configuration.trimConfigurationsRetroactively())
+ .build(),
+ ToolchainException.class);
} catch (ToolchainException e) {
// TODO(katre): better error handling
throw new AspectCreationException(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
index a266129..1e36cb7 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java
@@ -37,7 +37,6 @@
import com.google.devtools.build.lib.analysis.EmptyConfiguredTarget;
import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
-import com.google.devtools.build.lib.analysis.ToolchainResolver;
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;
@@ -309,12 +308,16 @@
// Collect local (target, rule) constraints for filtering out execution platforms.
ImmutableSet<Label> execConstraintLabels = getExecutionPlatformConstraints(rule);
unloadedToolchainContext =
- new ToolchainResolver(env, configuredTargetKey.getConfigurationKey())
- .setRequiredToolchainTypes(requiredToolchains)
- .setExecConstraintLabels(execConstraintLabels)
- .setShouldSanityCheckConfiguration(
- configuration.trimConfigurationsRetroactively())
- .resolve();
+ (UnloadedToolchainContext)
+ env.getValueOrThrow(
+ UnloadedToolchainContext.key()
+ .configurationKey(configuredTargetKey.getConfigurationKey())
+ .requiredToolchainTypeLabels(requiredToolchains)
+ .execConstraintLabels(execConstraintLabels)
+ .shouldSanityCheckConfiguration(
+ configuration.trimConfigurationsRetroactively())
+ .build(),
+ ToolchainException.class);
if (env.valuesMissing()) {
return null;
}
@@ -426,10 +429,8 @@
e.getCauses()));
} catch (ToolchainException e) {
// We need to throw a ConfiguredValueCreationException, so either find one or make one.
- ConfiguredValueCreationException cvce;
- if (e.getCause() instanceof ConfiguredValueCreationException) {
- cvce = (ConfiguredValueCreationException) e.getCause();
- } else {
+ ConfiguredValueCreationException cvce = e.asConfiguredValueCreationException();
+ if (cvce == null) {
cvce =
new ConfiguredValueCreationException(e.getMessage(), target.getLabel(), configuration);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index da00c9f..76cdaf3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -138,7 +138,7 @@
SkyFunctionName.createHermetic("REGISTERED_TOOLCHAINS");
static final SkyFunctionName SINGLE_TOOLCHAIN_RESOLUTION =
SkyFunctionName.createHermetic("SINGLE_TOOLCHAIN_RESOLUTION");
- static final SkyFunctionName TOOLCHAIN_RESOLUTION =
+ public static final SkyFunctionName TOOLCHAIN_RESOLUTION =
SkyFunctionName.createHermetic("TOOLCHAIN_RESOLUTION");
public static final SkyFunctionName REPOSITORY_MAPPING =
SkyFunctionName.createHermetic("REPOSITORY_MAPPING");
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
index d39d838..d2bf860 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
@@ -93,7 +93,6 @@
// Determine the actual toolchain implementations to use.
determineToolchainImplementations(
env,
- debug,
key.configurationKey(),
key.requiredToolchainTypeLabels(),
builder,
@@ -275,7 +274,7 @@
.handle(
Event.info(
String.format(
- "ToolchainResolver: Removed execution platform %s from"
+ "ToolchainResolution: Removed execution platform %s from"
+ " available execution platforms, it is missing constraint %s",
platformInfo.label(), constraint.label())));
}
@@ -285,8 +284,7 @@
}
private void determineToolchainImplementations(
- SkyFunction.Environment environment,
- boolean debug,
+ Environment environment,
BuildConfigurationValue.Key configurationKey,
ImmutableSet<Label> requiredToolchainTypeLabels,
UnloadedToolchainContext.Builder builder,
@@ -358,8 +356,6 @@
if (!requiredToolchainTypeLabels.isEmpty()) {
selectedExecutionPlatformKey =
findExecutionPlatformForToolchains(
- environment,
- debug,
requiredToolchainTypes,
platformKeys.executionPlatformKeys(),
resolvedToolchains);
@@ -400,7 +396,7 @@
}
/**
- * Adds all of toolchain labels from{@code toolchainResolutionValue} to {@code
+ * Adds all of toolchain labels from {@code toolchainResolutionValue} to {@code
* resolvedToolchains}.
*/
private static Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> findPlatformsAndLabels(
@@ -421,8 +417,6 @@
* resolvedToolchains} and has all required toolchain types.
*/
private static Optional<ConfiguredTargetKey> findExecutionPlatformForToolchains(
- SkyFunction.Environment environment,
- boolean debug,
ImmutableSet<ToolchainTypeInfo> requiredToolchainTypes,
ImmutableList<ConfiguredTargetKey> availableExecutionPlatformKeys,
Table<ConfiguredTargetKey, ToolchainTypeInfo, Label> resolvedToolchains) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/ToolchainResolverTest.java b/src/test/java/com/google/devtools/build/lib/analysis/ToolchainResolverTest.java
deleted file mode 100644
index f50a399..0000000
--- a/src/test/java/com/google/devtools/build/lib/analysis/ToolchainResolverTest.java
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2018 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;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.lib.analysis.ToolchainResolver.NoMatchingPlatformException;
-import com.google.devtools.build.lib.analysis.ToolchainResolver.UnresolvedToolchainsException;
-import com.google.devtools.build.lib.analysis.util.AnalysisMock;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.rules.platform.ToolchainTestCase;
-import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
-import com.google.devtools.build.lib.skyframe.ConstraintValueLookupUtil.InvalidConstraintValueException;
-import com.google.devtools.build.lib.skyframe.PlatformLookupUtil.InvalidPlatformException;
-import com.google.devtools.build.lib.skyframe.ToolchainException;
-import com.google.devtools.build.lib.skyframe.UnloadedToolchainContext;
-import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
-import com.google.devtools.build.skyframe.EvaluationResult;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionException;
-import com.google.devtools.build.skyframe.SkyFunctionName;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
-import java.util.Set;
-import javax.annotation.Nullable;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link ToolchainResolver}. */
-@RunWith(JUnit4.class)
-public class ToolchainResolverTest extends ToolchainTestCase {
- /**
- * An {@link AnalysisMock} that injects {@link ResolveToolchainsFunction} into the Skyframe
- * executor.
- */
- private static final class LocalAnalysisMock extends AnalysisMock.Delegate {
- LocalAnalysisMock() {
- super(AnalysisMock.get());
- }
-
- @Override
- public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(
- BlazeDirectories directories) {
- return ImmutableMap.<SkyFunctionName, SkyFunction>builder()
- .putAll(super.getSkyFunctions(directories))
- .put(RESOLVE_TOOLCHAINS_FUNCTION, new ResolveToolchainsFunction())
- .build();
- }
- }
-
- @Override
- protected AnalysisMock getAnalysisMock() {
- return new LocalAnalysisMock();
- }
-
- @Test
- public void resolve() throws Exception {
- // This should select platform mac, toolchain extra_toolchain_mac, because platform
- // mac is listed first.
- addToolchain(
- "extra",
- "extra_toolchain_linux",
- ImmutableList.of("//constraints:linux"),
- ImmutableList.of("//constraints:linux"),
- "baz");
- addToolchain(
- "extra",
- "extra_toolchain_mac",
- ImmutableList.of("//constraints:mac"),
- ImmutableList.of("//constraints:linux"),
- "baz");
- rewriteWorkspace(
- "register_toolchains('//extra:extra_toolchain_linux', '//extra:extra_toolchain_mac')",
- "register_execution_platforms('//platforms:mac', '//platforms:linux')");
-
- useConfiguration("--platforms=//platforms:linux");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(ImmutableSet.of(testToolchainTypeLabel), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasNoError();
- UnloadedToolchainContext unloadedToolchainContext = result.get(key).unloadedToolchainContext();
- assertThat(unloadedToolchainContext).isNotNull();
-
- assertThat(unloadedToolchainContext.requiredToolchainTypes())
- .containsExactly(testToolchainType);
- assertThat(unloadedToolchainContext.resolvedToolchainLabels())
- .containsExactly(Label.parseAbsoluteUnchecked("//extra:extra_toolchain_mac_impl"));
-
- assertThat(unloadedToolchainContext.executionPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.executionPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:mac"));
-
- assertThat(unloadedToolchainContext.targetPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.targetPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:linux"));
- }
-
- @Test
- public void resolve_noToolchainType() throws Exception {
- scratch.file("host/BUILD", "platform(name = 'host')");
- rewriteWorkspace("register_execution_platforms('//platforms:mac', '//platforms:linux')");
-
- useConfiguration("--host_platform=//host:host", "--platforms=//platforms:linux");
- ResolveToolchainsKey key = ResolveToolchainsKey.create(ImmutableSet.of(), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasNoError();
- UnloadedToolchainContext unloadedToolchainContext = result.get(key).unloadedToolchainContext();
- assertThat(unloadedToolchainContext).isNotNull();
-
- assertThat(unloadedToolchainContext.requiredToolchainTypes()).isEmpty();
-
- // With no toolchains requested, should fall back to the host platform.
- assertThat(unloadedToolchainContext.executionPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.executionPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//host:host"));
-
- assertThat(unloadedToolchainContext.targetPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.targetPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:linux"));
- }
-
- @Test
- public void resolve_noToolchainType_hostNotAvailable() throws Exception {
- scratch.file("host/BUILD", "platform(name = 'host')");
- scratch.file(
- "sample/BUILD",
- "constraint_setting(name='demo')",
- "constraint_value(name = 'demo_a', constraint_setting=':demo')",
- "constraint_value(name = 'demo_b', constraint_setting=':demo')",
- "platform(name = 'sample_a',",
- " constraint_values = [':demo_a'],",
- ")",
- "platform(name = 'sample_b',",
- " constraint_values = [':demo_b'],",
- ")");
- rewriteWorkspace(
- "register_execution_platforms('//platforms:mac', '//platforms:linux',",
- " '//sample:sample_a', '//sample:sample_b')");
-
- useConfiguration("--host_platform=//host:host", "--platforms=//platforms:linux");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(),
- ImmutableSet.of(Label.parseAbsoluteUnchecked("//sample:demo_b")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasNoError();
- UnloadedToolchainContext unloadedToolchainContext = result.get(key).unloadedToolchainContext();
- assertThat(unloadedToolchainContext).isNotNull();
-
- assertThat(unloadedToolchainContext.requiredToolchainTypes()).isEmpty();
-
- assertThat(unloadedToolchainContext.executionPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.executionPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//sample:sample_b"));
-
- assertThat(unloadedToolchainContext.targetPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.targetPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:linux"));
- }
-
- @Test
- public void resolve_unavailableToolchainType_single() throws Exception {
- useConfiguration("--host_platform=//platforms:linux", "--platforms=//platforms:mac");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(
- testToolchainTypeLabel, Label.parseAbsoluteUnchecked("//fake/toolchain:type_1")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(UnresolvedToolchainsException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains("no matching toolchains found for types //fake/toolchain:type_1");
- }
-
- @Test
- public void resolve_unavailableToolchainType_multiple() throws Exception {
- useConfiguration("--host_platform=//platforms:linux", "--platforms=//platforms:mac");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(
- testToolchainTypeLabel,
- Label.parseAbsoluteUnchecked("//fake/toolchain:type_1"),
- Label.parseAbsoluteUnchecked("//fake/toolchain:type_2")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(UnresolvedToolchainsException.class);
- // Only one of the missing types will be reported, so do not check the specific error message.
- }
-
- @Test
- public void resolve_invalidTargetPlatform_badTarget() throws Exception {
- scratch.file("invalid/BUILD", "filegroup(name = 'not_a_platform')");
- useConfiguration("--platforms=//invalid:not_a_platform");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(ImmutableSet.of(testToolchainTypeLabel), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(InvalidPlatformException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains(
- "//invalid:not_a_platform was referenced as a platform, "
- + "but does not provide PlatformInfo");
- }
-
- @Test
- public void resolve_invalidTargetPlatform_badPackage() throws Exception {
- scratch.resolve("invalid").delete();
- useConfiguration("--platforms=//invalid:not_a_platform");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(ImmutableSet.of(testToolchainTypeLabel), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(InvalidPlatformException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains("BUILD file not found");
- }
-
- @Test
- public void resolve_invalidHostPlatform() throws Exception {
- scratch.file("invalid/BUILD", "filegroup(name = 'not_a_platform')");
- useConfiguration("--host_platform=//invalid:not_a_platform");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(ImmutableSet.of(testToolchainTypeLabel), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(InvalidPlatformException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains("//invalid:not_a_platform");
- }
-
- @Test
- public void resolve_invalidExecutionPlatform() throws Exception {
- scratch.file("invalid/BUILD", "filegroup(name = 'not_a_platform')");
- useConfiguration("--extra_execution_platforms=//invalid:not_a_platform");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(ImmutableSet.of(testToolchainTypeLabel), targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(InvalidPlatformException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains("//invalid:not_a_platform");
- }
-
- @Test
- public void resolve_execConstraints() throws Exception {
- // This should select platform linux, toolchain extra_toolchain_linux, due to extra constraints,
- // even though platform mac is registered first.
- addToolchain(
- /* packageName= */ "extra",
- /* toolchainName= */ "extra_toolchain_linux",
- /* execConstraints= */ ImmutableList.of("//constraints:linux"),
- /* targetConstraints= */ ImmutableList.of("//constraints:linux"),
- /* data= */ "baz");
- addToolchain(
- /* packageName= */ "extra",
- /* toolchainName= */ "extra_toolchain_mac",
- /* execConstraints= */ ImmutableList.of("//constraints:mac"),
- /* targetConstraints= */ ImmutableList.of("//constraints:linux"),
- /* data= */ "baz");
- rewriteWorkspace(
- "register_toolchains('//extra:extra_toolchain_linux', '//extra:extra_toolchain_mac')",
- "register_execution_platforms('//platforms:mac', '//platforms:linux')");
-
- useConfiguration("--platforms=//platforms:linux");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(testToolchainTypeLabel),
- ImmutableSet.of(Label.parseAbsoluteUnchecked("//constraints:linux")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasNoError();
- UnloadedToolchainContext unloadedToolchainContext = result.get(key).unloadedToolchainContext();
- assertThat(unloadedToolchainContext).isNotNull();
-
- assertThat(unloadedToolchainContext.requiredToolchainTypes())
- .containsExactly(testToolchainType);
- assertThat(unloadedToolchainContext.resolvedToolchainLabels())
- .containsExactly(Label.parseAbsoluteUnchecked("//extra:extra_toolchain_linux_impl"));
-
- assertThat(unloadedToolchainContext.executionPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.executionPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:linux"));
-
- assertThat(unloadedToolchainContext.targetPlatform()).isNotNull();
- assertThat(unloadedToolchainContext.targetPlatform().label())
- .isEqualTo(Label.parseAbsoluteUnchecked("//platforms:linux"));
- }
-
- @Test
- public void resolve_execConstraints_invalid() throws Exception {
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(testToolchainTypeLabel),
- ImmutableSet.of(Label.parseAbsoluteUnchecked("//platforms:linux")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
-
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(InvalidConstraintValueException.class);
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .hasMessageThat()
- .contains("//platforms:linux");
- }
-
- @Test
- public void resolve_noMatchingPlatform() throws Exception {
- // Write toolchain A, and a toolchain implementing it.
- scratch.appendFile(
- "a/BUILD",
- "toolchain_type(name = 'toolchain_type_A')",
- "toolchain(",
- " name = 'toolchain',",
- " toolchain_type = ':toolchain_type_A',",
- " exec_compatible_with = ['//constraints:mac'],",
- " target_compatible_with = [],",
- " toolchain = ':toolchain_impl')",
- "filegroup(name='toolchain_impl')");
- // Write toolchain B, and a toolchain implementing it.
- scratch.appendFile(
- "b/BUILD",
- "load('//toolchain:toolchain_def.bzl', 'test_toolchain')",
- "toolchain_type(name = 'toolchain_type_B')",
- "toolchain(",
- " name = 'toolchain',",
- " toolchain_type = ':toolchain_type_B',",
- " exec_compatible_with = ['//constraints:linux'],",
- " target_compatible_with = [],",
- " toolchain = ':toolchain_impl')",
- "filegroup(name='toolchain_impl')");
-
- rewriteWorkspace(
- "register_toolchains('//a:toolchain', '//b:toolchain')",
- "register_execution_platforms('//platforms:mac', '//platforms:linux')");
-
- useConfiguration("--platforms=//platforms:linux");
- ResolveToolchainsKey key =
- ResolveToolchainsKey.create(
- ImmutableSet.of(
- Label.parseAbsoluteUnchecked("//a:toolchain_type_A"),
- Label.parseAbsoluteUnchecked("//b:toolchain_type_B")),
- targetConfigKey);
-
- EvaluationResult<ResolveToolchainsValue> result = createToolchainContextBuilder(key);
- assertThatEvaluationResult(result).hasError();
- assertThatEvaluationResult(result)
- .hasErrorEntryForKeyThat(key)
- .hasExceptionThat()
- .isInstanceOf(NoMatchingPlatformException.class);
- }
-
- private static final SkyFunctionName RESOLVE_TOOLCHAINS_FUNCTION =
- SkyFunctionName.createHermetic("RESOLVE_TOOLCHAINS_FUNCTION");
-
- @AutoValue
- abstract static class ResolveToolchainsKey implements SkyKey {
- @Override
- public SkyFunctionName functionName() {
- return RESOLVE_TOOLCHAINS_FUNCTION;
- }
-
- abstract ImmutableSet<Label> requiredToolchainTypes();
-
- abstract ImmutableSet<Label> execConstraintLabels();
-
- abstract BuildConfigurationValue.Key configurationKey();
-
- public static ResolveToolchainsKey create(
- Set<Label> requiredToolchains,
- BuildConfigurationValue.Key configurationKey) {
- return create(
- requiredToolchains,
- /* execConstraintLabels= */ ImmutableSet.of(),
- configurationKey);
- }
-
- public static ResolveToolchainsKey create(
- Set<Label> requiredToolchains,
- Set<Label> execConstraintLabels,
- BuildConfigurationValue.Key configurationKey) {
- return new AutoValue_ToolchainResolverTest_ResolveToolchainsKey(
- ImmutableSet.copyOf(requiredToolchains),
- ImmutableSet.copyOf(execConstraintLabels),
- configurationKey);
- }
- }
-
- private EvaluationResult<ResolveToolchainsValue> createToolchainContextBuilder(
- ResolveToolchainsKey key) throws InterruptedException {
- try {
- // Must re-enable analysis for Skyframe functions that create configured targets.
- skyframeExecutor.getSkyframeBuildView().enableAnalysis(true);
- return SkyframeExecutorTestUtils.evaluate(
- skyframeExecutor, key, /*keepGoing=*/ false, reporter);
- } finally {
- skyframeExecutor.getSkyframeBuildView().enableAnalysis(false);
- }
- }
-
- @AutoValue
- abstract static class ResolveToolchainsValue implements SkyValue {
- abstract UnloadedToolchainContext unloadedToolchainContext();
-
- static ResolveToolchainsValue create(UnloadedToolchainContext unloadedToolchainContext) {
- return new AutoValue_ToolchainResolverTest_ResolveToolchainsValue(unloadedToolchainContext);
- }
- }
-
- private static final class ResolveToolchainsFunction implements SkyFunction {
-
- @Nullable
- @Override
- public SkyValue compute(SkyKey skyKey, Environment env)
- throws SkyFunctionException, InterruptedException {
- ResolveToolchainsKey key = (ResolveToolchainsKey) skyKey;
- ToolchainResolver toolchainResolver =
- new ToolchainResolver(env, key.configurationKey())
- .setRequiredToolchainTypes(key.requiredToolchainTypes())
- .setExecConstraintLabels(key.execConstraintLabels());
-
- try {
- UnloadedToolchainContext unloadedToolchainContext = toolchainResolver.resolve();
- if (unloadedToolchainContext == null) {
- return null;
- }
- return ResolveToolchainsValue.create(unloadedToolchainContext);
- } catch (ToolchainException e) {
- throw new ResolveToolchainsFunctionException(e);
- }
- }
-
- @Nullable
- @Override
- public String extractTag(SkyKey skyKey) {
- return null;
- }
- }
-
- private static class ResolveToolchainsFunctionException extends SkyFunctionException {
- ResolveToolchainsFunctionException(ToolchainException e) {
- super(e, Transience.PERSISTENT);
- }
- }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
index c99c79a..b267e88 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewForTesting.java
@@ -41,7 +41,6 @@
import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
-import com.google.devtools.build.lib.analysis.ToolchainResolver;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
@@ -494,9 +493,13 @@
SkyFunctionEnvironmentForTesting skyfunctionEnvironment =
skyframeExecutor.getSkyFunctionEnvironmentForTesting(eventHandler);
UnloadedToolchainContext unloadedToolchainContext =
- new ToolchainResolver(skyfunctionEnvironment, BuildConfigurationValue.key(targetConfig))
- .setRequiredToolchainTypes(requiredToolchains)
- .resolve();
+ (UnloadedToolchainContext)
+ skyfunctionEnvironment.getValueOrThrow(
+ UnloadedToolchainContext.key()
+ .configurationKey(BuildConfigurationValue.key(targetConfig))
+ .requiredToolchainTypeLabels(requiredToolchains)
+ .build(),
+ ToolchainException.class);
OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> prerequisiteMap =
getPrerequisiteMapForTesting(
diff --git a/src/test/shell/bazel/toolchain_test.sh b/src/test/shell/bazel/toolchain_test.sh
index 7eedb4e..44c6f24 100755
--- a/src/test/shell/bazel/toolchain_test.sh
+++ b/src/test/shell/bazel/toolchain_test.sh
@@ -441,7 +441,7 @@
//demo:use &> $TEST_log || fail "Build failed"
expect_log 'ToolchainResolution: Looking for toolchain of type //toolchain:test_toolchain'
expect_log 'ToolchainResolution: For toolchain type //toolchain:test_toolchain, possible execution platforms and toolchains: {@local_config_platform//:host -> //:test_toolchain_impl_1}'
- expect_log 'ToolchainResolver: Selected execution platform @local_config_platform//:host, type //toolchain:test_toolchain -> toolchain //:test_toolchain_impl_1'
+ expect_log 'ToolchainResolution: Selected execution platform @local_config_platform//:host, type //toolchain:test_toolchain -> toolchain //:test_toolchain_impl_1'
expect_log 'Using toolchain: rule message: "this is the rule", toolchain extra_str: "foo from test_toolchain"'
}
@@ -820,7 +820,7 @@
--extra_execution_platforms=//platform:test_platform \
--toolchain_resolution_debug \
//demo:target &> $TEST_log || fail "Build failed"
- expect_log "ToolchainResolver: Selected execution platform //platform:test_platform"
+ expect_log "ToolchainResolution: Selected execution platform //platform:test_platform"
}