aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2016-11-02 17:52:00 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2016-11-03 07:17:01 +0000
commita1b2ae004c179e218acdd8028cd698e2c7102eba (patch)
tree7d1588022bc9796346af1cff9a1b1a2e8a07eba7
parentf7a5769187a11d4d15ed685abf55338eaeafdc12 (diff)
java_binary: fix runfiles dir creation on Windows
Create the runfiles directory for the shell stub script (bazel-bin/foo/bar_bin and bazel-bin/foo/bar_bin.runfiles) but use the batch script as the runfiles provider's executable (bazel-bin/foo/bar_bin.cmd). This way we the shell stub script can still find its runfiles (under its parent directory + its base name + ".runfiles) while "bazel run" can also work on Windows. Fixes https://github.com/bazelbuild/bazel/issues/2025 See https://github.com/bazelbuild/bazel/issues/1925 -- MOS_MIGRATED_REVID=137965442
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java43
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java8
2 files changed, 36 insertions, 15 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
index cd0173e777..db6563a6fd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java
@@ -147,14 +147,21 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
helper.createInstrumentationMetadata(classJar, javaArtifactsBuilder);
NestedSetBuilder<Artifact> filesBuilder = NestedSetBuilder.stableOrder();
- Artifact executable = null;
+ Artifact executableForRunfiles = null;
if (createExecutable) {
- executable = ruleContext.createOutputArtifact(); // the artifact for the rule itself
- filesBuilder.add(classJar).add(executable);
+ // This artifact is named as the rule itself, e.g. //foo:bar_bin -> bazel-bin/foo/bar_bin
+ executableForRunfiles = ruleContext.createOutputArtifact();
+ filesBuilder.add(classJar).add(executableForRunfiles);
if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
- mainClass = semantics.addCoverageSupport(helper, attributesBuilder,
- executable, instrumentationMetadata, javaArtifactsBuilder, mainClass);
+ mainClass =
+ semantics.addCoverageSupport(
+ helper,
+ attributesBuilder,
+ executableForRunfiles,
+ instrumentationMetadata,
+ javaArtifactsBuilder,
+ mainClass);
}
} else {
filesBuilder.add(classJar);
@@ -226,20 +233,20 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
return null;
}
+ Artifact executableToRun = executableForRunfiles;
if (createExecutable) {
// Create a shell stub for a Java application
- Artifact newExecutable =
+ executableToRun =
semantics.createStubAction(
ruleContext,
common,
jvmFlags,
- executable,
+ executableForRunfiles,
mainClass,
JavaCommon.getJavaBinSubstitution(ruleContext, launcher));
- if (!newExecutable.equals(executable)) {
- filesBuilder.add(newExecutable);
- runfilesBuilder.addArtifact(newExecutable);
- executable = newExecutable;
+ if (!executableToRun.equals(executableForRunfiles)) {
+ filesBuilder.add(executableToRun);
+ runfilesBuilder.addArtifact(executableToRun);
}
}
@@ -297,8 +304,14 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
// otherwise, set classpath to deploy jar.
extraArgs.add("--wrapper_script_flag=--singlejar");
}
+ // The executable we pass here will be used when creating the runfiles directory. E.g. for the
+ // stub script called bazel-bin/foo/bar_bin, the runfiles directory will be created under
+ // bazel-bin/foo/bar_bin.runfiles . On platforms where there's an extra stub script (Windows)
+ // which dispatches to this one, we still create the runfiles directory for the shell script,
+ // but use the dispatcher script (a batch file) as the RunfilesProvider's executable.
runfilesSupport =
- RunfilesSupport.withExecutable(ruleContext, defaultRunfiles, executable, extraArgs);
+ RunfilesSupport.withExecutable(
+ ruleContext, defaultRunfiles, executableForRunfiles, extraArgs);
}
RunfilesProvider runfilesProvider = RunfilesProvider.withData(
@@ -364,7 +377,11 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
.setFilesToBuild(filesToBuild)
.add(JavaRuleOutputJarsProvider.class, javaRuleOutputJarsProviderBuilder.build())
.add(RunfilesProvider.class, runfilesProvider)
- .setRunfilesSupport(runfilesSupport, executable)
+ // The executable to run (below) may be different from the executable for runfiles (the one
+ // we create the runfiles support object with). On Linux they are the same (it's the same
+ // shell script), on Windows they are different (the executable to run is a batch file, the
+ // executable for runfiles is the shell script).
+ .setRunfilesSupport(runfilesSupport, executableToRun)
.add(
JavaRuntimeClasspathProvider.class,
new JavaRuntimeClasspathProvider(common.getRuntimeClasspath()))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
index 10a59d2a6c..b1b72dcea6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java
@@ -256,8 +256,12 @@ public interface JavaSemantics {
* Creates the action that writes the Java executable stub script.
*
* <p>Returns the launcher script artifact. This may or may not be the same as {@code executable},
- * depending on the implementation of this method. If they are different, the returned value
- * should be used as the stub script instead of the input {@code executable}.
+ * depending on the implementation of this method. If they are the same, then this Artifact should
+ * be used when creating both the {@code RunfilesProvider} and the {@code RunfilesSupport}. If
+ * they are different, the new value should be used when creating the {@code RunfilesProvider} (so
+ * it will be the stub script executed by "bazel run" for example), and the old value should be
+ * used when creasting the {@code RunfilesSupport} (so the runfiles directory will be named after
+ * it).
*
* <p>For example on Windows we use a double dispatch approach: the launcher is a batch file (and
* is created and returned by this method) which shells out to a shell script (the {@code