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 #4319

Change-Id: Idd8242a20d202b1f5a56cddac95b625c6c08ede9

Closes #4980.

Change-Id: Ic2406a4da260b284e15852070d58472ca18340af
PiperOrigin-RevId: 193022708
  • Loading branch information
laszlocsomor authored and Copybara-Service committed Apr 16, 2018
1 parent ecbab79 commit 81ed3ad
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses;
import com.google.devtools.build.lib.bazel.rules.sh.BazelShRuleClasses;
import com.google.devtools.build.lib.rules.cpp.FdoSupportFunction;
import com.google.devtools.build.lib.rules.cpp.FdoSupportValue;
import com.google.devtools.build.lib.runtime.BlazeModule;
Expand All @@ -41,6 +42,8 @@ public void initializeRuleClasses(ConfiguredRuleClassProvider.Builder builder) {
ResourceFileLoader.loadResource(BazelCppRuleClasses.class, "cc_configure.WORKSPACE"));
builder.addWorkspaceFileSuffix(
ResourceFileLoader.loadResource(BazelRulesModule.class, "xcode_configure.WORKSPACE"));
builder.addWorkspaceFileSuffix(
ResourceFileLoader.loadResource(BazelShRuleClasses.class, "sh_configure.WORKSPACE"));
} catch (IOException e) {
throw new IllegalStateException(e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
load("@bazel_tools//tools/sh:sh_configure.bzl", "sh_configure")
sh_configure()
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ private void mockEmbeddedTools(Path embeddedBinaries) throws IOException {
tools.getRelative("tools/osx/xcode_configure.bzl"),
"def xcode_configure(*args, **kwargs):",
" pass");
FileSystemUtils.writeIsoLatin1(tools.getRelative("tools/sh/BUILD"), "");
FileSystemUtils.writeIsoLatin1(
tools.getRelative("tools/sh/sh_configure.bzl"),
"def sh_configure(*args, **kwargs):",
" pass");
}

private void fetchExternalRepo(RepositoryName externalRepo) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/shell/integration/discard_graph_edges_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ function test_packages_cleared() {
package_count="$(extract_histogram_count "$histo_file" \
'devtools\.build\.lib\..*\.Package$')"
# A few packages aren't cleared.
[[ "$package_count" -le 8 ]] \
[[ "$package_count" -le 10 ]] \
|| fail "package count $package_count too high"
glob_count="$(extract_histogram_count "$histo_file" "GlobValue$")"
[[ "$glob_count" -le 1 ]] \
Expand Down
2 changes: 2 additions & 0 deletions tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ filegroup(
"//tools/test:srcs",
"//tools/python:srcs",
"//tools/runfiles:srcs",
"//tools/sh:srcs",
"//tools/whitelists:srcs",
"//tools/zip:srcs",
],
Expand Down Expand Up @@ -62,6 +63,7 @@ filegroup(
"//tools/test:srcs",
"//tools/osx/crosstool:srcs",
"//tools/osx:srcs",
"//tools/sh:embedded_tools",
"//tools/whitelists:srcs",
"//tools/zip:srcs",
],
Expand Down
23 changes: 23 additions & 0 deletions tools/sh/BUILD
Original file line number Diff line number Diff line change
@@ -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__"],
)
6 changes: 6 additions & 0 deletions tools/sh/BUILD.tools
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
exports_files(["sh_toolchain.bzl", "sh_configure.bzl"])

toolchain_type(
name = "toolchain_type",
visibility = ["//visibility:public"],
)
94 changes: 94 additions & 0 deletions tools/sh/sh_configure.bzl
Original file line number Diff line number Diff line change
@@ -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")
26 changes: 26 additions & 0 deletions tools/sh/sh_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -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,
)

0 comments on commit 81ed3ad

Please sign in to comment.