diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ResolvedToolchainContext.java b/src/main/java/com/google/devtools/build/lib/analysis/ResolvedToolchainContext.java index 105a57d2fdca1f..33bbe0daf082df 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ResolvedToolchainContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ResolvedToolchainContext.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.platform.PlatformInfo; +import com.google.devtools.build.lib.analysis.platform.PlatformProviderUtils; import com.google.devtools.build.lib.analysis.platform.ToolchainInfo; import com.google.devtools.build.lib.analysis.platform.ToolchainTypeInfo; import com.google.devtools.build.lib.cmdline.Label; @@ -28,6 +29,9 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.rules.AliasConfiguredTarget; +import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData; +import com.google.devtools.build.lib.skyframe.ToolchainException; import com.google.devtools.build.lib.skylarkbuildapi.ToolchainContextApi; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.StarlarkContext; @@ -46,8 +50,64 @@ @ThreadSafe public abstract class ResolvedToolchainContext implements ToolchainContextApi, ToolchainContext { - static Builder builder() { - return new AutoValue_ResolvedToolchainContext.Builder(); + /** + * Finishes preparing the {@link ResolvedToolchainContext} by finding the specific toolchain + * providers to be used for each toolchain type. + */ + public static ResolvedToolchainContext load( + UnloadedToolchainContext unloadedToolchainContext, + String targetDescription, + Iterable toolchainTargets) + throws ToolchainException { + + ResolvedToolchainContext.Builder toolchainContext = + new AutoValue_ResolvedToolchainContext.Builder() + .setTargetDescription(targetDescription) + .setExecutionPlatform(unloadedToolchainContext.executionPlatform()) + .setTargetPlatform(unloadedToolchainContext.targetPlatform()) + .setRequiredToolchainTypes(unloadedToolchainContext.requiredToolchainTypes()) + .setResolvedToolchainLabels(unloadedToolchainContext.resolvedToolchainLabels()); + + ImmutableMap.Builder toolchains = + new ImmutableMap.Builder<>(); + ImmutableList.Builder templateVariableProviders = + new ImmutableList.Builder<>(); + for (ConfiguredTargetAndData target : toolchainTargets) { + Label discoveredLabel; + // Aliases are in toolchainTypeToResolved by the original alias label, not via the final + // target's label. + if (target.getConfiguredTarget() instanceof AliasConfiguredTarget) { + discoveredLabel = ((AliasConfiguredTarget) target.getConfiguredTarget()).getOriginalLabel(); + } else { + discoveredLabel = target.getConfiguredTarget().getLabel(); + } + ToolchainTypeInfo toolchainType = + unloadedToolchainContext.toolchainTypeToResolved().inverse().get(discoveredLabel); + ToolchainInfo toolchainInfo = PlatformProviderUtils.toolchain(target.getConfiguredTarget()); + + // If the toolchainType hadn't been resolved to an actual target, resolution would have + // failed with an error much earlier. However, the target might still not be an actual + // toolchain. + if (toolchainType != null) { + if (toolchainInfo != null) { + toolchains.put(toolchainType, toolchainInfo); + } else { + throw new TargetNotToolchainException(toolchainType, discoveredLabel); + } + } + + // Find any template variables present for this toolchain. + TemplateVariableInfo templateVariableInfo = + target.getConfiguredTarget().get(TemplateVariableInfo.PROVIDER); + if (templateVariableInfo != null) { + templateVariableProviders.add(templateVariableInfo); + } + } + + return toolchainContext + .setToolchains(toolchains.build()) + .setTemplateVariableProviders(templateVariableProviders.build()) + .build(); } /** Builder interface to help create new instances of {@link ResolvedToolchainContext}. */ @@ -179,4 +239,18 @@ public boolean containsKey(Object key, Location loc, StarlarkContext context) .findAny(); return matching.isPresent(); } + + /** + * Exception used when a toolchain type is required but the resolved target does not have + * ToolchainInfo. + */ + static final class TargetNotToolchainException extends ToolchainException { + TargetNotToolchainException(ToolchainTypeInfo toolchainType, Label resolvedTargetLabel) { + super( + String.format( + "toolchain type %s resolved to target %s, but that target does not provide" + + " ToolchainInfo", + toolchainType.typeLabel(), resolvedTargetLabel)); + } + } } 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 index 4c1765189f8ca7..59d8cf53240531 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainResolver.java @@ -63,7 +63,6 @@ public class ToolchainResolver { private final BuildConfigurationValue.Key configurationKey; // Optional data. - private String targetDescription = ""; private ImmutableSet