Symlink creation: pass symlinks to OutputService
This allows implementations of the OutputService to skip reading the
manifest file and instead use the in-memory data.
PiperOrigin-RevId: 281464135
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeStrategy.java b/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeStrategy.java
index bd1c7a8..4dba210 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeStrategy.java
@@ -13,8 +13,10 @@
// limitations under the License.
package com.google.devtools.build.lib.exec;
+import com.google.common.collect.Maps;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionExecutionException;
+import com.google.devtools.build.lib.actions.EnvironmentalExecException;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ExecutionStrategy;
import com.google.devtools.build.lib.actions.RunningActionEvent;
@@ -22,6 +24,9 @@
import com.google.devtools.build.lib.analysis.actions.SymlinkTreeActionContext;
import com.google.devtools.build.lib.profiler.AutoProfiler;
import com.google.devtools.build.lib.vfs.OutputService;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
@@ -52,8 +57,25 @@
"running " + action.prettyPrint(), logger, /*minTimeForLoggingInMilliseconds=*/ 100)) {
try {
if (outputService != null && outputService.canCreateSymlinkTree()) {
+ Map<PathFragment, Path> symlinks = null;
+ if (action.getRunfiles() != null) {
+ try {
+ symlinks =
+ Maps.transformValues(
+ action
+ .getRunfiles()
+ .getRunfilesInputs(
+ actionExecutionContext.getEventHandler(),
+ action.getOwner().getLocation(),
+ actionExecutionContext.getPathResolver()),
+ (artifact) -> artifact.getPath());
+ } catch (IOException e) {
+ throw new EnvironmentalExecException(e);
+ }
+ }
outputService.createSymlinkTree(
actionExecutionContext.getInputPath(action.getInputManifest()),
+ symlinks,
actionExecutionContext.getInputPath(action.getOutputManifest()),
action.isFilesetTree(),
action.getOutputManifest().getExecPath().getParentDirectory());
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteOutputService.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteOutputService.java
index c1157a0..da925e6 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteOutputService.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteOutputService.java
@@ -107,7 +107,11 @@
@Override
public void createSymlinkTree(
- Path inputManifest, Path outputManifest, boolean filesetTree, PathFragment symlinkTreeRoot) {
+ Path inputManifest,
+ @Nullable Map<PathFragment, Path> symlinks,
+ Path outputManifest,
+ boolean filesetTree,
+ PathFragment symlinkTreeRoot) {
throw new UnsupportedOperationException();
}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/OutputService.java b/src/main/java/com/google/devtools/build/lib/vfs/OutputService.java
index 1fa759f..8f604a5 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/OutputService.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/OutputService.java
@@ -120,14 +120,20 @@
* Creates the symlink tree
*
* @param inputPath the input manifest
+ * @param symlinks the symlinks to create
* @param outputPath the output manifest
* @param filesetTree is true iff we're constructing a Fileset
* @param symlinkTreeRoot the symlink tree root, relative to the execRoot
* @throws ExecException on failure
* @throws InterruptedException
*/
- void createSymlinkTree(Path inputPath, Path outputPath, boolean filesetTree,
- PathFragment symlinkTreeRoot) throws ExecException, InterruptedException;
+ void createSymlinkTree(
+ Path inputPath,
+ @Nullable Map<PathFragment, Path> symlinks,
+ Path outputPath,
+ boolean filesetTree,
+ PathFragment symlinkTreeRoot)
+ throws ExecException, InterruptedException;
/**
* Cleans the entire output tree.