Bazel rules for “build-in-docker” (or “bid”)
Bid allows you to create a build rule that runs a single bazel build action inside a Docker container. And if you can run a single action, you can run more if you so choose. This helps you if you must use software which is hard to bazelize, such as typically some EDA packages.
The limitation is, you must have a way to invoke docker run. I can afford to do that, but depending on your setup you might not. Not everyone is happy to run arbitrary binaries through a daemon that runs as root by default (it seems that rootless docker, or podman, are not compatible with use in bazel, so that avenue seems closed for the foreseeable future).
Cross-posted from the original at https://github.com/filmil/bazel-rules-bid
What is bid not?
-
Bid is different from https://github.com/bazelbuild/rules_docker. Those are Bazel rules for building containers.
-
Bid is also different from running bazel from a container described at https://bazel.build/install/docker-container. That is a way to run the entire bazel build inside a docker container.
What other approaches are there?
Here are some approaches to bazelizing the unbazelizable that I have seen (and my commentary):
- Building entirely inside a docker container. (Everything including bazel, is inside a container.)
- Building in a pre-prepared docker container sandbox. (This is similar, but runs all actions in a container sandbox.)
- Building in a nix environment. (Nix is really complex.)
- Extracting software from existing sysroot packages. (Doesn’t work with all vDSOs.)
- Bazelizing everything. (Sometimes hard to do. Or even infeasible, for example when the commercial software you must use has libraries which are no compatible with your kernel.)
Why bid?
This is a refactoring of a hack I did for https://github.com/filmil/bazel-ebook. The ebook toolchain setup was very complex. It included installing plenty of Python, pandoc and dependencies, which are notoriously hard to get right.
I worked around the whole issue by creating a Docker container which has a regular Debian system with all the tools installed, and writing bazel rules that invoke that container in build steps.
How to use bid?
This section is obsolete in the modules world, I need to update it.
Declare it in your WORKSPACE file.
Ensure your WORKSPACE file has:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
Then append the following:
git_repository(
name = "bazel_rules_bid",
remote = "https://github.com/filmil/bazel-rules-bid.git",
commit = "04b599ec790fe4572dfb851e145c791cb5022c15",
shallow_since = "1676537869 -0800"
)
load("@bazel_rules_bid//build:repositories.bzl", "bazel_bid_repositories")
bazel_bid_repositories()
See the example in Bazel-ebook on how to use it then. Mostly you use the rule to prepend the appropriate docker command line and container name to what you actually want to run in the docker container. The script takes care that all needed directories are made available to the docker container when it runs.
The first time you run the rule, it may take considerable time for your container to get downloaded. Once it is, however, you are good to go.