Skip to content

Commit

Permalink
Support passing arguments to run_binary via param file
Browse files Browse the repository at this point in the history
Allows to use run_binary in the case when the size of the command line
can grow longer than the maximum size allowed by the system.
  • Loading branch information
vejbomar committed Mar 14, 2024
1 parent e60cf00 commit e59f67b
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 6 deletions.
3 changes: 2 additions & 1 deletion docs/run_binary_doc.md
Expand Up @@ -11,7 +11,7 @@ Runs a binary as a build action. This rule does not require Bash (unlike native.
## run_binary

<pre>
run_binary(<a href="#run_binary-name">name</a>, <a href="#run_binary-args">args</a>, <a href="#run_binary-env">env</a>, <a href="#run_binary-outs">outs</a>, <a href="#run_binary-srcs">srcs</a>, <a href="#run_binary-tool">tool</a>)
run_binary(<a href="#run_binary-name">name</a>, <a href="#run_binary-args">args</a>, <a href="#run_binary-env">env</a>, <a href="#run_binary-outs">outs</a>, <a href="#run_binary-srcs">srcs</a>, <a href="#run_binary-tool">tool</a>, <a href="#run_binary-param_file_format">param_file_format</a>)
</pre>

Runs a binary as a build action.
Expand All @@ -29,5 +29,6 @@ This rule does not require Bash (unlike `native.genrule`).
| <a id="run_binary-outs"></a>outs | Output files generated by the action.<br><br>These labels are available for <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | List of labels | required | |
| <a id="run_binary-srcs"></a>srcs | Additional inputs of the action.<br><br>These labels are available for <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | <code>[]</code> |
| <a id="run_binary-tool"></a>tool | The tool to run in the action.<br><br>Must 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 <code>$(location)</code> expansion in <code>args</code> and <code>env</code>. | <a href="https://bazel.build/concepts/labels">Label</a> | required | |
| <a id="run_binary-param_file_format"></a>param_file_format | If provided, Bazel can pass command-line arguments to the tool via file.<br><br>Should be used when the size of the command line can grow longer than the maximum size allowed by the system. The format is the same as the format of <code>param_file_arg</code> in [`Args.use_param_file`](https://bazel.build/rules/lib/builtins/Args#use_param_file). The <code>tool</code> has to support reading arguments from the file for this to work. | <a href="https://bazel.build/rules/lib/string">String</a> | optional | <code>""</code> |


23 changes: 18 additions & 5 deletions rules/run_binary.bzl
Expand Up @@ -22,7 +22,13 @@ load("//lib:dicts.bzl", "dicts")

def _impl(ctx):
tool_as_list = [ctx.attr.tool]
args = [

args = ctx.actions.args()
if ctx.attr.param_file_format != "":
args.set_param_file_format("multiline")
args.use_param_file(param_file_arg = ctx.attr.param_file_format, use_always = False)

for arg in ctx.attr.args:
# Expand $(location) / $(locations) in args.
#
# To keep the rule simple, do not expand Make Variables (like *_binary.args usually would).
Expand All @@ -33,9 +39,8 @@ def _impl(ctx):
# 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) if "$(location" in a else a
for a in ctx.attr.args
]
args.add(ctx.expand_location(arg, tool_as_list) if "$(location" in arg else arg)

envs = {
# Expand $(location) / $(locations) in the values.
k: ctx.expand_location(v, tool_as_list) if "$(location" in v else v
Expand All @@ -46,7 +51,7 @@ def _impl(ctx):
inputs = ctx.files.srcs,
tools = [ctx.executable.tool],
executable = ctx.executable.tool,
arguments = args,
arguments = [args],
mnemonic = "RunBinary",
use_default_shell_env = False,
env = dicts.add(ctx.configuration.default_shell_env, envs),
Expand Down Expand Up @@ -92,5 +97,13 @@ run_binary = rule(
" [`$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
" expansion.",
),
"param_file_format": attr.string(
doc = "If provided, Bazel can pass command-line arguments to the tool via file. " +
"Should be used when the size of the command line can grow longer than the " +
"maximum size allowed by the system. The format is the same as the format of " +
"`param_file_arg` in [`param_file_arg`](https://bazel.build/rules/lib/builtins/Args#use_param_file). " +
"The `tool` has to support reading arguments from the file for this to work.",
default = "",
),
},
)

0 comments on commit e59f67b

Please sign in to comment.