aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar Yun Peng <pcloudy@google.com>2017-08-04 10:02:53 +0200
committerGravatar Dmitry Lomov <dslomov@google.com>2017-08-04 17:16:24 +0200
commit7e4fbbe4ab3915a57b2187408c3909e5cd6c6013 (patch)
treeb8e2c36553ca79e0035e2f701d3499c602dd8e9d /src/main/java/com/google/devtools
parent0d659c0dd219ae6a73689f4431d2432bc2025ec7 (diff)
Add --windows_exe_launcher option
If this is enabled, Bazel will build a Windows native exe binary launcher for sh_binary, in the future this flag will also apply to py_binary and java_binary. By default, it's turned ON, set --windows_exe_launcher=0 to turn it off. Fix https://github.com/bazelbuild/bazel/issues/3491 Change-Id: Ic55bff745670446e585e3cc62af9dc6561527d4f PiperOrigin-RevId: 164234552
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD1
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java62
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/sh/sh_stub_template_windows.txt35
4 files changed, 97 insertions, 17 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index fb1870b6e8..f17579cdfa 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -734,6 +734,7 @@ java_library(
"bazel/rules/java/java_stub_template.txt",
"bazel/rules/java/java_stub_template_windows.txt",
"bazel/rules/python/python_stub_template.txt",
+ "bazel/rules/sh/sh_stub_template_windows.txt",
],
deps = [
":bazel",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 106a066666..a96156aa42 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -1129,6 +1129,17 @@ public final class BuildConfiguration implements BuildEvent {
)
public TriState buildPythonZip;
+ @Option(
+ name = "windows_exe_launcher",
+ defaultValue = "true",
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ help =
+ "Build a Windows exe launcher for sh_binary rule, "
+ + "it has no effect on other platforms than Windows"
+ )
+ public boolean windowsExeLauncher;
+
@Override
public FragmentOptions getHost(boolean fallback) {
Options host = (Options) getDefault();
@@ -1139,6 +1150,7 @@ public final class BuildConfiguration implements BuildEvent {
host.useDynamicConfigurations = useDynamicConfigurations;
host.enableRunfiles = enableRunfiles;
host.buildPythonZip = buildPythonZip;
+ host.windowsExeLauncher = windowsExeLauncher;
host.commandLineBuildVariables = commandLineBuildVariables;
host.enforceConstraints = enforceConstraints;
host.separateGenfilesDirectory = separateGenfilesDirectory;
@@ -2711,6 +2723,10 @@ public final class BuildConfiguration implements BuildEvent {
}
}
+ public boolean enableWindowsExeLauncher() {
+ return options.windowsExeLauncher;
+ }
+
/**
* Collects executables defined by fragments.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
index 0b3d37dfd3..f264df8d49 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/ShBinary.java
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.bazel.rules.sh;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteSource;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -29,6 +28,9 @@ import com.google.devtools.build.lib.analysis.RunfilesSupport;
import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.ExecutableSymlinkAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
+import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction;
+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.bazel.rules.BazelConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
@@ -43,6 +45,8 @@ import java.nio.ByteOrder;
* Implementation for the sh_binary rule.
*/
public class ShBinary implements RuleConfiguredTargetFactory {
+ private static final Template STUB_SCRIPT_WINDOWS =
+ Template.forResource(ShBinary.class, "sh_stub_template_windows.txt");
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws RuleErrorException {
@@ -114,21 +118,8 @@ public class ShBinary implements RuleConfiguredTargetFactory {
|| artifact.getExtension().equals("bat");
}
- private static Artifact launcherForWindows(
- RuleContext ruleContext, Artifact primaryOutput, Artifact mainFile)
+ private static Artifact createWindowsExeLauncher(RuleContext ruleContext, Artifact mainFile)
throws RuleErrorException {
- if (isWindowsExecutable(mainFile)) {
- // If the extensions don't match, we should always respect mainFile's extension.
- if (mainFile.getExtension().equals(primaryOutput.getExtension())) {
- return primaryOutput;
- } else {
- ruleContext.ruleError(
- "Source file is a Windows executable file,"
- + " target name extension should match source file extension");
- throw new RuleErrorException();
- }
- }
-
// The launcher file consists of a base launcher binary and the launch information appended to
// the binary. The length of launch info is a signed 64-bit integer written at the end of
// the binary in little endian.
@@ -170,7 +161,7 @@ public class ShBinary implements RuleConfiguredTargetFactory {
launchInfoFile,
ByteSource.wrap(launchInfo.toByteArray()),
/*makeExecutable=*/ false));
- String path = ruleContext.getConfiguration().getActionEnvironment().getFixedEnv().get("PATH");
+
ruleContext.registerAction(
new SpawnAction.Builder()
.addInput(launcher)
@@ -184,10 +175,47 @@ public class ShBinary implements RuleConfiguredTargetFactory {
+ " "
+ bashLauncher.getExecPathString().replace('/', '\\')
+ " > nul\"")
- .setEnvironment(ImmutableMap.of("PATH", path))
+ .useDefaultShellEnvironment()
.setMnemonic("BuildBashLauncher")
.build(ruleContext));
return bashLauncher;
}
+
+ private static Artifact launcherForWindows(
+ RuleContext ruleContext, Artifact primaryOutput, Artifact mainFile)
+ throws RuleErrorException {
+ if (isWindowsExecutable(mainFile)) {
+ if (mainFile.getExtension().equals(primaryOutput.getExtension())) {
+ return primaryOutput;
+ } else {
+ // If the extensions don't match, we should always respect mainFile's extension.
+ ruleContext.ruleError(
+ "Source file is a Windows executable file,"
+ + " target name extension should match source file extension");
+ throw new RuleErrorException();
+ }
+ }
+
+ if (ruleContext.getConfiguration().enableWindowsExeLauncher()) {
+ return createWindowsExeLauncher(ruleContext, mainFile);
+ }
+
+ Artifact wrapper =
+ ruleContext.getImplicitOutputArtifact(ruleContext.getTarget().getName() + ".cmd");
+ ruleContext.registerAction(
+ new TemplateExpansionAction(
+ ruleContext.getActionOwner(),
+ wrapper,
+ STUB_SCRIPT_WINDOWS,
+ ImmutableList.of(
+ Substitution.of(
+ "%bash_exe_path%",
+ ruleContext
+ .getFragment(BazelConfiguration.class)
+ .getShellExecutable()
+ .getPathString())),
+ true));
+ return wrapper;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/sh_stub_template_windows.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/sh_stub_template_windows.txt
new file mode 100644
index 0000000000..175985fac6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/sh/sh_stub_template_windows.txt
@@ -0,0 +1,35 @@
+@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 sh_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.
+
+@echo off
+SETLOCAL ENABLEEXTENSIONS
+
+set bash_path=%bash_exe_path%
+
+rem launcher=${$0%.cmd}
+set launcher=%~dp0%~n0
+
+set sh_path=%launcher:\=/%
+
+set RUNFILES_MANIFEST_ONLY=1
+set RUNFILES_MANIFEST_FILE=%sh_path%.runfiles/MANIFEST
+set all_args=%*
+rem replaces $ with \$ in $*, then puts it on the command line
+rem Cribbed from here: http://ss64.com/nt/syntax-replace.html
+call %bash_path% -c "'%sh_path%' %all_args:$=\$%"