diff options
author | 2016-10-31 16:08:27 +0000 | |
---|---|---|
committer | 2016-10-31 16:42:22 +0000 | |
commit | 775dc683615d466b565a195abc30b09d90320eb7 (patch) | |
tree | a11e79c3c730dd4a2c3450bdda4ff40e62724b10 /src/main/java/com | |
parent | 2dd4c183294b46a2509aef395596d39a17b7536f (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')
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); /** |