use of com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException in project bazel by bazelbuild.
the class AspectFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws AspectFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
NestedSetBuilder<Label> transitiveRootCauses = NestedSetBuilder.stableOrder();
AspectKey key = (AspectKey) skyKey.argument();
ConfiguredAspectFactory aspectFactory;
Aspect aspect;
if (key.getAspectClass() instanceof NativeAspectClass) {
NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
} else if (key.getAspectClass() instanceof SkylarkAspectClass) {
SkylarkAspectClass skylarkAspectClass = (SkylarkAspectClass) key.getAspectClass();
SkylarkAspect skylarkAspect;
try {
skylarkAspect = loadSkylarkAspect(env, skylarkAspectClass.getExtensionLabel(), skylarkAspectClass.getExportedName());
} catch (AspectCreationException e) {
throw new AspectFunctionException(e);
}
if (skylarkAspect == null) {
return null;
}
aspectFactory = new SkylarkAspectFactory(skylarkAspect);
aspect = Aspect.forSkylark(skylarkAspect.getAspectClass(), skylarkAspect.getDefinition(key.getParameters()), key.getParameters());
} else {
throw new IllegalStateException();
}
// Keep this in sync with the same code in ConfiguredTargetFunction.
PackageValue packageValue = (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier()));
if (packageValue == null) {
return null;
}
Package pkg = packageValue.getPackage();
if (pkg.containsErrors()) {
throw new AspectFunctionException(new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier()));
}
Target target;
try {
target = pkg.getTarget(key.getLabel().getName());
} catch (NoSuchTargetException e) {
throw new AspectFunctionException(e);
}
if (!(target instanceof Rule)) {
env.getListener().handle(Event.error(target.getLocation(), String.format("%s is attached to %s %s but aspects must be attached to rules", aspect.getAspectClass().getName(), target.getTargetKind(), target.getName())));
throw new AspectFunctionException(new AspectCreationException("aspects must be attached to rules"));
}
ConfiguredTargetValue configuredTargetValue;
try {
configuredTargetValue = (ConfiguredTargetValue) env.getValueOrThrow(ConfiguredTargetValue.key(key.getLabel(), key.getBaseConfiguration()), ConfiguredValueCreationException.class);
} catch (ConfiguredValueCreationException e) {
throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
}
if (configuredTargetValue == null) {
// precomputed.
return null;
}
if (configuredTargetValue.getConfiguredTarget() == null) {
return null;
}
if (configuredTargetValue.getConfiguredTarget().getProvider(AliasProvider.class) != null) {
return createAliasAspect(env, target, aspect, key, configuredTargetValue.getConfiguredTarget());
}
ConfiguredTarget associatedTarget = configuredTargetValue.getConfiguredTarget();
ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder();
if (!key.getBaseKeys().isEmpty()) {
// We transitively collect all required aspects to reduce the number of restarts.
// Semantically it is enough to just request key.getBaseKeys().
ImmutableMap<AspectDescriptor, SkyKey> aspectKeys = getSkyKeysForAspects(key.getBaseKeys());
Map<SkyKey, SkyValue> values = env.getValues(aspectKeys.values());
if (env.valuesMissing()) {
return null;
}
try {
associatedTarget = getBaseTargetAndCollectPath(associatedTarget, key.getBaseKeys(), values, aspectPathBuilder);
} catch (DuplicateException e) {
env.getListener().handle(Event.error(associatedTarget.getTarget().getLocation(), e.getMessage()));
throw new AspectFunctionException(new AspectCreationException(e.getMessage(), associatedTarget.getLabel()));
}
}
aspectPathBuilder.add(aspect);
SkyframeDependencyResolver resolver = view.createDependencyResolver(env);
// When getting the dependencies of this hybrid aspect+base target, use the aspect's
// configuration. The configuration of the aspect will always be a superset of the target's
// (dynamic configuration mode: target is part of the aspect's config fragment requirements;
// static configuration mode: target is the same configuration as the aspect), so the fragments
// required by all dependencies (both those of the aspect and those of the base target)
// will be present this way.
TargetAndConfiguration originalTargetAndAspectConfiguration = new TargetAndConfiguration(target, key.getAspectConfiguration());
ImmutableList<Aspect> aspectPath = aspectPathBuilder.build();
try {
// Get the configuration targets that trigger this rule's configurable attributes.
ImmutableMap<Label, ConfigMatchingProvider> configConditions = ConfiguredTargetFunction.getConfigConditions(target, env, resolver, originalTargetAndAspectConfiguration, transitivePackages, transitiveRootCauses);
if (configConditions == null) {
// Those targets haven't yet been resolved.
return null;
}
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap;
try {
depValueMap = ConfiguredTargetFunction.computeDependencies(env, resolver, originalTargetAndAspectConfiguration, aspectPath, configConditions, ruleClassProvider, view.getHostConfiguration(originalTargetAndAspectConfiguration.getConfiguration()), transitivePackages, transitiveRootCauses);
} catch (ConfiguredTargetFunctionException e) {
throw new AspectCreationException(e.getMessage());
}
if (depValueMap == null) {
return null;
}
if (!transitiveRootCauses.isEmpty()) {
throw new AspectFunctionException(new AspectCreationException("Loading failed", transitiveRootCauses.build()));
}
return createAspect(env, key, aspectPath, aspect, aspectFactory, associatedTarget, key.getAspectConfiguration(), configConditions, depValueMap, transitivePackages);
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage(), cause.getAnalysisRootCause()));
} else if (e.getCause() instanceof InconsistentAspectOrderException) {
InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
} else {
// Cast to InvalidConfigurationException as a consistency check. If you add any
// DependencyEvaluationException constructors, you may need to change this code, too.
InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
}
} catch (AspectCreationException e) {
throw new AspectFunctionException(e);
}
}
use of com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException in project bazel by bazelbuild.
the class ConfiguredTargetFunction method compute.
@Override
public SkyValue compute(SkyKey key, Environment env) throws ConfiguredTargetFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
NestedSetBuilder<Label> transitiveLoadingRootCauses = NestedSetBuilder.stableOrder();
ConfiguredTargetKey configuredTargetKey = (ConfiguredTargetKey) key.argument();
LabelAndConfiguration lc = LabelAndConfiguration.of(configuredTargetKey.getLabel(), configuredTargetKey.getConfiguration());
BuildConfiguration configuration = lc.getConfiguration();
PackageValue packageValue = (PackageValue) env.getValue(PackageValue.key(lc.getLabel().getPackageIdentifier()));
if (packageValue == null) {
return null;
}
// TODO(ulfjack): This tries to match the logic in TransitiveTargetFunction /
// TargetMarkerFunction. Maybe we can merge the two?
Package pkg = packageValue.getPackage();
Target target;
try {
target = pkg.getTarget(lc.getLabel().getName());
} catch (NoSuchTargetException e) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(e.getMessage()));
}
if (pkg.containsErrors()) {
transitiveLoadingRootCauses.add(lc.getLabel());
}
transitivePackages.add(pkg);
// null).
if (!target.isConfigurable()) {
configuration = null;
}
// associates the error with the dep, which is misleading.
if (useDynamicConfigurations(configuration) && configuration.trimConfigurations() && env.getValue(TransitiveTargetValue.key(lc.getLabel())) == null) {
return null;
}
TargetAndConfiguration ctgValue = new TargetAndConfiguration(target, configuration);
SkyframeDependencyResolver resolver = view.createDependencyResolver(env);
// TODO(janakr): this acquire() call may tie up this thread indefinitely, reducing the
// parallelism of Skyframe. This is a strict improvement over the prior state of the code, in
// which we ran with #processors threads, but ideally we would call #tryAcquire here, and if we
// failed, would exit this SkyFunction and restart it when permits were available.
cpuBoundSemaphore.acquire();
try {
// Get the configuration targets that trigger this rule's configurable attributes.
ImmutableMap<Label, ConfigMatchingProvider> configConditions = getConfigConditions(ctgValue.getTarget(), env, resolver, ctgValue, transitivePackages, transitiveLoadingRootCauses);
if (env.valuesMissing()) {
return null;
}
// attributes.
if (!transitiveLoadingRootCauses.isEmpty() && configConditions != NO_CONFIG_CONDITIONS) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap = computeDependencies(env, resolver, ctgValue, ImmutableList.<Aspect>of(), configConditions, ruleClassProvider, view.getHostConfiguration(configuration), transitivePackages, transitiveLoadingRootCauses);
if (env.valuesMissing()) {
return null;
}
if (!transitiveLoadingRootCauses.isEmpty()) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
Preconditions.checkNotNull(depValueMap);
ConfiguredTargetValue ans = createConfiguredTarget(view, env, target, configuration, depValueMap, configConditions, transitivePackages);
return ans;
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
throw new ConfiguredTargetFunctionException((ConfiguredValueCreationException) e.getCause());
} else if (e.getCause() instanceof InconsistentAspectOrderException) {
InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
} else {
// Cast to InvalidConfigurationException as a consistency check. If you add any
// DependencyEvaluationException constructors, you may need to change this code, too.
InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
}
} catch (AspectCreationException e) {
// getAnalysisRootCause may be null if the analysis of the aspect itself failed.
Label analysisRootCause = target.getLabel();
if (e.getAnalysisRootCause() != null) {
analysisRootCause = e.getAnalysisRootCause();
}
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(e.getMessage(), analysisRootCause));
} finally {
cpuBoundSemaphore.release();
}
}
use of com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException in project bazel by bazelbuild.
the class PostConfiguredTargetFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
ImmutableMap<ActionAnalysisMetadata, ConflictException> badActions = PrecomputedValue.BAD_ACTIONS.get(env);
ConfiguredTargetValue ctValue = (ConfiguredTargetValue) env.getValue(ConfiguredTargetValue.key((ConfiguredTargetKey) skyKey.argument()));
if (env.valuesMissing()) {
return null;
}
for (ActionAnalysisMetadata action : ctValue.getActions()) {
if (badActions.containsKey(action)) {
throw new ActionConflictFunctionException(badActions.get(action));
}
}
ConfiguredTarget ct = ctValue.getConfiguredTarget();
TargetAndConfiguration ctgValue = new TargetAndConfiguration(ct.getTarget(), ct.getConfiguration());
ImmutableMap<Label, ConfigMatchingProvider> configConditions = getConfigurableAttributeConditions(ctgValue, env);
if (configConditions == null) {
return null;
}
OrderedSetMultimap<Attribute, Dependency> deps;
try {
BuildConfiguration hostConfiguration = buildViewProvider.getSkyframeBuildView().getHostConfiguration(ct.getConfiguration());
SkyframeDependencyResolver resolver = buildViewProvider.getSkyframeBuildView().createDependencyResolver(env);
// We don't track root causes here - this function is only invoked for successfully analyzed
// targets - as long as we redo the exact same steps here as in ConfiguredTargetFunction, this
// can never fail.
deps = resolver.dependentNodeMap(ctgValue, hostConfiguration, /*aspect=*/
null, configConditions);
if (ct.getConfiguration() != null && ct.getConfiguration().useDynamicConfigurations()) {
deps = ConfiguredTargetFunction.getDynamicConfigurations(env, ctgValue, deps, hostConfiguration, ruleClassProvider);
}
} catch (EvalException | ConfiguredTargetFunction.DependencyEvaluationException | InvalidConfigurationException | InconsistentAspectOrderException e) {
throw new PostConfiguredTargetFunctionException(e);
}
env.getValues(Iterables.transform(deps.values(), TO_KEYS));
if (env.valuesMissing()) {
return null;
}
return new PostConfiguredTargetValue(ct);
}
use of com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException in project bazel by bazelbuild.
the class ConfiguredTargetFunction method getConfigConditions.
/**
* Returns the set of {@link ConfigMatchingProvider}s that key the configurable attributes used by
* this rule.
*
* <p>>If the configured targets supplying those providers aren't yet resolved by the dependency
* resolver, returns null.
*/
@Nullable
static ImmutableMap<Label, ConfigMatchingProvider> getConfigConditions(Target target, Environment env, SkyframeDependencyResolver resolver, TargetAndConfiguration ctgValue, NestedSetBuilder<Package> transitivePackages, NestedSetBuilder<Label> transitiveLoadingRootCauses) throws DependencyEvaluationException, InterruptedException {
if (!(target instanceof Rule)) {
return NO_CONFIG_CONDITIONS;
}
Map<Label, ConfigMatchingProvider> configConditions = new LinkedHashMap<>();
// Collect the labels of the configured targets we need to resolve.
OrderedSetMultimap<Attribute, Label> configLabelMap = OrderedSetMultimap.create();
RawAttributeMapper attributeMap = RawAttributeMapper.of(((Rule) target));
for (Attribute a : ((Rule) target).getAttributes()) {
for (Label configLabel : attributeMap.getConfigurabilityKeys(a.getName(), a.getType())) {
if (!BuildType.Selector.isReservedLabel(configLabel)) {
configLabelMap.put(a, target.getLabel().resolveRepositoryRelative(configLabel));
}
}
}
if (configLabelMap.isEmpty()) {
return NO_CONFIG_CONDITIONS;
}
// Collect the corresponding Skyframe configured target values. Abort early if they haven't
// been computed yet.
Collection<Dependency> configValueNames = null;
try {
configValueNames = resolver.resolveRuleLabels(ctgValue, configLabelMap, transitiveLoadingRootCauses);
} catch (InconsistentAspectOrderException e) {
throw new DependencyEvaluationException(e);
}
if (env.valuesMissing()) {
return null;
}
// No need to get new configs from Skyframe - config_setting rules always use the current
// target's config.
// TODO(bazel-team): remove the need for this special transformation. We can probably do this by
// simply passing this through trimConfigurations.
BuildConfiguration targetConfig = ctgValue.getConfiguration();
if (useDynamicConfigurations(targetConfig)) {
ImmutableList.Builder<Dependency> staticConfigs = ImmutableList.builder();
for (Dependency dep : configValueNames) {
staticConfigs.add(Dependency.withConfigurationAndAspects(dep.getLabel(), targetConfig, dep.getAspects()));
}
configValueNames = staticConfigs.build();
}
Map<SkyKey, ConfiguredTarget> configValues = resolveConfiguredTargetDependencies(env, configValueNames, transitivePackages, transitiveLoadingRootCauses);
if (configValues == null) {
return null;
}
// Get the configured targets as ConfigMatchingProvider interfaces.
for (Dependency entry : configValueNames) {
ConfiguredTarget value = configValues.get(TO_KEYS.apply(entry));
// The code above guarantees that value is non-null here.
ConfigMatchingProvider provider = value.getProvider(ConfigMatchingProvider.class);
if (provider != null) {
configConditions.put(entry.getLabel(), provider);
} else {
// Not a valid provider for configuration conditions.
String message = entry.getLabel() + " is not a valid configuration key for " + target.getLabel();
env.getListener().handle(Event.error(TargetUtils.getLocationMaybe(target), message));
throw new DependencyEvaluationException(new ConfiguredValueCreationException(message, target.getLabel()));
}
}
return ImmutableMap.copyOf(configConditions);
}
Aggregations