97 lines
4.2 KiB
Python
97 lines
4.2 KiB
Python
# Copyright 2019 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.
|
|
|
|
"""
|
|
run_binary() build rule implementation.
|
|
|
|
Runs a binary as a build action. This rule does not require Bash (unlike native.genrule()).
|
|
"""
|
|
|
|
load("//lib:dicts.bzl", "dicts")
|
|
|
|
def _run_binary_impl(ctx):
|
|
tool_as_list = [ctx.attr.tool]
|
|
args = [
|
|
# Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in args.
|
|
#
|
|
# To keep the rule simple, do not expand Make Variables (like *_binary.args usually would).
|
|
# (We can add this feature later if users ask for it.)
|
|
#
|
|
# Also for simple implementation and usage, do not Bash-tokenize the arguments. Without
|
|
# tokenization the user can write args=["a b"] to pass (a b) as one argument, but with
|
|
# tokenization they would have to write args=["'a b'"] or args=["a\\ b"]. There's no
|
|
# documented tokenization function anyway (as of 2019-05-21 ctx.tokenize exists but is
|
|
# undocumented, see https://github.com/bazelbuild/bazel/issues/8389).
|
|
ctx.expand_location(a, tool_as_list)
|
|
for a in ctx.attr.args
|
|
]
|
|
envs = {
|
|
# Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in the values.
|
|
k: ctx.expand_location(v, tool_as_list)
|
|
for k, v in ctx.attr.env.items()
|
|
}
|
|
ctx.actions.run(
|
|
outputs = ctx.outputs.outs,
|
|
inputs = ctx.files.srcs,
|
|
tools = [ctx.executable.tool],
|
|
executable = ctx.executable.tool,
|
|
arguments = args,
|
|
mnemonic = "RunBinary",
|
|
use_default_shell_env = False,
|
|
env = dicts.add(ctx.configuration.default_shell_env, envs),
|
|
)
|
|
return DefaultInfo(
|
|
files = depset(ctx.outputs.outs),
|
|
runfiles = ctx.runfiles(files = ctx.outputs.outs),
|
|
)
|
|
|
|
run_binary = rule(
|
|
implementation = _run_binary_impl,
|
|
doc = "Runs a binary as a build action.\n\nThis rule does not require Bash (unlike" +
|
|
" `native.genrule`).",
|
|
attrs = {
|
|
"tool": attr.label(
|
|
doc = "The tool to run in the action.\n\nMust be the label of a *_binary rule," +
|
|
" of a rule that generates an executable file, or of a file that can be" +
|
|
" executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary" +
|
|
" with executable permission on Linux). This label is available for" +
|
|
" `$(execpath)` and `$(location)` expansion in `args` and `env`.",
|
|
executable = True,
|
|
allow_files = True,
|
|
mandatory = True,
|
|
cfg = "exec",
|
|
),
|
|
"env": attr.string_dict(
|
|
doc = "Environment variables of the action.\n\nSubject to " +
|
|
" [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
|
|
" expansion.",
|
|
),
|
|
"srcs": attr.label_list(
|
|
allow_files = True,
|
|
doc = "Additional inputs of the action.\n\nThese labels are available for" +
|
|
" `$(execpath)` and `$(location)` expansion in `args` and `env`.",
|
|
),
|
|
"outs": attr.output_list(
|
|
mandatory = True,
|
|
doc = "Output files generated by the action.\n\nThese labels are available for" +
|
|
" `$(execpath)` and `$(location)` expansion in `args` and `env`.",
|
|
),
|
|
"args": attr.string_list(
|
|
doc = "Command line arguments of the binary.\n\nSubject to" +
|
|
" [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
|
|
" expansion.",
|
|
),
|
|
},
|
|
)
|