diff options
author | 2018-04-16 05:11:38 -0700 | |
---|---|---|
committer | 2018-04-16 05:13:15 -0700 | |
commit | 81ed3add408adb20bddbc3ba1818c65806738dc5 (patch) | |
tree | 885208ea7cf7da2b7091375f0d122fcd1e34488f /tools/sh | |
parent | ecbab79b7bc982e5b60b09203607ab6a4d066294 (diff) |
bash: Add a toolchain for local Bash.
Bazel automatically detects the local Bash and
creates a custom toolchain rule for it.
Later, rules that use Bash will require this
toolchain and retrieve Bash's path from it instead
of relying on hardcoded paths or the
`--shell_executable` flag.
See https://github.com/bazelbuild/bazel/issues/4319
Change-Id: Idd8242a20d202b1f5a56cddac95b625c6c08ede9
Closes #4980.
Change-Id: Ic2406a4da260b284e15852070d58472ca18340af
PiperOrigin-RevId: 193022708
Diffstat (limited to 'tools/sh')
-rw-r--r-- | tools/sh/BUILD | 23 | ||||
-rw-r--r-- | tools/sh/BUILD.tools | 6 | ||||
-rw-r--r-- | tools/sh/sh_configure.bzl | 94 | ||||
-rw-r--r-- | tools/sh/sh_toolchain.bzl | 26 |
4 files changed, 149 insertions, 0 deletions
diff --git a/tools/sh/BUILD b/tools/sh/BUILD new file mode 100644 index 0000000000..66f710a926 --- /dev/null +++ b/tools/sh/BUILD @@ -0,0 +1,23 @@ +package(default_visibility = ["//visibility:private"]) + +filegroup( + name = "srcs", + srcs = glob( + ["**"], + exclude = [ + "*~", + ".*", + ], + ), + visibility = ["//tools:__pkg__"], +) + +filegroup( + name = "embedded_tools", + srcs = [ + "BUILD.tools", + "sh_configure.bzl", + "sh_toolchain.bzl", + ], + visibility = ["//tools:__pkg__"], +) diff --git a/tools/sh/BUILD.tools b/tools/sh/BUILD.tools new file mode 100644 index 0000000000..d5d9d4896a --- /dev/null +++ b/tools/sh/BUILD.tools @@ -0,0 +1,6 @@ +exports_files(["sh_toolchain.bzl", "sh_configure.bzl"]) + +toolchain_type( + name = "toolchain_type", + visibility = ["//visibility:public"], +) diff --git a/tools/sh/sh_configure.bzl b/tools/sh/sh_configure.bzl new file mode 100644 index 0000000000..7ba056c6cb --- /dev/null +++ b/tools/sh/sh_configure.bzl @@ -0,0 +1,94 @@ +# Copyright 2018 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Configure the shell toolchain on the local machine.""" + +def _is_windows(repository_ctx): + """Returns true if the host OS is Windows.""" + return repository_ctx.os.name.startswith("windows") + +def _sh_config_impl(repository_ctx): + """sh_config rule implementation. + + Detects the path of the shell interpreter on the local machine and + stores it in a sh_toolchain rule. + + Args: + repository_ctx: the repository rule context object + """ + sh_path = repository_ctx.os.environ.get("BAZEL_SH") + if not sh_path: + if _is_windows(repository_ctx): + sh_path = repository_ctx.which("bash.exe") + if sh_path: + # When the Windows Subsystem for Linux is installed there's a + # bash.exe under %WINDIR%\system32\bash.exe that launches Ubuntu + # Bash which cannot run native Windows programs so it's not what + # we want. + windir = repository_ctx.os.environ.get("WINDIR") + if windir and sh_path.startswith(windir): + sh_path = None + else: + sh_path = repository_ctx.which("bash") + if not sh_path: + sh_path = repository_ctx.which("sh") + + if not sh_path: + sh_path = "" + + if sh_path and _is_windows(repository_ctx): + sh_path = sh_path.replace("\\", "/") + + os_label = None + if _is_windows(repository_ctx): + os_label = "@bazel_tools//platforms:windows" + elif repository_ctx.os.name.startswith("linux"): + os_label = "@bazel_tools//platforms:linux" + elif repository_ctx.os.name.startswith("mac"): + os_label = "@bazel_tools//platforms:osx" + else: + fail("Unknown OS") + + repository_ctx.file("BUILD", """ +load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain") + +sh_toolchain( + name = "local_sh", + path = "{sh_path}", + visibility = ["//visibility:public"], +) + +toolchain( + name = "local_sh_toolchain", + exec_compatible_with = [ + "@bazel_tools//platforms:x86_64", + "{os_label}", + ], + toolchain = ":local_sh", + toolchain_type = "@bazel_tools//tools/sh:toolchain_type", +) +""".format(sh_path = sh_path, os_label = os_label)) + +sh_config = repository_rule( + environ = [ + "WINDIR", + "PATH", + ], + local = True, + implementation = _sh_config_impl, +) + +def sh_configure(): + """Detect the local shell interpreter and register its toolchain.""" + sh_config(name = "local_config_sh") + native.register_toolchains("@local_config_sh//:local_sh_toolchain") diff --git a/tools/sh/sh_toolchain.bzl b/tools/sh/sh_toolchain.bzl new file mode 100644 index 0000000000..ddd7de7980 --- /dev/null +++ b/tools/sh/sh_toolchain.bzl @@ -0,0 +1,26 @@ +# Copyright 2018 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Define a toolchain rule for the shell.""" + +def _sh_toolchain_impl(ctx): + """sh_toolchain rule implementation.""" + return [platform_common.ToolchainInfo(path = ctx.attr.path)] + +sh_toolchain = rule( + attrs = { + # Absolute path to the shell interpreter. + "path": attr.string(), + }, + implementation = _sh_toolchain_impl, +) |