Summary
Here is why.
Background
Bazel is a build system. Originally created at Google for internal purposes, then eventually open sourced. Since then, it has not been universally accepted. You can find discussions where it is being put down in favor of other build systems.
Yet, I have been using bazel in a lot of my recent projects, and have been quite pleased with the results. I intend to explain here why this works for me. I do not intend to compare to anything else, if that is what you are after, you will need to look for that elsewhere.
Bazel things that work well
Bazel sets up your dev environment automatically. Bazel knows how to download and apply build tools without you having to do that preliminary setup.
Bazel builds hermetically. Builds are set up so that each build step sees only the inputs necessary for it to work. This means there is no way for stray dependencies to create unforeseen effects in a build.
Bazel can build ephemerally. Artifacts built by Bazel don’t interact with any other builds on the same system.
Bazel builds reproducibly. Repeated builds produce identical artifacts.
Bazel can build anything. Most build tools fare quite well with building C and C++. However, once you have a project that builds multiple languages, you are left with your own devices. Bazel allows you to build any tools, using the approach that looks the same no matter what the underlying build toolchain may be.
Bazel can build tools that are then used in the build. It is exceptionally easy to build your own helpful tools, and leave it to bazel to build them correctly.
Bazel captures and uses dependencies correctly. This is hard to do manually in tools like make
.
Bazel can import foreign build systems. This used not to be the case, but it now is, with rules_foreign_cc.
Bazel model of extension is efficient. You can create, and share build rules with others, and reuse build rules others create. You also apply the build rules in a way that cleanly separates uses of build rules and the definition of build rules.
I am familiar with how Bazel works. Partly because I used Bazel’s closed source cousin internally at Google for many years. This is of course subjective, but it’s still a factor for me. That said, for those unfamiliar with Bazel and its underlying principles, it might become a downside.
Bazel things that do not work that well
Bazel may need special IDE integration. This was more true in the past years, while today it is not so much the case with the more universal support for language servers.
Bazel is a java program. Some people will take this as a negative. It might well be, but I have not seen that as a big problem. JVM may be part of bazel’s runtime, but in everyday work you do not really care. It is a historic accident, however, which has been perpetuated to this day.
Bazel is opinionated. Bazel insists on building in a particular way, which may be unintuitive or unexpected for people who are used to other build systems.
Some software is outright hostile to being used under Bazel. This is mostly concerning programs that want to create many files and directories at will, and expect to be able to access the filesystem at will. Specifically, digital design tooling is notorious for being like that. Now, while this isn’t particularly an issue with Bazel, it can put a damper into what you may be able to achieve with it. If your toolchain is full of such tools, it can be nigh impossible to adapt bazel to work with them.
You may find you need to work out your own build rules. This used to be a showstopper for me for quite some time. I had to invest considerable time to wrap my mind around how build rules work, and to become somewhat competent in writing them. If you don’t have the time or the wherewithal to do this, bazel might not be for you.
Conclusion
This article was intended to list the tradeoffs I noticed, and to note that those tradeoffs for using bazel are worth it to me personally.
You may find that your tradeoffs are different. You may find that the tradeoff tips the scale differently for you.
That is also OK.