diff options
author | 2016-11-18 20:03:43 +0000 | |
---|---|---|
committer | 2016-11-21 19:37:41 +0000 | |
commit | 7883bf1da7f071dd8810e9b0bef7d70c9838e06c (patch) | |
tree | 7e2078f151846b1033d970bf16f64f288451ffc6 | |
parent | 2eaa31fade12242b7075c2bbac945aeeedf985e8 (diff) |
Adds support for multiple top-level dynamic configurations
(e.g. --experimental_multi_cpu).
--
MOS_MIGRATED_REVID=139607063
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/analysis/BuildView.java | 58 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java | 33 |
2 files changed, 61 insertions, 30 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java index 1f21e65dc7..b9297a2b68 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java @@ -19,12 +19,13 @@ import static com.google.common.collect.Iterables.concat; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Predicate; -import com.google.common.base.Verify; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; @@ -839,44 +840,49 @@ public class BuildView { private List<TargetAndConfiguration> getDynamicConfigurations( Iterable<TargetAndConfiguration> inputs, EventHandler eventHandler) throws InterruptedException { - Map<Label, TargetAndConfiguration> labelsToTargets = new LinkedHashMap<>(); - BuildConfiguration topLevelConfig = null; - List<Dependency> asDeps = new ArrayList<Dependency>(); + Map<Label, Target> labelsToTargets = new LinkedHashMap<>(); + // We'll get the configs from SkyframeExecutor#getConfigurations, which gets configurations + // for deps including transitions. So to satisfy its API we repackage each target as a + // Dependency with a NONE transition. + Multimap<BuildConfiguration, Dependency> asDeps = + ArrayListMultimap.<BuildConfiguration, Dependency>create(); for (TargetAndConfiguration targetAndConfig : inputs) { - labelsToTargets.put(targetAndConfig.getLabel(), targetAndConfig); - BuildConfiguration targetConfig = targetAndConfig.getConfiguration(); - if (targetConfig != null) { - asDeps.add(Dependency.withTransitionAndAspects( - targetAndConfig.getLabel(), - Attribute.ConfigurationTransition.NONE, - ImmutableSet.<AspectDescriptor>of())); // TODO(bazel-team): support top-level aspects - - // TODO(bazel-team): support multiple top-level configurations (for, e.g., - // --experimental_multi_cpu). This requires refactoring the getConfigurations() call below. - Verify.verify(topLevelConfig == null || topLevelConfig == targetConfig); - topLevelConfig = targetConfig; + labelsToTargets.put(targetAndConfig.getLabel(), targetAndConfig.getTarget()); + if (targetAndConfig.getConfiguration() != null) { + asDeps.put(targetAndConfig.getConfiguration(), + Dependency.withTransitionAndAspects( + targetAndConfig.getLabel(), + Attribute.ConfigurationTransition.NONE, + // TODO(bazel-team): support top-level aspects + ImmutableSet.<AspectDescriptor>of())); } } - Map<Label, TargetAndConfiguration> successfullyEvaluatedTargets = new LinkedHashMap<>(); + // Maps <target, originalConfig> pairs to <target, dynamicConfig> pairs for targets that + // could be successfully Skyframe-evaluated. + Map<TargetAndConfiguration, TargetAndConfiguration> successfullyEvaluatedTargets = + new LinkedHashMap<>(); if (!asDeps.isEmpty()) { - Map<Dependency, BuildConfiguration> trimmedTargets = - skyframeExecutor.getConfigurations(eventHandler, topLevelConfig.getOptions(), asDeps); - for (Map.Entry<Dependency, BuildConfiguration> trimmedTarget : trimmedTargets.entrySet()) { - Label targetLabel = trimmedTarget.getKey().getLabel(); - successfullyEvaluatedTargets.put(targetLabel, - new TargetAndConfiguration( - labelsToTargets.get(targetLabel).getTarget(), trimmedTarget.getValue())); + for (BuildConfiguration fromConfig : asDeps.keySet()) { + Map<Dependency, BuildConfiguration> trimmedTargets = + skyframeExecutor.getConfigurations(eventHandler, fromConfig.getOptions(), + asDeps.get(fromConfig)); + for (Map.Entry<Dependency, BuildConfiguration> trimmedTarget : trimmedTargets.entrySet()) { + Target target = labelsToTargets.get(trimmedTarget.getKey().getLabel()); + successfullyEvaluatedTargets.put( + new TargetAndConfiguration(target, fromConfig), + new TargetAndConfiguration(target, trimmedTarget.getValue())); + } } } ImmutableList.Builder<TargetAndConfiguration> result = ImmutableList.<TargetAndConfiguration>builder(); for (TargetAndConfiguration originalInput : inputs) { - if (successfullyEvaluatedTargets.containsKey(originalInput.getLabel())) { + if (successfullyEvaluatedTargets.containsKey(originalInput)) { // The configuration was successfully trimmed. - result.add(successfullyEvaluatedTargets.get(originalInput.getLabel())); + result.add(successfullyEvaluatedTargets.get(originalInput)); } else { // Either the configuration couldn't be determined (e.g. loading phase error) or it's null. result.add(originalInput); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java index 2463760aee..b36cc32010 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java @@ -258,8 +258,32 @@ public abstract class AnalysisTestCase extends FoundationTestCase { return masterConfig; } - protected BuildConfiguration getTargetConfiguration() { - return Iterables.getOnlyElement(masterConfig.getTargetConfigurations()); + /** + * Returns the target configuration for the most recent build, as created in Blaze's + * master configuration creation phase. Most significantly, this is never a dynamic + * configuration. + */ + protected BuildConfiguration getTargetConfiguration() throws InterruptedException { + return getTargetConfiguration(false); + } + + /** + * Returns the target configuration for the most recent build. If useDynamicVersionIfEnabled is + * true and dynamic configurations are enabled, returns the dynamic version. Else returns the + * static version. + */ + // TODO(gregce): force getTargetConfiguration() to getTargetConfiguration(true) once we know + // all callers can handle the dynamic version + protected BuildConfiguration getTargetConfiguration(boolean useDynamicVersionIfEnabled) + throws InterruptedException { + BuildConfiguration targetConfig = + Iterables.getOnlyElement(masterConfig.getTargetConfigurations()); + if (useDynamicVersionIfEnabled && targetConfig.useDynamicConfigurations()) { + return skyframeExecutor.getConfigurationForTesting(eventCollector, + targetConfig.fragmentClasses(), targetConfig.getOptions()); + } else { + return targetConfig; + } } protected BuildConfiguration getHostConfiguration() { @@ -379,7 +403,7 @@ public abstract class AnalysisTestCase extends FoundationTestCase { * Returns the corresponding configured target, if it exists. Note that this will only return * anything useful after a call to update() with the same label. */ - protected ConfiguredTarget getConfiguredTarget(String label) { + protected ConfiguredTarget getConfiguredTarget(String label) throws InterruptedException { return getConfiguredTarget(label, getTargetConfiguration()); } @@ -396,7 +420,8 @@ public abstract class AnalysisTestCase extends FoundationTestCase { return buildView.hasErrors(configuredTarget); } - protected Artifact getBinArtifact(String packageRelativePath, ConfiguredTarget owner) { + protected Artifact getBinArtifact(String packageRelativePath, ConfiguredTarget owner) + throws InterruptedException { Label label = owner.getLabel(); return buildView.getArtifactFactory().getDerivedArtifact( label.getPackageFragment().getRelative(packageRelativePath), |