It’s easy to decide on a build tool for a pet project based on personal preference; however, as soon as you plan to standardize on a tool at an enterprise-wide level, you’ll definitely have to consider more aspects. A wrong choice may cause a ripple effect across the organization, potentially resulting in unmaintainable builds, long-running build times, or a poor user experience.
Bazel, an open source build tool implemented and maintained by Google, is one of the newer players in the field.
Google internally uses a build tool which they call Blaze. Blaze is optimized to carry out Google-internal use cases and processes. Most prominently, Blaze focuses on building large mono-repositories, delivering fast execution and feedback times, as well as ensuring reproducibility and correctness. As you can imagine, those requirements make Blaze a highly opinionated though powerful tool. Despite its strong stance on internal build practices and standards, Google decided to open-source a Blaze derivate Bazel in 2015. Bazel comes with the same DNA as its internal cousin, but it is far less Google-specific. After growing the community and feature set for over four years, Google released its first official, production-ready offering—Bazel version 1.0—in October 2019.
It’s not uncommon for projects to have custom requirements. While Bazel’s built-in support for languages and ecosystems is broad and expansive, it cannot cover every possible use case. With the help of Bazel’s extension mechanism, called Rules, developers can enhance the tool’s base functionality and share it across the organization or wider community.
Building polyglot projects
Many build tools support building only a single language or ecosystem. That’s not the case with Bazel. Bazel can handle polyglot projects. Bazel embraces modern software development methodologies like containerization of applications with Docker and deployment to orchestration engines like Kubernetes.
Bazel’s main focus is on projects with large codebases, predominantly for organizations that have decided to put all of their projects into a mono-repository. It’s not a dealbreaker if you break down your projects into individual source code repositories. That’s common practice, especially if you are working on software with a micro-services architecture. Bazel can handle both mono-repository and multi-repository code organizational structures quite well.
When executing builds over and over again, you do not want any surprises. Non-deterministic behaviour erodes trust in the correctness of build results. Bazel also ensures a sandboxed build execution by enforcing the definition of all of its dependencies explicitly.
As a developer of build logic, you use a higher-level language called Starlark, a Python derivative. Starlark introduces an abstraction to the concepts of a build and hides its implementation complexities as much as possible. As a result, you do not have to concern yourself with low-level implementation details like compilers or linkers. Instead, you just point your build to the source code and declare dependencies. Bazel will figure out the rest. Needless to say, you can still fine-tune the compiler or linker settings if needed.
Reducing build times is very much needed when you are running thousands of tests hundreds of times. Bazel knows when something needs to be rebuilt, and rebuilds only that. Companies like DropBox, Uber, Google, Pinterest and Stripe use Bazel today.