Bazel modules promise to usher the era of trivial bazel dependency management. However, getting from here to there seems to be a journey fraught with peril. Migration guides are few and far between. And it’s never about the easy stuff what makes it fraught, it’s always the side quests and corner cases that create issues.
Since Bazel 9.0 promises to disable the old dependency management approaches based on WORKSPACE
by the end of 2025, I figured we should better start preparing. This is my preparation central.
Realizations
I realized quickly that the overhead of migration can only be conquered by judiciously applying automation and simplification efforts.
In the past, we built jenga towers of dependencies, which we need to deconstruct and remake in the image of the new modules approach.
This is taking significant effort, but is worth it to me.
To manage the migration complexity, I adopted a few conventions which allow me to decouple my work on migrating the modules from BCR and publication. See the “Standardization” section below.
Repositories in topological order
You can expect that earlier listed repositories could be dependencies of later-listed repositories.
- https://github.com/filmil/bazel_zlib_foreign
- https://github.com/filmil/bazel_libzstd
- https://github.com/filmil/bazel-registry
- https://github.com/filmil/bazel_elfutils
- https://github.com/filmil/bazel_hello_foreign
- https://github.com/filmil/bazel_graphviz_foreign
Standardization
- Modules built using
rules_foreign_cc
do not play well with native bazel deps.- I am rebuilding those that I need using the same rules, and using them as dependencies instead. This avoids the complications of getting the library cooperation just right.
- I prefer static linking which may not be everyone’s cup of tea.
- Build verification is a standardized set of bazel commands
bazel test //... && cd integration && bazel test //...
- Latest workflow statuses are publicized in README.md for the respective repository
- Tagging and releases are automated and happen on a weekly schedule.
- Registry publication is manual, but executed based on a tagged release by an automated process.
- Modules are first published to a staging repository https://github.com/filmil/bazel-registry.
- This allows early adopters to get fixes before the module makes it into BCR.
- Some modules will never make it into BCR, so this may be the only repo where they would be available.
- Best effort hermeticity. Hermeticity notes are in README.md
- Best effort BCR publication. I will submit a generated PR, but it’s up to BCR if they incorporate the result into the BCR. I don’t care much to get included so long as the modules are available in my registry.
- Some of my modules use techniques that aren’t necessarily best practices, so those may not ever get publicized to BCR.
- Repositories use the naming schema:
bazel_foo_foreign
for repos built usingrules_foreign_cc
.- These rules are less efficient to build than building via bazel, but building foreign modules with foreign deps works better than building foreign modules using bazel-provided libraries.
foo_foreign
for the respective module name, since it seems that BCR folks prefer it that way.
- Usable targets are of the same form:
library_name//:lib