aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Dmitry Lomov <dslomov@google.com>2016-02-12 14:41:05 +0000
committerGravatar Dmitry Lomov <dslomov@google.com>2016-02-12 15:25:33 +0000
commitdfe2f10e28376407db239f867fb39629b35bf8ad (patch)
treec08ed71ae4f52aab00c6151bb4b207e82e8fc17a /src/main/java/com/google
parent0032f17ba372b96201d36ea5716eb994ac3dcf28 (diff)
Windows: execute build-runfiles through shell.
Needed for #276. -- MOS_MIGRATED_REVID=114529775
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeActionContext.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeHelper.java33
-rw-r--r--src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeStrategy.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/test/StandaloneTestStrategy.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/test/TestStrategy.java30
10 files changed, 97 insertions, 35 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
index b657e8d1ea..b96a7e7049 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RunfilesSupport.java
@@ -292,9 +292,16 @@ public class RunfilesSupport {
BuildConfiguration config = context.getConfiguration();
Artifact outputManifest = context.getDerivedArtifact(
outputManifestPath, config.getBinDirectory());
- context.getAnalysisEnvironment().registerAction(new SymlinkTreeAction(
- context.getActionOwner(), inputManifest, artifactsMiddleman, outputManifest,
- /*filesetTree=*/false));
+ context
+ .getAnalysisEnvironment()
+ .registerAction(
+ new SymlinkTreeAction(
+ context.getActionOwner(),
+ inputManifest,
+ artifactsMiddleman,
+ outputManifest,
+ /*filesetTree=*/ false,
+ config.getShExecutable()));
return outputManifest;
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
index 17591e0265..05f8ccd466 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeAction.java
@@ -23,6 +23,7 @@ import com.google.devtools.build.lib.actions.Executor;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.Preconditions;
+import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
@@ -37,6 +38,7 @@ public class SymlinkTreeAction extends AbstractAction {
private final Artifact inputManifest;
private final Artifact outputManifest;
private final boolean filesetTree;
+ private final PathFragment shExecutable;
/**
* Creates SymlinkTreeAction instance.
@@ -52,13 +54,19 @@ public class SymlinkTreeAction extends AbstractAction {
* @param filesetTree true if this is fileset symlink tree,
* false if this is a runfiles symlink tree.
*/
- public SymlinkTreeAction(ActionOwner owner, Artifact inputManifest,
- @Nullable Artifact artifactMiddleman, Artifact outputManifest, boolean filesetTree) {
+ public SymlinkTreeAction(
+ ActionOwner owner,
+ Artifact inputManifest,
+ @Nullable Artifact artifactMiddleman,
+ Artifact outputManifest,
+ boolean filesetTree,
+ PathFragment shExecutable) {
super(owner, computeInputs(inputManifest, artifactMiddleman), ImmutableList.of(outputManifest));
Preconditions.checkArgument(outputManifest.getPath().getBaseName().equals("MANIFEST"));
this.inputManifest = inputManifest;
this.outputManifest = outputManifest;
this.filesetTree = filesetTree;
+ this.shExecutable = shExecutable;
}
private static ImmutableList<Artifact> computeInputs(
@@ -114,7 +122,9 @@ public class SymlinkTreeAction extends AbstractAction {
public void execute(
ActionExecutionContext actionExecutionContext)
throws ActionExecutionException, InterruptedException {
- actionExecutionContext.getExecutor().getContext(SymlinkTreeActionContext.class)
- .createSymlinks(this, actionExecutionContext);
+ actionExecutionContext
+ .getExecutor()
+ .getContext(SymlinkTreeActionContext.class)
+ .createSymlinks(this, actionExecutionContext, shExecutable);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeActionContext.java b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeActionContext.java
index 9ad9c1ad58..dcf6ecbe4f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeActionContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/SymlinkTreeActionContext.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.analysis;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ActionExecutionException;
import com.google.devtools.build.lib.actions.Executor.ActionContext;
+import com.google.devtools.build.lib.vfs.PathFragment;
/**
* Action context for symlink tree actions (an action that creates a tree of symlinks).
@@ -25,7 +26,9 @@ public interface SymlinkTreeActionContext extends ActionContext {
/**
* Creates the symlink tree.
*/
- void createSymlinks(SymlinkTreeAction action,
- ActionExecutionContext actionExecutionContext)
+ void createSymlinks(
+ SymlinkTreeAction action,
+ ActionExecutionContext actionExecutionContext,
+ PathFragment shExecutable)
throws ActionExecutionException, InterruptedException;
}
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 295dc0596a..3f9de4f8ce 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
@@ -178,6 +178,7 @@ public class ExecutionTool {
this.runtime = env.getRuntime();
this.request = request;
+
// Create tools before getting the strategies from the modules as some of them need tools to
// determine whether the host actually supports certain strategies (e.g. sandboxing).
createToolsSymlinks();
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeHelper.java b/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeHelper.java
index ed87aea887..494f4454ca 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/SymlinkTreeHelper.java
@@ -27,6 +27,7 @@ import com.google.devtools.build.lib.analysis.config.BinTools;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.shell.CommandException;
import com.google.devtools.build.lib.util.CommandBuilder;
+import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.OsUtils;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.Path;
@@ -87,7 +88,7 @@ public final class SymlinkTreeHelper {
*/
public void createSymlinksUsingCommand(Path execRoot,
BuildConfiguration config, BinTools binTools) throws CommandException {
- List<String> argv = getSpawnArgumentList(execRoot, binTools);
+ List<String> argv = getSpawnArgumentList(execRoot, binTools, config.getShExecutable());
CommandBuilder builder = new CommandBuilder();
builder.addArgs(argv);
@@ -103,16 +104,20 @@ public final class SymlinkTreeHelper {
* block for undetermined period of time. If it is interrupted during
* that wait, ExecException will be thrown but interrupted bit will be
* preserved.
- *
- * @param action action instance that requested symlink tree creation
+ * @param action action instance that requested symlink tree creation
* @param actionExecutionContext Services that are in the scope of the action.
+ * @param shExecutable
*/
- public void createSymlinks(AbstractAction action, ActionExecutionContext actionExecutionContext,
- BinTools binTools) throws ExecException, InterruptedException {
+ public void createSymlinks(
+ AbstractAction action,
+ ActionExecutionContext actionExecutionContext,
+ BinTools binTools,
+ PathFragment shExecutable)
+ throws ExecException, InterruptedException {
List<String> args = getSpawnArgumentList(
- actionExecutionContext.getExecutor().getExecRoot(), binTools);
+ actionExecutionContext.getExecutor().getExecRoot(), binTools, shExecutable);
try (ResourceHandle handle =
- ResourceManager.instance().acquireResources(action, RESOURCE_SET)) {
+ ResourceManager.instance().acquireResources(action, RESOURCE_SET)) {
actionExecutionContext.getExecutor().getSpawnActionContext(action.getMnemonic()).exec(
new BaseSpawn.Local(args, ImmutableMap.<String, String>of(), action),
actionExecutionContext);
@@ -122,10 +127,20 @@ public final class SymlinkTreeHelper {
/**
* Returns the complete argument list build-runfiles has to be called with.
*/
- private List<String> getSpawnArgumentList(Path execRoot, BinTools binTools) {
+ private List<String> getSpawnArgumentList(
+ Path execRoot, BinTools binTools, PathFragment shExecutable) {
PathFragment path = binTools.getExecPath(BUILD_RUNFILES);
Preconditions.checkNotNull(path, BUILD_RUNFILES + " not found in embedded tools");
- List<String> args = Lists.newArrayList(execRoot.getRelative(path).getPathString());
+
+ List<String> args = Lists.newArrayList();
+ if (OS.getCurrent() == OS.WINDOWS) {
+ // During bootstrapping, build-runfiles is a shell script, that cannot be directly
+ // executed on Windows, so we shell out.
+ args.add(shExecutable.getPathString());
+ args.add("-c");
+ args.add("$0 $*");
+ }
+ args.add(execRoot.getRelative(path).getPathString());
if (filesetTree) {
args.add("--allow_relative");
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 f2b769533a..609ce57998 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
@@ -22,6 +22,7 @@ import com.google.devtools.build.lib.analysis.SymlinkTreeAction;
import com.google.devtools.build.lib.analysis.SymlinkTreeActionContext;
import com.google.devtools.build.lib.analysis.config.BinTools;
import com.google.devtools.build.lib.profiler.AutoProfiler;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.logging.Logger;
@@ -42,8 +43,10 @@ public final class SymlinkTreeStrategy implements SymlinkTreeActionContext {
}
@Override
- public void createSymlinks(SymlinkTreeAction action,
- ActionExecutionContext actionExecutionContext)
+ public void createSymlinks(
+ SymlinkTreeAction action,
+ ActionExecutionContext actionExecutionContext,
+ PathFragment shExecutable)
throws ActionExecutionException, InterruptedException {
Executor executor = actionExecutionContext.getExecutor();
try (AutoProfiler p =
@@ -58,7 +61,7 @@ public final class SymlinkTreeStrategy implements SymlinkTreeActionContext {
action.getOutputManifest().getPath(),
action.isFilesetTree(), helper.getSymlinkTreeRoot());
} else {
- helper.createSymlinks(action, actionExecutionContext, binTools);
+ helper.createSymlinks(action, actionExecutionContext, binTools, shExecutable);
}
} catch (ExecException e) {
throw e.toActionExecutionException(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
index 598b4fadbf..e11ff8ecfc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/NativeLibs.java
@@ -156,8 +156,14 @@ public final class NativeLibs {
ruleContext.getActionOwner(), null, symlinks.values(),
ruleContext.getConfiguration().getMiddlemanDirectory(), "android_native_libs");
- ruleContext.registerAction(new SymlinkTreeAction(
- ruleContext.getActionOwner(), inputManifest, nativeLibsMiddleman, outputManifest, false));
+ ruleContext.registerAction(
+ new SymlinkTreeAction(
+ ruleContext.getActionOwner(),
+ inputManifest,
+ nativeLibsMiddleman,
+ outputManifest,
+ false,
+ ruleContext.getConfiguration().getShExecutable()));
return outputManifest;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/StandaloneTestStrategy.java b/src/main/java/com/google/devtools/build/lib/rules/test/StandaloneTestStrategy.java
index 11b77f564c..d80fff8caf 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/StandaloneTestStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/StandaloneTestStrategy.java
@@ -70,8 +70,9 @@ public class StandaloneTestStrategy extends TestStrategy {
throws ExecException, InterruptedException {
Path runfilesDir = null;
try {
- runfilesDir = TestStrategy.getLocalRunfilesDirectory(
- action, actionExecutionContext, binTools);
+ runfilesDir =
+ TestStrategy.getLocalRunfilesDirectory(
+ action, actionExecutionContext, binTools, action.getShExecutable());
} catch (ExecException e) {
throw new TestExecException(e.getMessage());
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java
index f0860f8295..6fc354b6ff 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestRunnerAction.java
@@ -88,6 +88,7 @@ public class TestRunnerAction extends AbstractAction implements NotifyOnActionCa
private final int shardNum;
private final int runNumber;
private final String workspaceName;
+ private final PathFragment shExecutable;
// Mutable state related to test caching.
private boolean checkedCaching = false;
@@ -167,6 +168,7 @@ public class TestRunnerAction extends AbstractAction implements NotifyOnActionCa
this.undeclaredOutputsAnnotationsPath = undeclaredOutputsAnnotationsDir.getChild("ANNOTATIONS");
this.testInfrastructureFailure = baseDir.getChild(namePrefix + ".infrastructure_failure");
this.workspaceName = workspaceName;
+ this.shExecutable = configuration.getShExecutable();
Map<String, String> mergedTestEnv = new HashMap<>(configuration.getTestEnv());
mergedTestEnv.putAll(extraTestEnv);
@@ -556,6 +558,10 @@ public class TestRunnerAction extends AbstractAction implements NotifyOnActionCa
throw new UserExecException("'" + basename + "' not found in test runtime");
}
+ public PathFragment getShExecutable() {
+ return shExecutable;
+ }
+
/**
* The same set of paths as the parent test action, resolved against a given exec root.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/test/TestStrategy.java b/src/main/java/com/google/devtools/build/lib/rules/test/TestStrategy.java
index 3275791cf1..2ac016bbde 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/test/TestStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/test/TestStrategy.java
@@ -345,9 +345,12 @@ public abstract class TestStrategy implements TestActionContext {
* Returns the runfiles directory associated with the test executable,
* creating/updating it if necessary and --build_runfile_links is specified.
*/
- protected static Path getLocalRunfilesDirectory(TestRunnerAction testAction,
- ActionExecutionContext actionExecutionContext, BinTools binTools) throws ExecException,
- InterruptedException {
+ protected static Path getLocalRunfilesDirectory(
+ TestRunnerAction testAction,
+ ActionExecutionContext actionExecutionContext,
+ BinTools binTools,
+ PathFragment shExecutable)
+ throws ExecException, InterruptedException {
TestTargetExecutionSettings execSettings = testAction.getExecutionSettings();
// If the symlink farm is already created then return the existing directory. If not we
@@ -369,7 +372,8 @@ public abstract class TestStrategy implements TestActionContext {
long startTime = Profiler.nanoTimeMaybe();
synchronized (execSettings.getInputManifest()) {
Profiler.instance().logSimpleTask(startTime, ProfilerTask.WAIT, testAction);
- updateLocalRunfilesDirectory(testAction, runfilesDir, actionExecutionContext, binTools);
+ updateLocalRunfilesDirectory(
+ testAction, runfilesDir, actionExecutionContext, binTools, shExecutable);
}
return runfilesDir;
@@ -381,9 +385,13 @@ public abstract class TestStrategy implements TestActionContext {
* $0.runfiles/MANIFEST, if it exists, are used a proxy for the set of existing symlinks, to avoid
* the need for recursion.
*/
- private static void updateLocalRunfilesDirectory(TestRunnerAction testAction, Path runfilesDir,
- ActionExecutionContext actionExecutionContext, BinTools binTools) throws ExecException,
- InterruptedException {
+ private static void updateLocalRunfilesDirectory(
+ TestRunnerAction testAction,
+ Path runfilesDir,
+ ActionExecutionContext actionExecutionContext,
+ BinTools binTools,
+ PathFragment shExecutable)
+ throws ExecException, InterruptedException {
Executor executor = actionExecutionContext.getExecutor();
TestTargetExecutionSettings execSettings = testAction.getExecutionSettings();
@@ -401,9 +409,11 @@ public abstract class TestStrategy implements TestActionContext {
executor.getEventHandler().handle(Event.progress(
"Building runfiles directory for '" + execSettings.getExecutable().prettyPrint() + "'."));
- new SymlinkTreeHelper(execSettings.getInputManifest().getExecPath(),
- runfilesDir.relativeTo(executor.getExecRoot()), /* filesetTree= */ false)
- .createSymlinks(testAction, actionExecutionContext, binTools);
+ new SymlinkTreeHelper(
+ execSettings.getInputManifest().getExecPath(),
+ runfilesDir.relativeTo(executor.getExecRoot()), /* filesetTree= */
+ false)
+ .createSymlinks(testAction, actionExecutionContext, binTools, shExecutable);
executor.getEventHandler().handle(Event.progress(testAction.getProgressMessage()));
}