Skip to content

Support passing arguments to run_binary via param file #492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/run_binary_doc.md
Original file line number Diff line number Diff line change
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-param_file_format">param_file_format</a>, <a href="#run_binary-srcs">srcs</a>, <a href="#run_binary-tool">tool</a>)
</pre>

Runs a binary as a build action.
Expand All @@ -27,6 +27,7 @@ This rule does not require Bash (unlike `native.genrule`).
| <a id="run_binary-args"></a>args | Command line arguments of the binary.<br><br>Subject to [<code>$(location)</code>](https://bazel.build/reference/be/make-variables#predefined_label_variables) expansion. | List of strings | optional | <code>[]</code> |
| <a id="run_binary-env"></a>env | Environment variables of the action.<br><br>Subject to [<code>$(location)</code>](https://bazel.build/reference/be/make-variables#predefined_label_variables) expansion. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | optional | <code>{}</code> |
| <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-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 [<code>Args.param_file_arg</code>](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. | String | optional | <code>""</code> |
| <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 | |

Expand Down
23 changes: 18 additions & 5 deletions rules/run_binary.bzl
Original file line number Diff line number Diff line change
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.\n\n" +
"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 [`Args.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 = "",
),
Comment on lines +100 to +107
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had hard time understanding this and I needed to open Bazel's documentation. Although I used the functionality before.

I'd suggest just pasting the Bazel's doc here. Maybe adding that param files are only used if the attribute is set.

A format string with a single "%s". If the args are spilled to a params file then they are replaced with an argument consisting of this string formatted with the path of the params file.
For example, if the args are spilled to a params file "params.txt", then specifying "--file=%s" would cause the action command line to contain "--file=params.txt".

},
)