Skip to content

Commit

Permalink
build: Add an install target.
Browse files Browse the repository at this point in the history
Adds a bazel rule that mimics the GNU Makefile standard.

https://www.gnu.org/prep/standards/html_node/Standard-Targets.html
  • Loading branch information
jaqx0r committed Apr 9, 2024
1 parent afb9c6a commit 215f19d
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 6 deletions.
23 changes: 21 additions & 2 deletions BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@buildifier_prebuilt//:rules.bzl", "buildifier")
load("//:install.bzl", "install")
load("//:subst.bzl", "subst_template")

package(default_visibility = [":__subpackages__"])
Expand Down Expand Up @@ -67,15 +68,16 @@ cc_binary(
)

SUBSTITUTIONS = {
"@sysconfdir@": "/etc",
"@pkgexdir@": "/usr/share/doc/filergen/examples",
"@sysconfdir@": "/etc/filtergen",
"@pkgexdir@": "/usr/share/doc/filtergen/examples",
"@sbindir@": "/usr/sbin",
"@VERSION@": VERSION,
}

subst_template(
name = "fgadm",
src = "fgadm.in",
executable = True,
substitutions = SUBSTITUTIONS,
)

Expand All @@ -97,6 +99,23 @@ subst_template(
substitutions = SUBSTITUTIONS,
)

install(
name = "install",
prefix = "/home/jaq/fgbin",
targets = {
":fgadm": "/sbin",
":filtergen": "/sbin",
":fgadm.conf": "/etc/filtergen",
":rules.filter": "/etc/filtergen",
"filter_syntax.5": "/man/man5",
"filter_backends.7": "/man/man7",
"filtergen.8": "/man/man8",
"fgadm.8": "/man/man8",
"//examples:examples": "/doc/filtergen/examples",
"//doc:doc": "/doc/filtergen",
},
)

buildifier(
name = "buildifier",
exclude_patterns = [
Expand Down
8 changes: 8 additions & 0 deletions doc/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
filegroup(
name = "doc",
srcs = glob(
["*"],
exclude = ["BUILD"],
),
visibility = ["//:__pkg__"],
)
5 changes: 4 additions & 1 deletion examples/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
filegroup(
name = "examples",
srcs = glob(["*.filter"]),
visibility = ["//testsuite/filtergen:__pkg__"],
visibility = [
"//:__pkg__",
"//testsuite/filtergen:__pkg__",
],
)
78 changes: 78 additions & 0 deletions install.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""Install rules.
Based on the GNU Makefile standard targets: https://www.gnu.org/prep/standards/html_node/Standard-Targets.html
"""

def _install_impl(ctx):
"""Install some targets somewhere in the filesystem."""

# Like https://www.gnu.org/prep/standards/html_node/DESTDIR.html#DESTDIR
output = ctx.actions.declare_file("install_script")
commands = "#!/usr/bin/env bash\nexport RUNFILES_LIB_DEBUG=1\ncat $0\n" + RUNFILES_BOILERPLATE
runfiles = ctx.runfiles(files = [ctx.file._bash_runfile_helper])
for target in ctx.attr.targets:
print(target)
target_dir = ctx.attr.prefix + ctx.attr.targets.get(target)
commands += "install -d {}\n".format(target_dir)
mode = "-m 644"

# Like https://www.gnu.org/prep/standards/html_node/Command-Variables.html#Command-Variables
if target[DefaultInfo].files_to_run and target[DefaultInfo].files_to_run.executable:
mode = ""
print(target, target[DefaultInfo].files.to_list())
installables = ["$(rlocation _main/{})".format(x.short_path) for x in target[DefaultInfo].files.to_list()]
commands += "install {mode} {target} {dest}\n".format(mode = mode, target = " ".join(installables), dest = target_dir)
runfiles = runfiles.merge_all([
target[DefaultInfo].default_runfiles,
ctx.runfiles(target[DefaultInfo].files.to_list()),
])
ctx.actions.write(
output = output,
is_executable = True,
content = commands,
)
return [
DefaultInfo(
executable = output,
runfiles = runfiles,
),
]

RUNFILES_BOILERPLATE = """
# --- begin runfiles.bash initialization v3 ---
# Copy-pasted from the Bazel Bash runfiles library v3.
set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v3 ---
"""

install = rule(
implementation = _install_impl,
doc = "Install some targets to the filesystem.",
attrs = {
"srcs": attr.label_list(
allow_files = True,
),
"prefix": attr.string(
default = "/usr/local",
doc = "Installation prefix directory, aka DESTDIR.",
),
"targets": attr.label_keyed_string_dict(
doc = "Installation targets of label:destination",
allow_files = True,
),
# Bazel ships with a useful bash function for querying the absolute path to runfiles at
# runtime.
"_bash_runfile_helper": attr.label(
default = "@bazel_tools//tools/bash/runfiles",
doc = "Label pointing to bash runfile helper",
allow_single_file = True,
),
},
executable = True,
)
23 changes: 20 additions & 3 deletions subst.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,22 @@ def _subst_template_impl(ctx):
output = output,
substitutions = ctx.attr.substitutions,
)
return [
DefaultInfo(files = depset([output])),
]
runfiles = ctx.runfiles(files = [output])
files = depset([output])
if ctx.attr.executable:
return [
DefaultInfo(
executable = output,
runfiles = runfiles,
),
]
else:
return [
DefaultInfo(
files = files,
runfiles = runfiles,
),
]

subst_template = rule(
implementation = _subst_template_impl,
Expand All @@ -23,5 +36,9 @@ subst_template = rule(
"substitutions": attr.string_dict(
doc = "Substitutions to apply to the template",
),
"executable": attr.bool(
default = False,
doc = "Set if the substitution is an executable.",
),
},
)

0 comments on commit 215f19d

Please sign in to comment.