Dealing with Bazel runfiles is one of the most annoying things about using Bazel. Fortunately, Bazel provides a library to make resolving runfiles from Bash scripts easy.
Properly resolving runfiles is more complicated than it first appears. Many systems
manage runfiles as symbolic links in a runfiles directory, but some use a manifest
file named MANIFEST
. To properly resolve a runfile you must be able to handle
both cases.
Within the bazel_tools
repsoitory there is a script named runfiles.bash
.
It is self-described as a “runfiles lookup library for Bazel-built Bash binaries and tests”.
It provides a function named rlocation()
which allows you to resolve the location
of a runfile from any bash script.
To use:
- Add
@bazel_tools//tools/bash/runfiles
as a dependency of yoursh_*
rule:
|
|
- Copy-paste the initialization code from
runfiles.bash
to th beginning of your script:
|
|
- Use
rlocation()
to resolve runfiles locations. Note that runfile paths must start with the name of your workspace:
|
|
Note: According to Jay Conrod’s blog post Writing Bazel rules: data and runfiles,
the rlocation
function is already predeclared in sh_test()
rules which means
that loading the runfiles library is not necessary. I verified that this is true
in practice, but I could not find any official documentation about this guarantee.