Key building block: run_binary
This rule is an “adapter” from an executable (something you could bazel run) to an action (something you can bazel build).
The executable (called a “tool” here) is run in a single action
which spawns that executable given some declared inputs, and produces some declared, default outputs.
:::caution
Bazel’s built-in genrule
looks a lot like run_binary, but it’s best to avoid it.
- Arbitrary bash one-liner, commonly non-hermetic
- Bash dependency hurts portability
- Subtly different semantics for
expand_location,stamp, etc.
my_tool with three arguments to produce a folder called dir_a:
- The path to
some.filewhich is the only input - An
-outdirflag, which we know from reading the CLI documentation for my_tool.- We’re always required to predict what path the tool will write to. If you get it wrong, Bazel will error that the “output was not produced”.
- A syntax-sugar shorthand for “the output folder Bazel assigns for this action”
js_run_binary rule takes it a step further, adding the ability to:
- capture stdout/stderr/exit code as “outputs”
chdirto a specific working directory- throw away log-spam on success
Making tools work
Thetool in run_binary can be any executable.
However some tools don’t work the way Bazel expects.
This can usually be fixed without having to change the tool, which is good since most tools are
written by third-parties who don’t care about your Bazel migration problems!
:::caution
Google engineers got in the habit of rewriting everything to work with Blaze.
Do not follow their lead! Changing more than one thing at a time makes your migration riskier.
:::
You can make most tools work under Bazel by asking:
“How can the tool tell that it’s running under Bazel?”
There are three ways to make the tool think it’s still running outside Bazel:
- “Monkey-patch” the runtime
- Node.js
-requireflag to run - JVM has a classpath, you can inject a shadowing class
- Node.js
- In-process wrapper
- Peel one layer off the tool’s CLI
- Write your own CLI that calls its entry point
- Parent process wrapper
- Often a short Bash script

