Skip to content

Commit

Permalink
bash: Add a toolchain for local Bash.
Browse files Browse the repository at this point in the history
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 bazelbuild#4319

Change-Id: Idd8242a20d202b1f5a56cddac95b625c6c08ede9
  • Loading branch information
laszlocsomor committed Apr 12, 2018
1 parent 4087bc0 commit 64b3270
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
local_repository(name = "bazel_tools", path = __embedded_dir__ + "/embedded_tools")
bind(name = "cc_toolchain", actual = "@bazel_tools//tools/cpp:default-toolchain")
bind(name = "java_toolchain", actual = "%java_toolchain%")

load("@bazel_tools//tools/bash:bash_def.bzl", "bash_repositories")
bash_repositories()
6 changes: 5 additions & 1 deletion tools/bash/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ filegroup(

filegroup(
name = "embedded_tools",
srcs = ["//tools/bash/runfiles:embedded_tools"],
srcs = [
"BUILD.tools",
"bash_def.bzl",
"//tools/bash/runfiles:embedded_tools",
],
visibility = ["//tools:__pkg__"],
)
6 changes: 6 additions & 0 deletions tools/bash/BUILD.tools
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
exports_files(["bash_def.bzl"])

toolchain_type(
name = "bash_toolchain_type",
visibility = ["//visibility:public"],
)
75 changes: 75 additions & 0 deletions tools/bash/bash_def.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
def _bash_toolchain_impl(ctx):
return [platform_common.ToolchainInfo(path = ctx.attr.path)]

def _is_windows(repository_ctx):
return repository_ctx.os.name.startswith("windows")

def _bash_config_impl(repository_ctx):
bash_path = repository_ctx.os.environ.get("BAZEL_SH")
if not bash_path:
if _is_windows(repository_ctx):
bash_path = repository_ctx.which("bash.exe")
if bash_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 bash_path.startswith(windir):
bash_path = None
else:
bash_path = repository_ctx.which("bash")

if not bash_path:
bash_path = ""

if bash_path and _is_windows(repository_ctx):
bash_path = bash_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/bash:bash_def.bzl", "bash_toolchain")
bash_toolchain(
name = "local_bash",
path = "{bash_path}",
visibility = ["//visibility:public"],
)
toolchain(
name = "local_bash_toolchain",
exec_compatible_with = [
"@bazel_tools//platforms:x86_64",
"{os_label}",
],
toolchain = ":local_bash",
toolchain_type = "@bazel_tools//tools/bash:bash_toolchain_type",
)
""".format(bash_path = bash_path, os_label = os_label))

bash_toolchain = rule(
attrs = {"path": attr.string()},
implementation = _bash_toolchain_impl,
)

bash_config = repository_rule(
environ = [
"WINDIR",
"PATH",
],
local = True,
implementation = _bash_config_impl,
)

def bash_repositories():
"""Detect the local Bash and register it as a toolchain."""
bash_config(name = "local_config_bash")
native.register_toolchains("@local_config_bash//:local_bash_toolchain")

0 comments on commit 64b3270

Please sign in to comment.