Improve error message when requesting an invalid toolchain type from the context.
Fixes #3428.
Change-Id: Ib3f45bc6856651cfb29d338d0b4480ba1dd77cea
PiperOrigin-RevId: 163760940
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
index fc52bd6..23db96c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainContext.java
@@ -51,31 +51,42 @@
)
public class ToolchainContext {
public static ToolchainContext create(
- List<Label> requiredToolchains, ImmutableBiMap<Label, Label> resolvedLabels) {
+ String targetDescription,
+ List<Label> requiredToolchains,
+ ImmutableBiMap<Label, Label> resolvedLabels) {
ToolchainContext toolchainContext =
- new ToolchainContext(requiredToolchains, new ResolvedToolchainLabels(resolvedLabels));
+ new ToolchainContext(
+ targetDescription, requiredToolchains, new ResolvedToolchainLabels(resolvedLabels));
return toolchainContext;
}
+ /** Description of the target the toolchain context applies to, for use in error messages. */
+ private final String targetDescription;
+
+ /** The toolchain types that are required by the target. */
private final ImmutableList<Label> requiredToolchains;
- // Map from toolchain type labels to actual resolved toolchain labels.
+ /** Map from toolchain type labels to actual resolved toolchain labels. */
private final ResolvedToolchainLabels resolvedToolchainLabels;
- // Stores the actual ToolchainInfo provider for each toolchain type.
- private ResolvedToolchainProviders resolvedToolchainProviders =
- ResolvedToolchainProviders.empty();
+ /** Stores the actual ToolchainInfo provider for each toolchain type. */
+ private ResolvedToolchainProviders resolvedToolchainProviders;
private ToolchainContext(
- List<Label> requiredToolchains, ResolvedToolchainLabels resolvedToolchainLabels) {
+ String targetDescription,
+ List<Label> requiredToolchains,
+ ResolvedToolchainLabels resolvedToolchainLabels) {
+ this.targetDescription = targetDescription;
this.requiredToolchains = ImmutableList.copyOf(requiredToolchains);
this.resolvedToolchainLabels = resolvedToolchainLabels;
+ this.resolvedToolchainProviders =
+ new ResolvedToolchainProviders(ImmutableMap.<Label, ToolchainInfo>of());
}
public void resolveToolchains(OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap) {
if (!this.requiredToolchains.isEmpty()) {
this.resolvedToolchainProviders =
- ResolvedToolchainProviders.create(resolvedToolchainLabels, prerequisiteMap);
+ new ResolvedToolchainProviders(findToolchains(resolvedToolchainLabels, prerequisiteMap));
}
}
@@ -109,38 +120,36 @@
}
}
- /** Tracks the mapping from toolchain type label to {@link ToolchainInfo} provider. */
- private static class ResolvedToolchainProviders implements SkylarkValue, SkylarkIndexable {
- private static ResolvedToolchainProviders empty() {
- return new ResolvedToolchainProviders(ImmutableMap.<Label, ToolchainInfo>of());
- }
+ private static ImmutableMap<Label, ToolchainInfo> findToolchains(
+ ResolvedToolchainLabels resolvedToolchainLabels,
+ OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap) {
+ // Find the prerequisites associated with the $toolchains attribute.
+ Optional<Attribute> toolchainAttribute =
+ prerequisiteMap
+ .keys()
+ .stream()
+ .filter(attribute -> attribute.getName().equals(PlatformSemantics.TOOLCHAINS_ATTR))
+ .findFirst();
+ Preconditions.checkState(
+ toolchainAttribute.isPresent(),
+ "No toolchains attribute found while loading resolved toolchains");
- private static ResolvedToolchainProviders create(
- ResolvedToolchainLabels resolvedToolchainLabels,
- OrderedSetMultimap<Attribute, ConfiguredTarget> prerequisiteMap) {
- // Find the prerequisites associated with the $toolchains attribute.
- Optional<Attribute> toolchainAttribute =
- prerequisiteMap
- .keys()
- .stream()
- .filter(attribute -> attribute.getName().equals(PlatformSemantics.TOOLCHAINS_ATTR))
- .findFirst();
- Preconditions.checkState(
- toolchainAttribute.isPresent(),
- "No toolchains attribute found while loading resolved toolchains");
-
- ImmutableMap.Builder<Label, ToolchainInfo> toolchains = new ImmutableMap.Builder<>();
- for (ConfiguredTarget target : prerequisiteMap.get(toolchainAttribute.get())) {
- Label discoveredLabel = target.getLabel();
- Label toolchainType = resolvedToolchainLabels.getType(discoveredLabel);
- if (toolchainType != null) {
- ToolchainInfo toolchainInfo = PlatformProviderUtils.toolchain(target);
- toolchains.put(toolchainType, toolchainInfo);
- }
+ ImmutableMap.Builder<Label, ToolchainInfo> toolchains = new ImmutableMap.Builder<>();
+ for (ConfiguredTarget target : prerequisiteMap.get(toolchainAttribute.get())) {
+ Label discoveredLabel = target.getLabel();
+ Label toolchainType = resolvedToolchainLabels.getType(discoveredLabel);
+ if (toolchainType != null) {
+ ToolchainInfo toolchainInfo = PlatformProviderUtils.toolchain(target);
+ toolchains.put(toolchainType, toolchainInfo);
}
- return new ResolvedToolchainProviders(toolchains.build());
}
+ return toolchains.build();
+ }
+
+ /** Tracks the mapping from toolchain type label to {@link ToolchainInfo} provider. */
+ private class ResolvedToolchainProviders implements SkylarkValue, SkylarkIndexable {
+
private final ImmutableMap<Label, ToolchainInfo> toolchains;
private ResolvedToolchainProviders(ImmutableMap<Label, ToolchainInfo> toolchains) {
@@ -187,6 +196,19 @@
@Override
public ToolchainInfo getIndex(Object key, Location loc) throws EvalException {
Label toolchainType = transformKey(key, loc);
+
+ if (!requiredToolchains.contains(toolchainType)) {
+ throw new EvalException(
+ loc,
+ String.format(
+ "In %s, toolchain type %s was requested but only types [%s] are configured",
+ targetDescription,
+ toolchainType,
+ requiredToolchains
+ .stream()
+ .map(toolchain -> toolchain.toString())
+ .collect(joining())));
+ }
return toolchains.get(toolchainType);
}
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 234ed0b..57b09e2 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
@@ -278,7 +278,12 @@
ImmutableList<Label> requiredToolchains = aspect.getDefinition().getRequiredToolchains();
toolchainContext =
ToolchainUtil.createToolchainContext(
- env, requiredToolchains, key.getAspectConfiguration());
+ env,
+ String.format(
+ "aspect %s applied to %s",
+ aspect.getDescriptor().getDescription(), target.toString()),
+ requiredToolchains,
+ key.getAspectConfiguration());
} catch (ToolchainContextException e) {
// TODO(katre): better error handling
throw new AspectCreationException(e.getMessage());
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 4e3356d..1b783b9 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
@@ -234,10 +234,11 @@
// Determine what toolchains are needed by this target.
ToolchainContext toolchainContext = null;
if (target instanceof Rule) {
- ImmutableList<Label> requiredToolchains =
- ((Rule) target).getRuleClassObject().getRequiredToolchains();
+ Rule rule = ((Rule) target);
+ ImmutableList<Label> requiredToolchains = rule.getRuleClassObject().getRequiredToolchains();
toolchainContext =
- ToolchainUtil.createToolchainContext(env, requiredToolchains, configuration);
+ ToolchainUtil.createToolchainContext(
+ env, rule.toString(), requiredToolchains, configuration);
if (env.valuesMissing()) {
return null;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
index 3afe90a..4b1840a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainUtil.java
@@ -49,11 +49,15 @@
* of the {@link ToolchainResolutionFunction}.
*/
public static ToolchainContext createToolchainContext(
- Environment env, List<Label> requiredToolchains, BuildConfiguration configuration)
+ Environment env,
+ String targetDescription,
+ List<Label> requiredToolchains,
+ BuildConfiguration configuration)
throws ToolchainContextException, InterruptedException {
ImmutableBiMap<Label, Label> resolvedLabels =
resolveToolchainLabels(env, requiredToolchains, configuration);
- ToolchainContext toolchainContext = ToolchainContext.create(requiredToolchains, resolvedLabels);
+ ToolchainContext toolchainContext =
+ ToolchainContext.create(targetDescription, requiredToolchains, resolvedLabels);
return toolchainContext;
}