Hermetic, Ephemeral, Reproducible Builds: Take Three (3)

October 29, 2025

Bazel rules to support a debian rootfs

The idea of this repository is to provide a hermetic, ephemeral and reproducible repository of prebuilt binaries, which can then be brought into bazel builds to remove the dependence on local binary installations.

Find the project page at: https://github.com/filmil/bazel_debian_rootfs

Test status Publish BCR status Publish status Tag and Release status

This is otherwise a difficult task. Making a hermetic bazel build involves painstakingly bringing in each needed binary one at a time. Often, this means descending into the rats nest of dependencies and having to bring them all in. One can convince themselves that this approach is then equivalent to rebuilding an entire software repository from scratch. Something that we should avoid doing if we can help it. And something that presents a significant barrier to entry for bazel builds, and one that is best avoided if possible.

Instead, we use existing rules_distroless and rules_oci to bring in packages from a Debian repository. The rules that achieve this are all confined within the bazel package //images.

The second step is bringing the actual binaries into the bazel build process for reuse. This is done in //bin. If you look at the example script for ghdl, you will see the complication: since the Debian rootfs is not necessarily compatible with the host distribution, we have to create an environment that allows execution of “foreign” binaries on your machine. This is done by creatively using LD_LIBRARY_PATH, PATH and other needed environment variables on a per-binary basis. Getting the incantation just right for ghdl to operate properly makes me think that a more robust approach should be used instead, if we were to generalize the approach.

Prerequisites

  • bazel installation via bazelisk. I recommend downloading bazelisk and placing it somewhere in your $PATH under the name bazel.

Everything else will be downloaded for use the first time you run the build.

Examples

In general, see integration/ for example use.

Sample use: ghdl_verilog

cd integration && bazel build //... && cat bazel-bin/verilog/lib.v

To see how it builds a library, run this:

cd integration && bazel build //:lib

Notes

  • Only Linux host and target are supported for now, although it should be straightforward (but not necessarily trivial) to add support for other archs.

  • When updating //image/rootfs_definition.yaml, make sure to turn off the lock file. This allows the definition to be actually updated. Otherwise, adding a new package, for example, will not be reflected in the built rootfs.

References