I’ve written about Bazel transitions multiple times: first when demonstrating rule extensions, and then when explaining split transitions.
Now I want to showcase a community-built way to apply transitions more easily.
Enter with_cfg.bzl
with_cfg.bzl is a convenient way to apply Bazel transitions. It was created by well-known community member Fabian, and I can’t recommend it enough.
Applying a transition to a plain swift_library
Say we want to ensure that our swift_library is always built with --compilation_mode=opt. We can achieve that quite easily with the following .bzl file:
load("@rules_swift//swift:swift_library.bzl", "swift_library")
load("@with_cfg.bzl", "with_cfg")
opt_swift_library, _opt_swift_library_internal = (
with_cfg(swift_library)
.set("compilation_mode", "opt")
.build()
)
That’s it.
NOTE: You can ignore _opt_swift_library_internal. It needs to be assigned to a global variable because of Bazel’s restrictions on rule definitions, but you aren’t supposed to use it directly. Instead, use the generated opt_swift_library macro.
Finally, load opt_swift_library from the .bzl file containing the code above and use it just like a regular swift_library. The target and all its transitive dependencies will be built with the opt compilation mode.
Prior art
I won’t go into detail about what this would look like without with_cfg.bzl, as that’s already covered in my earlier articles.
Conclusion
Unfortunately, I discovered this way too late, but I’m glad it exists. It makes transitions much less tedious to write and reason about.