blob: c64fafde2494e021d099747dd6bf91664f0eae95 [file] [log] [blame]
# Copyright (C) 2024 The Android Open Source Project
#
# 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.
"""`bison` wrapper.
Caveat: Do not use native_binary or ctx.actions.symlink() to wrap this binary
due to the use of $0.
"""
load("@bazel_skylib//lib:paths.bzl", "paths")
visibility("//build/kernel/...")
def _bison_wrapper_impl(ctx):
file = ctx.actions.declare_file("{}/bison".format(ctx.attr.name))
root_from_base = "/".join([".."] * len(paths.dirname(file.path).split("/")))
content = """\
#!/bin/sh
# We don't use any tools in this script. Prevent using host tools.
PATH=
if [ -n "${{BUILD_WORKSPACE_DIRECTORY}}" ] || [ "${{BAZEL_TEST}}" = "1" ]; then
export RUNFILES_DIR=${{RUNFILES_DIR:-${{0}}.runfiles}}
ACTUAL=${{RUNFILES_DIR}}/{workspace_name}/{actual_short}
export BISON_PKGDATADIR=${{RUNFILES_DIR}}/{workspace_name}/{pkgdata_dir_short}
export M4=${{RUNFILES_DIR}}/{workspace_name}/{m4_short}
else
KLEAF_REPO_DIR=${{0%/*}}/{root_from_base}
ACTUAL=${{KLEAF_REPO_DIR}}/{actual}
export BISON_PKGDATADIR=${{KLEAF_REPO_DIR}}/{pkgdata_dir}
export M4=${{KLEAF_REPO_DIR}}/{m4}
fi
if [ ! -x "${{M4}}" ]; then
echo "ERROR: m4 is not found at ${{M4}}" >&2
exit 1
fi
if [ ! -d "${{BISON_PKGDATADIR}}" ]; then
echo "ERROR: BISON_PKGDATADIR ${{BISON_PKGDATADIR}} is empty!" >&2
exit 1
fi
"${{ACTUAL}}" $*
""".format(
# https://bazel.build/extending/rules#runfiles_location
# The recommended way to detect launcher_path is use $0.
# From man sh: If bash is invoked with a file of commands, $0 is set to the name of that
# file.
workspace_name = ctx.workspace_name,
root_from_base = root_from_base,
pkgdata_dir = ctx.file.pkgdata_dir.path,
actual = ctx.executable.actual.path,
m4 = ctx.executable.m4.path,
pkgdata_dir_short = ctx.file.pkgdata_dir.short_path,
actual_short = ctx.executable.actual.short_path,
m4_short = ctx.executable.m4.short_path,
)
ctx.actions.write(file, content, is_executable = True)
return DefaultInfo(
files = depset([file]),
runfiles = ctx.runfiles(
files = [ctx.executable.actual],
transitive_files = ctx.attr.pkgdata_files.files,
).merge_all([
ctx.attr.actual[DefaultInfo].default_runfiles,
ctx.attr.m4[DefaultInfo].default_runfiles,
]),
executable = file,
)
bison_wrapper = rule(
implementation = _bison_wrapper_impl,
doc = """Creates a wrapper script over real `bison` binary.
Caveat: Do not use native_binary or ctx.actions.symlink() to wrap this binary
due to the use of $0.
""",
attrs = {
"actual": attr.label(
allow_files = True,
executable = True,
# Don't apply transitions; let hermetic_tools handle it.
cfg = "target",
),
"pkgdata_dir": attr.label(allow_single_file = True),
"pkgdata_files": attr.label(allow_files = True),
"m4": attr.label(
executable = True,
# Don't apply transitions; let hermetic_tools handle it.
cfg = "target",
),
},
executable = True,
)