Use toolchain resolution in rule creation.
Part of #2219.
Change-Id: Id4929d5ddcd57b4635af5e513eb9a09f16a78e71
PiperOrigin-RevId: 162634398
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 27cc526..0d11365 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
@@ -42,6 +42,7 @@
import com.google.devtools.build.lib.analysis.MergedConfiguredTarget;
import com.google.devtools.build.lib.analysis.MergedConfiguredTarget.DuplicateException;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
+import com.google.devtools.build.lib.analysis.ToolchainContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
@@ -72,6 +73,8 @@
import com.google.devtools.build.lib.skyframe.AspectFunction.AspectCreationException;
import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider;
+import com.google.devtools.build.lib.skyframe.ToolchainUtil.ToolchainContextException;
+import com.google.devtools.build.lib.skyframe.ToolchainUtil.UnresolvedToolchainsException;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import com.google.devtools.build.lib.util.Preconditions;
@@ -99,12 +102,12 @@
/**
* SkyFunction for {@link ConfiguredTargetValue}s.
*
- * This class, together with {@link AspectFunction} drives the analysis phase. For more information,
- * see {@link com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
+ * <p>This class, together with {@link AspectFunction} drives the analysis phase. For more
+ * information, see {@link com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
*
* @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
*/
-final class ConfiguredTargetFunction implements SkyFunction {
+public final class ConfiguredTargetFunction implements SkyFunction {
// This construction is a bit funky, but guarantees that the Object reference here is globally
// unique.
static final ImmutableMap<Label, ConfigMatchingProvider> NO_CONFIG_CONDITIONS =
@@ -231,6 +234,19 @@
new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
+ // Determine what toolchains are needed by this target.
+ ToolchainContext toolchainContext = null;
+ if (target instanceof Rule) {
+ ImmutableList<Label> requiredToolchains =
+ ((Rule) target).getRuleClassObject().getRequiredToolchains();
+ toolchainContext =
+ ToolchainUtil.createToolchainContext(env, requiredToolchains, configuration);
+ if (env.valuesMissing()) {
+ return null;
+ }
+ }
+
+ // Calculate the dependencies of this target.
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap =
computeDependencies(
env,
@@ -238,6 +254,7 @@
ctgValue,
ImmutableList.<Aspect>of(),
configConditions,
+ toolchainContext,
ruleClassProvider,
view.getHostConfiguration(configuration),
transitivePackages,
@@ -250,8 +267,16 @@
new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
Preconditions.checkNotNull(depValueMap);
- ConfiguredTargetValue ans = createConfiguredTarget(
- view, env, target, configuration, depValueMap, configConditions, transitivePackages);
+ ConfiguredTargetValue ans =
+ createConfiguredTarget(
+ view,
+ env,
+ target,
+ configuration,
+ depValueMap,
+ configConditions,
+ toolchainContext,
+ transitivePackages);
return ans;
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
@@ -276,28 +301,45 @@
}
throw new ConfiguredTargetFunctionException(
new ConfiguredValueCreationException(e.getMessage(), analysisRootCause));
+ } catch (ToolchainContextException e) {
+ if (e.getCause() instanceof UnresolvedToolchainsException) {
+ UnresolvedToolchainsException ute = (UnresolvedToolchainsException) e.getCause();
+ env.getListener()
+ .handle(Event.error(ute.getMessage() + " for target " + target.getLabel()));
+ throw new ConfiguredTargetFunctionException(
+ new ConfiguredValueCreationException(ute.getMessage(), target.getLabel()));
+ } else if (e.getCause() instanceof ConfiguredValueCreationException) {
+ ConfiguredValueCreationException cvce = (ConfiguredValueCreationException) e.getCause();
+ throw new ConfiguredTargetFunctionException(cvce);
+ } else {
+ // TODO(katre): better error handling
+ throw new ConfiguredTargetFunctionException(
+ new ConfiguredValueCreationException(e.getMessage()));
+ }
} finally {
cpuBoundSemaphore.release();
}
}
/**
- * Computes the direct dependencies of a node in the configured target graph (a configured
- * target or an aspects).
+ * Computes the direct dependencies of a node in the configured target graph (a configured target
+ * or an aspects).
*
* <p>Returns null if Skyframe hasn't evaluated the required dependencies yet. In this case, the
* caller should also return null to Skyframe.
- * @param env the Skyframe environment
+ *
+ * @param env the Skyframe environment
* @param resolver the dependency resolver
* @param ctgValue the label and the configuration of the node
* @param aspects
* @param configConditions the configuration conditions for evaluating the attributes of the node
+ * @param toolchainContext context information for required toolchains
* @param ruleClassProvider rule class provider for determining the right configuration fragments
- * to apply to deps
+ * to apply to deps
* @param hostConfiguration the host configuration. There's a noticeable performance hit from
* instantiating this on demand for every dependency that wants it, so it's best to compute
* the host configuration as early as possible and pass this reference to all consumers
- * */
+ */
@Nullable
static OrderedSetMultimap<Attribute, ConfiguredTarget> computeDependencies(
Environment env,
@@ -305,17 +347,24 @@
TargetAndConfiguration ctgValue,
Iterable<Aspect> aspects,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
+ @Nullable ToolchainContext toolchainContext,
RuleClassProvider ruleClassProvider,
BuildConfiguration hostConfiguration,
NestedSetBuilder<Package> transitivePackages,
NestedSetBuilder<Label> transitiveLoadingRootCauses)
throws DependencyEvaluationException, ConfiguredTargetFunctionException,
- AspectCreationException, InterruptedException {
+ AspectCreationException, InterruptedException {
// Create the map from attributes to set of (target, configuration) pairs.
OrderedSetMultimap<Attribute, Dependency> depValueNames;
try {
- depValueNames = resolver.dependentNodeMap(
- ctgValue, hostConfiguration, aspects, configConditions, transitiveLoadingRootCauses);
+ depValueNames =
+ resolver.dependentNodeMap(
+ ctgValue,
+ hostConfiguration,
+ aspects,
+ configConditions,
+ toolchainContext,
+ transitiveLoadingRootCauses);
} catch (EvalException e) {
// EvalException can only be thrown by computed Skylark attributes in the current rule.
env.getListener().handle(Event.error(e.getLocation(), e.getMessage()));
@@ -1102,10 +1151,14 @@
}
@Nullable
- private ConfiguredTargetValue createConfiguredTarget(SkyframeBuildView view,
- Environment env, Target target, BuildConfiguration configuration,
+ private ConfiguredTargetValue createConfiguredTarget(
+ SkyframeBuildView view,
+ Environment env,
+ Target target,
+ BuildConfiguration configuration,
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap,
ImmutableMap<Label, ConfigMatchingProvider> configConditions,
+ @Nullable ToolchainContext toolchainContext,
NestedSetBuilder<Package> transitivePackages)
throws ConfiguredTargetFunctionException, InterruptedException {
StoredEventHandler events = new StoredEventHandler();
@@ -1122,8 +1175,14 @@
}
Preconditions.checkNotNull(depValueMap);
- ConfiguredTarget configuredTarget = view.createConfiguredTarget(target, configuration,
- analysisEnvironment, depValueMap, configConditions);
+ ConfiguredTarget configuredTarget =
+ view.createConfiguredTarget(
+ target,
+ configuration,
+ analysisEnvironment,
+ depValueMap,
+ configConditions,
+ toolchainContext);
events.replayOn(env.getListener());
if (events.hasErrors()) {