When writing a rule that executes in the exec configuration, we need to communicate that to Bazel so it doesn’t attempt to build it for the target configuration:
generator = rule(
implementation = _generator_impl,
...,
cfg = "exec",
)
While there is nothing wrong with cfg = "exec", my opinion is that we should use the newer transition object API.
This means that instead of:
cfg = "exec"
we use:
cfg = config.exec()
Why?
Apart from legitimate use cases such as transition composition and passing an exec group, I think using the object form is better for readability and discoverability.
"exec" is a special string. You need to already know what it means and where it is supported.
config.exec(), on the other hand, looks like an API. It is easier to discover, easier to search for, and makes it clearer that we are applying an execution transition.
Passing the "exec" string is not deprecated, and I am not suggesting that it is incorrect.
Conclusion
This is simply my take on config.exec().
Migrating an entire codebase from cfg = "exec" to cfg = config.exec() will not result in any build-time improvement. It will, however, make the API usage slightly more explicit and leave room for features that the string form cannot express.