aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Laszlo Csomor <laszlocsomor@google.com>2016-10-31 16:08:27 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2016-10-31 16:42:22 +0000
commit775dc683615d466b565a195abc30b09d90320eb7 (patch)
treea11e79c3c730dd4a2c3450bdda4ff40e62724b10 /src/main/java/com/google/devtools/build/lib
parent2dd4c183294b46a2509aef395596d39a17b7536f (diff)
Windows: java_binary can be an action executable
This change introduces a new output of java_binary on Windows: %{name}.cmd, a Windows-compatible Java launcher script. This simply calls out to bash.exe passing the shell launcher we use on other platforms. This change allows java_binary to be the executable of a Skylark action or any SpawnAction. Fixes https://github.com/bazelbuild/bazel/issues/1925 RELNOTES[NEW]: Bazel on Windows: java_binary can now be a the executable of Skylark rule actions (ctx.action's executable argument) -- MOS_MIGRATED_REVID=137708331
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template_windows.txt31
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaBinary.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/java/JavaSemantics.java16
5 files changed, 96 insertions, 6 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index 1d3dcc97eb..901b0d9987 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -594,6 +594,7 @@ java_library(
srcs = glob(["bazel/*.java"]),
resources = [
"bazel/rules/java/java_stub_template.txt",
+ "bazel/rules/java/java_stub_template_windows.txt",
"bazel/rules/python/stub_template.txt",
],
deps = [
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
index c3c85e68ad..9fe7b81d71 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaSemantics.java
@@ -33,6 +33,7 @@ import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Co
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Template;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.bazel.rules.BazelConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.BuildType;
@@ -52,6 +53,7 @@ import com.google.devtools.build.lib.rules.java.JavaUtil;
import com.google.devtools.build.lib.rules.java.Jvm;
import com.google.devtools.build.lib.rules.java.proto.GeneratedExtensionRegistryProvider;
import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.lib.util.ShellEscaper;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -71,6 +73,8 @@ public class BazelJavaSemantics implements JavaSemantics {
private static final Template STUB_SCRIPT =
Template.forResource(BazelJavaSemantics.class, "java_stub_template.txt");
+ private static final Template STUB_SCRIPT_WINDOWS =
+ Template.forResource(BazelJavaSemantics.class, "java_stub_template_windows.txt");
private static final String JAVABUILDER_CLASS_NAME =
"com.google.devtools.build.buildjar.BazelJavaBuilder";
@@ -155,8 +159,12 @@ public class BazelJavaSemantics implements JavaSemantics {
}
@Override
- public void createStubAction(RuleContext ruleContext, final JavaCommon javaCommon,
- List<String> jvmFlags, Artifact executable, String javaStartClass,
+ public Artifact createStubAction(
+ RuleContext ruleContext,
+ final JavaCommon javaCommon,
+ List<String> jvmFlags,
+ Artifact executable,
+ String javaStartClass,
String javaExecutable) {
Preconditions.checkState(ruleContext.getConfiguration().hasFragment(Jvm.class));
@@ -195,6 +203,33 @@ public class BazelJavaSemantics implements JavaSemantics {
ruleContext.registerAction(new TemplateExpansionAction(
ruleContext.getActionOwner(), executable, STUB_SCRIPT, arguments, true));
+ if (OS.getCurrent() == OS.WINDOWS) {
+ Artifact newExecutable =
+ ruleContext.getImplicitOutputArtifact(ruleContext.getTarget().getName() + ".cmd");
+ ruleContext.registerAction(
+ new TemplateExpansionAction(
+ ruleContext.getActionOwner(),
+ newExecutable,
+ STUB_SCRIPT_WINDOWS,
+ ImmutableList.of(
+ Substitution.of(
+ "%bash_exe_path%",
+ ruleContext
+ .getFragment(BazelConfiguration.class)
+ .getShellExecutable()
+ .getPathString()),
+ Substitution.of(
+ "%cygpath_exe_path%",
+ ruleContext
+ .getFragment(BazelConfiguration.class)
+ .getShellExecutable()
+ .replaceName("cygpath.exe")
+ .getPathString())),
+ true));
+ return newExecutable;
+ } else {
+ return executable;
+ }
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template_windows.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template_windows.txt
new file mode 100644
index 0000000000..d3f47434bb
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/java_stub_template_windows.txt
@@ -0,0 +1,31 @@
+@rem Copyright 2016 The Bazel Authors. All rights reserved.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem This script was generated from java_stub_template_windows.txt. Please
+@rem don't edit it directly.
+@rem See the header comments in the accompanying shell script (same path as that
+@rem of this file, minus the ".cmd" extension) for available command line flags.
+
+@SETLOCAL ENABLEEXTENSIONS
+
+@set bash_path=%bash_exe_path%
+@set cygpath_path=%cygpath_exe_path%
+
+@rem launcher=${$0%.cmd}
+@set launcher=%~dp0%~n0
+
+@rem sh_path=$($cygpath_path -m $launcher)
+@for /f %%i in ('%cygpath_path% -m %launcher%') do @set sh_path=%%i
+
+@call %bash_path% -c "%sh_path% %*"
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 01de5495da..cd0173e777 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
@@ -228,8 +228,19 @@ public class JavaBinary implements RuleConfiguredTargetFactory {
if (createExecutable) {
// Create a shell stub for a Java application
- semantics.createStubAction(ruleContext, common, jvmFlags, executable, mainClass,
- JavaCommon.getJavaBinSubstitution(ruleContext, launcher));
+ Artifact newExecutable =
+ semantics.createStubAction(
+ ruleContext,
+ common,
+ jvmFlags,
+ executable,
+ mainClass,
+ JavaCommon.getJavaBinSubstitution(ruleContext, launcher));
+ if (!newExecutable.equals(executable)) {
+ filesBuilder.add(newExecutable);
+ runfilesBuilder.addArtifact(newExecutable);
+ executable = newExecutable;
+ }
}
JavaSourceJarsProvider javaSourceJarsProvider = javaSourceJarsProviderBuilder.build();
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 8f3be1af11..10a59d2a6c 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
@@ -254,9 +254,21 @@ 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}.
+ *
+ * <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
+ * executable} argument).
*/
- void createStubAction(RuleContext ruleContext, final JavaCommon javaCommon,
- List<String> jvmFlags, Artifact executable, String javaStartClass,
+ Artifact createStubAction(
+ RuleContext ruleContext,
+ final JavaCommon javaCommon,
+ List<String> jvmFlags,
+ Artifact executable,
+ String javaStartClass,
String javaExecutable);
/**