Add a method to perform the necessary setups for Execution phase.
This new method combines a few setup steps from the various sources into one,
which will come into effect when we successfully merge the Skyframe phases.
This method is to be called before we enter the analysis/execution phase.
Note that the setup is not exhaustive at the current stage, but just enough to handle the "happy path" build without progress reporting and action cache.
RELNOTES: None
PiperOrigin-RevId: 398183724
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 3322a4f..f8b85ca 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -320,6 +320,7 @@
"//src/main/java/com/google/devtools/build/lib/skyframe:loading_phase_started_event",
"//src/main/java/com/google/devtools/build/lib/skyframe:managed_directories_knowledge",
"//src/main/java/com/google/devtools/build/lib/skyframe:package_progress_receiver",
+ "//src/main/java/com/google/devtools/build/lib/skyframe:package_roots_no_symlink_creation",
"//src/main/java/com/google/devtools/build/lib/skyframe:package_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions",
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index 0bbe732..a6b1825 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -16,6 +16,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Stopwatch;
import com.google.common.base.Throwables;
@@ -23,6 +24,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Iterables;
import com.google.common.flogger.GoogleLogger;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.ActionCacheChecker;
@@ -86,6 +88,7 @@
import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
import com.google.devtools.build.lib.skyframe.Builder;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
+import com.google.devtools.build.lib.skyframe.PackageRootsNoSymlinkCreation;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.DetailedExitCode;
@@ -103,6 +106,7 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
@@ -234,6 +238,85 @@
}
/**
+ * Sets up for execution.
+ *
+ * <p>b/199053098: This method concentrates the setup steps for execution, which were previously
+ * scattered over several classes. We need this in order to merge analysis & execution phases.
+ * TODO(b/199053098): Minimize code duplication with the main code path.
+ */
+ public void prepareForExecution(UUID buildId)
+ throws AbruptExitException, BuildFailedException, InterruptedException {
+ init();
+
+ SkyframeExecutor skyframeExecutor = env.getSkyframeExecutor();
+ // TODO(b/199053098): Support symlink forest.
+ List<Root> pkgPathEntries = env.getPackageLocator().getPathEntries();
+ Preconditions.checkState(
+ pkgPathEntries.size() == 1,
+ "--experimental_merged_skyframe_analysis_execution requires a single package path entry."
+ + " Found a list of size: %s",
+ pkgPathEntries.size());
+ Root singleSourceRoot = Iterables.getOnlyElement(pkgPathEntries);
+ PackageRoots noSymlinkPackageRoots = new PackageRootsNoSymlinkCreation(singleSourceRoot);
+ env.getEventBus().post(new ExecRootPreparedEvent(noSymlinkPackageRoots.getPackageRootsMap()));
+ env.getSkyframeBuildView()
+ .getArtifactFactory()
+ .setPackageRoots(noSymlinkPackageRoots.getPackageRootLookup());
+
+ OutputService outputService = env.getOutputService();
+ ModifiedFileSet modifiedOutputFiles = ModifiedFileSet.EVERYTHING_MODIFIED;
+ if (outputService != null) {
+ try (SilentCloseable c = Profiler.instance().profile("outputService.startBuild")) {
+ modifiedOutputFiles =
+ outputService.startBuild(
+ env.getReporter(), buildId, request.getBuildOptions().finalizeActions);
+ }
+ } else {
+ // TODO(bazel-team): this could be just another OutputService
+ try (SilentCloseable c = Profiler.instance().profile("startLocalOutputBuild")) {
+ startLocalOutputBuild();
+ }
+ }
+ if (outputService == null || !outputService.actionFileSystemType().inMemoryFileSystem()) {
+ // Must be created after the output path is created above.
+ createActionLogDirectory();
+ }
+
+ ActionCache actionCache = getActionCache();
+ actionCache.resetStatistics();
+ SkyframeBuilder skyframeBuilder;
+ try (SilentCloseable c = Profiler.instance().profile("createBuilder")) {
+ skyframeBuilder =
+ (SkyframeBuilder)
+ createBuilder(request, actionCache, skyframeExecutor, modifiedOutputFiles);
+ }
+ try (SilentCloseable c = Profiler.instance().profile("configureActionExecutor")) {
+ skyframeExecutor.configureActionExecutor(
+ skyframeBuilder.getFileCache(), skyframeBuilder.getActionInputPrefetcher());
+ }
+ // TODO(b/199053098): Setup progress reporting objects in SkyframeActionExecutor.
+ try (SilentCloseable c =
+ Profiler.instance().profile("prepareSkyframeActionExecutorForExecution")) {
+ skyframeExecutor.prepareSkyframeActionExecutorForExecution(
+ env.getReporter(),
+ executor,
+ request,
+ skyframeBuilder.getActionCacheChecker(),
+ skyframeBuilder.getTopDownActionCache());
+ }
+ for (ExecutorLifecycleListener executorLifecycleListener : executorLifecycleListeners) {
+ try (SilentCloseable c =
+ Profiler.instance().profile(executorLifecycleListener + ".executionPhaseStarting")) {
+ executorLifecycleListener.executionPhaseStarting(null, () -> null);
+ }
+ }
+
+ try (SilentCloseable c = Profiler.instance().profile("configureResourceManager")) {
+ configureResourceManager(env.getLocalResourceManager(), request);
+ }
+ }
+
+ /**
* Performs the execution phase (phase 3) of the build, in which the Builder is applied to the
* action graph to bring the targets up to date. (This function will return prior to
* execution-proper if --nobuild was specified.)
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
index 5dab8d3..98cb4ae 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
@@ -394,6 +394,22 @@
.build()));
}
+ ActionCacheChecker getActionCacheChecker() {
+ return actionCacheChecker;
+ }
+
+ TopDownActionCache getTopDownActionCache() {
+ return topDownActionCache;
+ }
+
+ MetadataProvider getFileCache() {
+ return fileCache;
+ }
+
+ ActionInputPrefetcher getActionInputPrefetcher() {
+ return actionInputPrefetcher;
+ }
+
private static int countTestActions(Iterable<ConfiguredTarget> testTargets) {
int count = 0;
for (ConfiguredTarget testTarget : testTargets) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 6fc958a..a0bd606 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -1610,14 +1610,8 @@
deleteActionsIfRemoteOptionsChanged(options);
try (SilentCloseable c =
Profiler.instance().profile("skyframeActionExecutor.prepareForExecution")) {
- skyframeActionExecutor.prepareForExecution(
- reporter,
- executor,
- options,
- actionCacheChecker,
- topDownActionCache,
- outputService,
- isAnalysisIncremental());
+ prepareSkyframeActionExecutorForExecution(
+ reporter, executor, options, actionCacheChecker, topDownActionCache);
}
resourceManager.resetResourceUsage();
@@ -1650,6 +1644,22 @@
}
}
+ public void prepareSkyframeActionExecutorForExecution(
+ Reporter reporter,
+ Executor executor,
+ OptionsProvider options,
+ ActionCacheChecker actionCacheChecker,
+ TopDownActionCache topDownActionCache) {
+ skyframeActionExecutor.prepareForExecution(
+ reporter,
+ executor,
+ options,
+ actionCacheChecker,
+ topDownActionCache,
+ outputService,
+ isAnalysisIncremental());
+ }
+
/** Asks the Skyframe evaluator to run a single exclusive test. */
public EvaluationResult<?> runExclusiveTest(
Reporter reporter,
@@ -1666,14 +1676,8 @@
try (SilentCloseable c =
Profiler.instance().profile("skyframeActionExecutor.prepareForExecution")) {
- skyframeActionExecutor.prepareForExecution(
- reporter,
- executor,
- options,
- actionCacheChecker,
- topDownActionCache,
- outputService,
- isAnalysisIncremental());
+ prepareSkyframeActionExecutorForExecution(
+ reporter, executor, options, actionCacheChecker, topDownActionCache);
}
resourceManager.resetResourceUsage();
@@ -1702,14 +1706,8 @@
OptionsProvider options,
ActionCacheChecker checker,
TopDownActionCache topDownActionCache) {
- skyframeActionExecutor.prepareForExecution(
- reporter,
- executor,
- options,
- checker,
- topDownActionCache,
- outputService,
- isAnalysisIncremental());
+ prepareSkyframeActionExecutorForExecution(
+ reporter, executor, options, checker, topDownActionCache);
}
private void deleteActionsIfRemoteOptionsChanged(OptionsProvider options)