aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Klaus Aehlig <aehlig@google.com>2017-05-08 08:26:03 -0400
committerGravatar Kristina Chodorow <kchodorow@google.com>2017-05-08 09:49:57 -0400
commit0cce00c45cfe663caa20cd565d505e1bd43024e4 (patch)
treed55c4e73d08b289d9bcd19437bc02568aa3ab472 /src
parent5aaf52f5d0704b91245517f19f2fe4638b2a6a97 (diff)
BEP: Provide infrastructure to report configurations
In preparation to support multi-configuration builds, provide infrastructure allowing build events to reference BuildConfigurations. The streaming mechanism will ensure that build configurations are introduced in the stream before being referenced for the first time. Change-Id: I6b96fbebc76a05eff4f75a07e8a9cfbcd57f9c22 PiperOrigin-RevId: 155368666
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildEventWithConfiguration.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java21
-rw-r--r--src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java84
5 files changed, 167 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 8514cdd7cd..3ff7f470df 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -42,6 +42,11 @@ import com.google.devtools.build.lib.analysis.Dependency;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection.Transitions;
+import com.google.devtools.build.lib.buildeventstream.BuildEvent;
+import com.google.devtools.build.lib.buildeventstream.BuildEventConverters;
+import com.google.devtools.build.lib.buildeventstream.BuildEventId;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
+import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
@@ -119,7 +124,7 @@ import javax.annotation.Nullable;
category = SkylarkModuleCategory.BUILTIN,
doc = "Data required for the analysis of a target that comes from targets that "
+ "depend on it and not targets that it depends on.")
-public final class BuildConfiguration {
+public final class BuildConfiguration implements BuildEvent {
/**
* An interface for language-specific configurations.
*
@@ -2713,4 +2718,26 @@ public final class BuildConfiguration {
}
return currentTransition;
}
+
+ @Override
+ public BuildEventId getEventId() {
+ return BuildEventId.configurationId(checksum());
+ }
+
+ @Override
+ public Collection<BuildEventId> getChildrenEvents() {
+ return ImmutableList.of();
+ }
+
+ @Override
+ public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) {
+ return GenericBuildEvent.protoChaining(this)
+ .setConfiguration(
+ BuildEventStreamProtos.Configuration.newBuilder()
+ .setMnemonic(getMnemonic())
+ .setPlatformName(getPlatformName())
+ .setCpu(getCpu())
+ .build())
+ .build();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildEventWithConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildEventWithConfiguration.java
new file mode 100644
index 0000000000..a4742c0101
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildEventWithConfiguration.java
@@ -0,0 +1,27 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.analysis.config;
+
+import com.google.devtools.build.lib.buildeventstream.BuildEvent;
+import java.util.Collection;
+
+/** Interface for {@link BuildEvent}s that reference {@link BuildConfigration}s */
+public interface BuildEventWithConfiguration extends BuildEvent {
+ /**
+ * The {@link BuildConfiguration}s the event mentions, and hence should be introduced in the
+ * stream before this event.
+ */
+ Collection<BuildConfiguration> getConfigurations();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
index 0e13b62b29..381358bfd4 100644
--- a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
+++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java
@@ -107,6 +107,13 @@ public final class BuildEventId implements Serializable {
.build());
}
+ public static BuildEventId configurationId(String id) {
+ BuildEventStreamProtos.BuildEventId.ConfigurationId configurationId =
+ BuildEventStreamProtos.BuildEventId.ConfigurationId.newBuilder().setId(id).build();
+ return new BuildEventId(
+ BuildEventStreamProtos.BuildEventId.newBuilder().setConfiguration(configurationId).build());
+ }
+
private static BuildEventId targetPatternExpanded(List<String> targetPattern, boolean skipped) {
BuildEventStreamProtos.BuildEventId.PatternExpandedId patternId =
BuildEventStreamProtos.BuildEventId.PatternExpandedId.newBuilder()
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
index b81341f54e..e55ca36cb3 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildEventStreamer.java
@@ -31,6 +31,8 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.EventReportingArtifacts;
import com.google.devtools.build.lib.analysis.BuildInfoEvent;
import com.google.devtools.build.lib.analysis.NoBuildEvent;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildEventWithConfiguration;
import com.google.devtools.build.lib.buildeventstream.AbortedEvent;
import com.google.devtools.build.lib.buildeventstream.AnnounceBuildEventTransportsEvent;
import com.google.devtools.build.lib.buildeventstream.ArtifactGroupNamer;
@@ -79,6 +81,7 @@ public class BuildEventStreamer implements EventHandler {
private final Reporter reporter;
private Set<BuildEventId> announcedEvents;
private final Set<BuildEventId> postedEvents = new HashSet<>();
+ private final Set<BuildEventId> configurationsPosted = new HashSet<>();
private final Multimap<BuildEventId, BuildEvent> pendingEvents = HashMultimap.create();
private int progressCount;
private final CountingArtifactGroupNamer artifactGroupNamer = new CountingArtifactGroupNamer();
@@ -299,6 +302,17 @@ public class BuildEventStreamer implements EventHandler {
maybeReportArtifactSet(new NestedSetView<Artifact>(set));
}
+ private void maybeReportConfiguration(BuildConfiguration configuration) {
+ BuildEventId id = configuration.getEventId();
+ synchronized (this) {
+ if (configurationsPosted.contains(id)) {
+ return;
+ }
+ configurationsPosted.add(id);
+ }
+ post(configuration);
+ }
+
@Override
public void handle(Event event) {}
@@ -318,6 +332,13 @@ public class BuildEventStreamer implements EventHandler {
return;
}
+ if (event instanceof BuildEventWithConfiguration) {
+ for (BuildConfiguration configuration :
+ ((BuildEventWithConfiguration) event).getConfigurations()) {
+ maybeReportConfiguration(configuration);
+ }
+ }
+
if (event instanceof EventReportingArtifacts) {
for (NestedSet<Artifact> artifactSet :
((EventReportingArtifacts) event).reportedArtifacts()) {
diff --git a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
index ef6ab7bec3..00738ae316 100644
--- a/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/runtime/BuildEventStreamerTest.java
@@ -21,6 +21,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.Futures;
@@ -28,6 +30,11 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.EventReportingArtifacts;
import com.google.devtools.build.lib.actions.Root;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildEventWithConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.FragmentOptions;
import com.google.devtools.build.lib.buildeventstream.AnnounceBuildEventTransportsEvent;
import com.google.devtools.build.lib.buildeventstream.ArtifactGroupNamer;
import com.google.devtools.build.lib.buildeventstream.BuildEvent;
@@ -198,6 +205,45 @@ public class BuildEventStreamerTest extends FoundationTestCase {
}
}
+ private static class GenericConfigurationEvent implements BuildEventWithConfiguration {
+ private final BuildEventId id;
+ private final Collection<BuildEventId> children;
+ private final Collection<BuildConfiguration> configurations;
+
+ GenericConfigurationEvent(
+ BuildEventId id,
+ Collection<BuildEventId> children,
+ Collection<BuildConfiguration> configurations) {
+ this.id = id;
+ this.children = children;
+ this.configurations = configurations;
+ }
+
+ GenericConfigurationEvent(BuildEventId id, BuildConfiguration configuration) {
+ this(id, ImmutableSet.<BuildEventId>of(), ImmutableSet.of(configuration));
+ }
+
+ @Override
+ public BuildEventId getEventId() {
+ return id;
+ }
+
+ @Override
+ public Collection<BuildEventId> getChildrenEvents() {
+ return children;
+ }
+
+ @Override
+ public Collection<BuildConfiguration> getConfigurations() {
+ return configurations;
+ }
+
+ @Override
+ public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) {
+ return GenericBuildEvent.protoChaining(this).build();
+ }
+ }
+
private static BuildEventId testId(String opaque) {
return BuildEventId.unknownBuildEventId(opaque);
}
@@ -546,4 +592,42 @@ public class BuildEventStreamerTest extends FoundationTestCase {
verify(outErr, times(1)).getOut();
verify(outErr, times(1)).getErr();
}
+
+ @Test
+ public void testReportedConfigurations() throws Exception {
+ // Verify that configuration events are posted, but only once.
+ RecordingBuildEventTransport transport = new RecordingBuildEventTransport();
+ BuildEventStreamer streamer =
+ new BuildEventStreamer(ImmutableSet.<BuildEventTransport>of(transport), reporter);
+
+ BuildEvent startEvent =
+ new GenericBuildEvent(
+ testId("Initial"),
+ ImmutableSet.<BuildEventId>of(ProgressEvent.INITIAL_PROGRESS_UPDATE));
+ BuildConfiguration configuration =
+ new BuildConfiguration(
+ new BlazeDirectories(outputBase, outputBase, rootDirectory, "productName"),
+ ImmutableMap.<Class<? extends BuildConfiguration.Fragment>,
+ BuildConfiguration.Fragment>of(),
+ BuildOptions.of(ImmutableList.<Class<? extends FragmentOptions>>of(
+ BuildConfiguration.Options.class)));
+ BuildEvent firstWithConfiguration =
+ new GenericConfigurationEvent(testId("first"), configuration);
+ BuildEvent secondWithConfiguration =
+ new GenericConfigurationEvent(testId("second"), configuration);
+
+ streamer.buildEvent(startEvent);
+ streamer.buildEvent(firstWithConfiguration);
+ streamer.buildEvent(secondWithConfiguration);
+
+ List<BuildEvent> allEventsSeen = transport.getEvents();
+ assertEquals(7, allEventsSeen.size());
+ assertEquals(startEvent.getEventId(), allEventsSeen.get(0).getEventId());
+ assertEquals(ProgressEvent.INITIAL_PROGRESS_UPDATE, allEventsSeen.get(1).getEventId());
+ assertEquals(configuration, allEventsSeen.get(2));
+ assertEquals(BuildEventId.progressId(1), allEventsSeen.get(3).getEventId());
+ assertEquals(firstWithConfiguration, allEventsSeen.get(4));
+ assertEquals(BuildEventId.progressId(2), allEventsSeen.get(5).getEventId());
+ assertEquals(secondWithConfiguration, allEventsSeen.get(6));
+ }
}