aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Estren <gregce@google.com>2016-11-18 20:03:43 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2016-11-21 19:37:41 +0000
commit7883bf1da7f071dd8810e9b0bef7d70c9838e06c (patch)
tree7e2078f151846b1033d970bf16f64f288451ffc6
parent2eaa31fade12242b7075c2bbac945aeeedf985e8 (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.java58
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java33
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),