Search in sources :

Example 21 with BuildConfiguration

use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.

the class SkyframeDependencyResolver method getConfigurations.

@Nullable
@Override
protected List<BuildConfiguration> getConfigurations(Set<Class<? extends BuildConfiguration.Fragment>> fragments, Iterable<BuildOptions> buildOptions) throws InvalidConfigurationException, InterruptedException {
    List<SkyKey> keys = new ArrayList<>();
    for (BuildOptions options : buildOptions) {
        keys.add(BuildConfigurationValue.key(fragments, options));
    }
    Map<SkyKey, ValueOrException<InvalidConfigurationException>> configValues = env.getValuesOrThrow(keys, InvalidConfigurationException.class);
    if (env.valuesMissing()) {
        return null;
    }
    ImmutableList.Builder<BuildConfiguration> result = ImmutableList.builder();
    for (SkyKey key : keys) {
        result.add(((BuildConfigurationValue) configValues.get(key).get()).getConfiguration());
    }
    return result.build();
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) BuildOptions(com.google.devtools.build.lib.analysis.config.BuildOptions) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) ValueOrException(com.google.devtools.build.skyframe.ValueOrException) Nullable(javax.annotation.Nullable)

Example 22 with BuildConfiguration

use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.

the class SkyframeExecutor method getConfigurations.

/**
   * Retrieves the configurations needed for the given deps. If {@link
   * BuildConfiguration.Options#trimConfigurations()} is true, trims their fragments to only those
   * needed by their transitive closures. Else unconditionally includes all fragments.
   *
   * <p>Skips targets with loading phase errors.
   */
public Multimap<Dependency, BuildConfiguration> getConfigurations(ExtendedEventHandler eventHandler, BuildOptions fromOptions, Iterable<Dependency> keys) {
    Multimap<Dependency, BuildConfiguration> builder = ArrayListMultimap.<Dependency, BuildConfiguration>create();
    Set<Dependency> depsToEvaluate = new HashSet<>();
    // Check: if !Configuration.useDynamicConfigs then just return the original configs.
    Set<Class<? extends BuildConfiguration.Fragment>> allFragments = null;
    if (useUntrimmedDynamicConfigs(fromOptions)) {
        allFragments = ((ConfiguredRuleClassProvider) ruleClassProvider).getAllFragments();
    }
    // Get the fragments needed for dynamic configuration nodes.
    final List<SkyKey> transitiveFragmentSkyKeys = new ArrayList<>();
    Map<Label, Set<Class<? extends BuildConfiguration.Fragment>>> fragmentsMap = new HashMap<>();
    Set<Label> labelsWithErrors = new HashSet<>();
    for (Dependency key : keys) {
        if (key.hasStaticConfiguration()) {
            builder.put(key, key.getConfiguration());
        } else if (useUntrimmedDynamicConfigs(fromOptions)) {
            fragmentsMap.put(key.getLabel(), allFragments);
        } else {
            depsToEvaluate.add(key);
            transitiveFragmentSkyKeys.add(TransitiveTargetValue.key(key.getLabel()));
        }
    }
    EvaluationResult<SkyValue> fragmentsResult = evaluateSkyKeys(eventHandler, transitiveFragmentSkyKeys, /*keepGoing=*/
    true);
    for (Map.Entry<SkyKey, ErrorInfo> entry : fragmentsResult.errorMap().entrySet()) {
        reportCycles(eventHandler, entry.getValue().getCycleInfo(), entry.getKey());
    }
    for (Dependency key : keys) {
        if (!depsToEvaluate.contains(key)) {
        // No fragments to compute here.
        } else if (fragmentsResult.getError(TransitiveTargetValue.key(key.getLabel())) != null) {
            labelsWithErrors.add(key.getLabel());
        } else {
            TransitiveTargetValue ttv = (TransitiveTargetValue) fragmentsResult.get(TransitiveTargetValue.key(key.getLabel()));
            fragmentsMap.put(key.getLabel(), ttv.getTransitiveConfigFragments().toSet());
        }
    }
    // Now get the configurations.
    final List<SkyKey> configSkyKeys = new ArrayList<>();
    for (Dependency key : keys) {
        if (labelsWithErrors.contains(key.getLabel()) || key.hasStaticConfiguration()) {
            continue;
        }
        Set<Class<? extends BuildConfiguration.Fragment>> depFragments = fragmentsMap.get(key.getLabel());
        if (depFragments != null) {
            for (BuildOptions toOptions : ConfiguredTargetFunction.getDynamicTransitionOptions(fromOptions, key.getTransition(), depFragments, ruleClassProvider, true)) {
                configSkyKeys.add(BuildConfigurationValue.key(depFragments, toOptions));
            }
        }
    }
    EvaluationResult<SkyValue> configsResult = evaluateSkyKeys(eventHandler, configSkyKeys, /*keepGoing=*/
    true);
    for (Dependency key : keys) {
        if (labelsWithErrors.contains(key.getLabel()) || key.hasStaticConfiguration()) {
            continue;
        }
        Set<Class<? extends BuildConfiguration.Fragment>> depFragments = fragmentsMap.get(key.getLabel());
        if (depFragments != null) {
            for (BuildOptions toOptions : ConfiguredTargetFunction.getDynamicTransitionOptions(fromOptions, key.getTransition(), depFragments, ruleClassProvider, true)) {
                SkyKey configKey = BuildConfigurationValue.key(depFragments, toOptions);
                builder.put(key, ((BuildConfigurationValue) configsResult.get(configKey)).getConfiguration());
            }
        }
    }
    return builder;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Set(java.util.Set) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) ModifiedFileSet(com.google.devtools.build.lib.vfs.ModifiedFileSet) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ErrorInfo(com.google.devtools.build.skyframe.ErrorInfo) ArrayList(java.util.ArrayList) Label(com.google.devtools.build.lib.cmdline.Label) Dependency(com.google.devtools.build.lib.analysis.Dependency) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) SkyValue(com.google.devtools.build.skyframe.SkyValue) BuildOptions(com.google.devtools.build.lib.analysis.config.BuildOptions) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) HashSet(java.util.HashSet)

Example 23 with BuildConfiguration

use of com.google.devtools.build.lib.analysis.config.BuildConfiguration 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);
}
Also used : ConflictException(com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ConflictException) Attribute(com.google.devtools.build.lib.packages.Attribute) Label(com.google.devtools.build.lib.cmdline.Label) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) ActionAnalysisMetadata(com.google.devtools.build.lib.actions.ActionAnalysisMetadata) Dependency(com.google.devtools.build.lib.analysis.Dependency) EvalException(com.google.devtools.build.lib.syntax.EvalException) InconsistentAspectOrderException(com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException) InvalidConfigurationException(com.google.devtools.build.lib.analysis.config.InvalidConfigurationException) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) TargetAndConfiguration(com.google.devtools.build.lib.analysis.TargetAndConfiguration) ConfigMatchingProvider(com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider) Nullable(javax.annotation.Nullable)

Example 24 with BuildConfiguration

use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.

the class BazelConfigurationCollection method createConfigurations.

@Override
@Nullable
public BuildConfiguration createConfigurations(ConfigurationFactory configurationFactory, Cache<String, BuildConfiguration> cache, PackageProviderForConfigurations packageProvider, BuildOptions buildOptions, EventHandler eventHandler) throws InvalidConfigurationException, InterruptedException {
    // Target configuration
    BuildConfiguration targetConfiguration = configurationFactory.getConfiguration(packageProvider, buildOptions, false, cache);
    if (targetConfiguration == null) {
        return null;
    }
    BuildConfiguration dataConfiguration = targetConfiguration;
    // Host configuration
    // Note that this passes in the dataConfiguration, not the target
    // configuration. This is intentional.
    BuildConfiguration hostConfiguration = getHostConfigurationFromRequest(configurationFactory, packageProvider, dataConfiguration, buildOptions, cache);
    if (hostConfiguration == null) {
        return null;
    }
    ListMultimap<SplitTransition<?>, BuildConfiguration> splitTransitionsTable = ArrayListMultimap.create();
    for (SplitTransition<BuildOptions> transition : buildOptions.getPotentialSplitTransitions()) {
        for (BuildOptions splitOptions : transition.split(buildOptions)) {
            BuildConfiguration splitConfig = configurationFactory.getConfiguration(packageProvider, splitOptions, false, cache);
            splitTransitionsTable.put(transition, splitConfig);
        }
    }
    if (packageProvider.valuesMissing()) {
        return null;
    }
    BuildConfiguration result = setupTransitions(targetConfiguration, dataConfiguration, hostConfiguration, splitTransitionsTable);
    result.reportInvalidOptions(eventHandler);
    return result;
}
Also used : BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) AppleCrosstoolSplitTransition(com.google.devtools.build.lib.rules.objc.AppleCrosstoolSplitTransition) SplitTransition(com.google.devtools.build.lib.packages.Attribute.SplitTransition) BuildOptions(com.google.devtools.build.lib.analysis.config.BuildOptions) Nullable(javax.annotation.Nullable)

Example 25 with BuildConfiguration

use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.

the class SkyframeBuildView method getHostConfiguration.

/**
   * Returns the host configuration trimmed to the same fragments as the input configuration. If
   * the input is null, returns the top-level host configuration.
   *
   * <p>For static configurations, this unconditionally returns the (sole) top-level configuration.
   *
   * <p>This may only be called after {@link #setTopLevelHostConfiguration} has set the
   * correct host configuration at the top-level.
   */
public BuildConfiguration getHostConfiguration(BuildConfiguration config) {
    if (config == null || !config.useDynamicConfigurations()) {
        return topLevelHostConfiguration;
    }
    // TODO(bazel-team): have the fragment classes be those required by the consuming target's
    // transitive closure. This isn't the same as the input configuration's fragment classes -
    // the latter may be a proper subset of the former.
    //
    // ConfigurationFactory.getConfiguration provides the reason why: if a declared required
    // fragment is evaluated and returns null, it never gets added to the configuration. So if we
    // use the configuration's fragments as the source of truth, that excludes required fragments
    // that never made it in.
    //
    // If we're just trimming an existing configuration, this is no big deal (if the original
    // configuration doesn't need the fragment, the trimmed one doesn't either). But this method
    // trims a host configuration to the same scope as a target configuration. Since their options
    // are different, the host instance may actually be able to produce the fragment. So it's
    // wrong and potentially dangerous to unilaterally exclude it.
    Set<Class<? extends BuildConfiguration.Fragment>> fragmentClasses = config.trimConfigurations() ? config.fragmentClasses() : ((ConfiguredRuleClassProvider) ruleClassProvider).getAllFragments();
    BuildConfiguration hostConfig = hostConfigurationCache.get(fragmentClasses);
    if (hostConfig != null) {
        return hostConfig;
    }
    // TODO(bazel-team): investigate getting the trimmed config from Skyframe instead of cloning.
    // This is the only place we instantiate BuildConfigurations outside of Skyframe, This can
    // produce surprising effects, such as requesting a configuration that's in the Skyframe cache
    // but still produces a unique instance because we don't check that cache. It'd be nice to
    // guarantee that *all* instantiations happen through Skyframe. That could, for example,
    // guarantee that config1.equals(config2) implies config1 == config2, which is nice for
    // verifying we don't accidentally create extra configurations. But unfortunately,
    // hostConfigurationCache was specifically created because Skyframe is too slow for this use
    // case. So further optimization is necessary to make that viable (proto_library in particular
    // contributes to much of the difference).
    BuildConfiguration trimmedConfig = topLevelHostConfiguration.clone(fragmentClasses, ruleClassProvider);
    hostConfigurationCache.put(fragmentClasses, trimmedConfig);
    return trimmedConfig;
}
Also used : BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration)

Aggregations

BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)51 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)13 Label (com.google.devtools.build.lib.cmdline.Label)12 Artifact (com.google.devtools.build.lib.actions.Artifact)11 ImmutableList (com.google.common.collect.ImmutableList)8 ImmutableMap (com.google.common.collect.ImmutableMap)8 Test (org.junit.Test)8 Attribute (com.google.devtools.build.lib.packages.Attribute)7 BuildOptions (com.google.devtools.build.lib.analysis.config.BuildOptions)6 InvalidConfigurationException (com.google.devtools.build.lib.analysis.config.InvalidConfigurationException)6 Rule (com.google.devtools.build.lib.packages.Rule)6 Target (com.google.devtools.build.lib.packages.Target)6 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)6 SkyKey (com.google.devtools.build.skyframe.SkyKey)6 ArrayList (java.util.ArrayList)6 Map (java.util.Map)6 Nullable (javax.annotation.Nullable)6 Root (com.google.devtools.build.lib.actions.Root)5 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)5 HashMap (java.util.HashMap)5