diff --git a/docs/run_binary_doc.md b/docs/run_binary_doc.md index 50b62e40..0d519d53 100755 --- a/docs/run_binary_doc.md +++ b/docs/run_binary_doc.md @@ -11,7 +11,7 @@ Runs a binary as a build action. This rule does not require Bash (unlike native. ## run_binary
-run_binary(name, args, env, outs, srcs, tool)
+run_binary(name, args, env, outs, srcs, tool, param_file_format)
 
Runs a binary as a build action. @@ -29,5 +29,6 @@ This rule does not require Bash (unlike `native.genrule`). | outs | Output files generated by the action.

These labels are available for $(location) expansion in args and env. | List of labels | required | | | srcs | Additional inputs of the action.

These labels are available for $(location) expansion in args and env. | List of labels | optional | [] | | tool | The tool to run in the action.

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 $(location) expansion in args and env. | Label | required | | +| param_file_format | 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 [`Args.use_param_file`](https://bazel.build/rules/lib/builtins/Args#use_param_file). The tool has to support reading arguments from the file for this to work. | String | optional | "" | diff --git a/rules/run_binary.bzl b/rules/run_binary.bzl index 7701fa0d..8ff20644 100644 --- a/rules/run_binary.bzl +++ b/rules/run_binary.bzl @@ -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). @@ -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 @@ -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), @@ -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 = "", + ), }, )