Bazel is a build system, i.e. a system that will run compilers and tests to assemble your software, similar to Make, Ant, Gradle, Buck, Pants, and Maven.
Bazel was designed to fit the way software is developed at Google. It has the following features:
Multi-language support: Bazel supports Java and C++ out of the box, and can be extended to support arbitrary programming languages.
High-level build language: Projects are described in the BUILD language, a concise text format that describes a project as sets of small interconnected libraries. By contrast, in systems like Make you have to describe individual files and compiler invocations.
Multi-platform support: The same tool and the same BUILD files can be used to build software for different architectures, and even different platforms. At Google, we use Bazel to build both server applications (C++, Java, and Go binaries running on systems in our data centers) and client apps (Android and iOS apps running on ARM chips).
Reproducibility: In BUILD files, each library, test, and binary must specify its dependencies completely. Bazel uses this dependency information to know what must be rebuilt when you make changes to a source file, and which tasks can run in parallel. This means that all builds are incremental and will always produce the same result.
Scalable: Bazel can handle large builds; at Google, it is common for a server binary to have 100k source files, and builds where no files were changed take about ~200ms.
Make, Ninja: These systems give very exact control over what commands get invoked to build files, but it's up to the user to write rules that are correct.
Users interact with Bazel on a higher level. For example, it has built-in rules for “Java test”, “C++ binary”, and notions such as “target platform” and “host platform”. The rules have been battle tested to be foolproof.
Ant and Maven: Ant and Maven are primarily geared toward Java, while Bazel handles multiple languages. Bazel encourages subdividing codebases in smaller reusable units, and can rebuild only ones that need rebuilding. This speeds up development when working with larger codebases.
Gradle: Bazel configuration files are much more structured than Gradle's, letting Bazel understand exactly what each action does. This allows for more parallelism and better reproducibility.
Buck, Pants: Both systems were created ex-Googlers at Twitter and Facebook. They have been modeled on Bazel, but their feature set has not caught up to Bazel, so it's not an alternative for us.
Bazel is a flavor of the tool that Google uses to build its server software internally. It has expanded to also build the client apps (iOS, Android) that connect to our servers.
Bazel shares most of its code with the internal tool and its rules are used for zillions of builds every day.
A long time ago, Google built its software using large, generated Makefiles. These led to slow and unreliable builds, which began to interfere with our developers' productivity and the company's agility. Hence, we built Bazel.
Google's in-house flavor of Bazel does use build clusters, so Bazel does have hooks in the code base to plug-in a remote build cache or a remote execution system.
The code base we are opening up runs tasks locally. We are confident that this is fast enough for most of our users.
For our server code, we use the following development workflow:
All of our server code base is in a single, gigantic version control system.
Everybody builds their software with Bazel.
Different teams own different parts of the source tree, and make their components available as BUILD targets.
Branching is primarily used for managing releases, so everybody develops their software at head.
Bazel is a cornerstones of this philosophy: since Bazel requires all dependencies to be fully specified, we can predict which programs and tests are affected by a change, and vet them before submission.
More background on the development process at Google can be found on the eng tools blog.
Building software should be fun and easy, and slow and unpredictable builds take the fun out of programming.
Bazel may give you faster build times because it can recompile only the files that need to be recompiled. Similarly, it can skip re-running tests it knows haven't changed.
Bazel produces deterministic results. This eliminates skews between incremental vs clean builds, laptop vs CI system, etc.
Bazel can share code between different client and server apps. For example, you can change a client/server protocol in a single commit, and test that the updated mobile app works with the updated server, building both with the same tool, reaping all the aforementioned benefits of Bazel.
Bazel shines at building and testing projects with the following properties:
Currently, Linux and MacOS. Porting to other Unix platforms should be straightforward, provided a JDK is available for the platform.
We have experimented with a Windows port using MinGW/MSYS (see README.windows), but have no plans to invest in this port right now. Due to its Unix heritage, porting Bazel is significant work. For example, Bazel uses symlinks extensively, which has varying levels of support across Windows versions.
Bazel tries to be smart about caching. This means it is a bad match for build steps that may not be cached. For example, the following steps should not be controlled from Bazel:
Bazel tries to minimize expensive compilation steps. If you are only using interpreted languages, such as JavaScript or Python, Bazel will likely not interest you.
The core features (C++, Java, and shell rules) have extensive use inside Google, so they are thoroughly tested and have very little churn. Similarly, we test new versions of Bazel across our millions of targets every day to find regressions, and we release new versions multiple times every month.
In short, except for features marked as experimental, at any point in time, Bazel should Just Work.
You can recognize the different experimental features as follows:
Options: Experimental features start with --experimental_.
Rules: Experimental rules are undocumented in the build encyclopedia. TODO(bazel-team): add link.
Attributes: Experimental rule attributes are undocumented in the build encyclopedia. TODO(bazel-team): add link.
TODO(bazel-team): document skylark status more precisely.
Inside Google, we make sure that Bazel crashes are very rare. This should also hold for our open-source codebase.
See our getting started doc
TODO(bazel-team): more doc links
Your project never works in isolation. Typically, it builds with a certain version of the JDK/C++ compiler, with a certain test driver framework, on a certain version of your operating system.
These aspects make builds less reproducible, and to counter this, we at Google check most of these tools into version control, including the toolchains and Bazel itself. By convention, we do this in a directory called “tools”.
Bazel allows tools such as the JDK to live outside your workspace, but the configuration data for this (where is the JDK, where is the C++ compiler?) still needs to be somewhere, and that place is tools/.
Bazel comes with a base_workspace/ directory, containing a minimal set of configuration files, suitable for running toolchains from /usr/bin/.
With Docker you can easily create sandboxes with fixed OS releases, eg. Ubuntu 12.04, Fedora 21. This solves the problem of reproducibility for the system environment (i.e. “which version of /usr/bin/c++ do I need?”).
It does not address reproducibility with regard to changes in the source code. Running Make with an imperfectly written Makefile inside a Docker container can still yield unpredictable results.
Inside Google, we check in tools for reproducibility. In this way, we can vet changes to tools (“upgrade GCC to 4.6.1”) with the same mechanism as changes to base libraries (“fix bounds check in OpenSSL”).
For Java and C++ binaries, yes, assuming you do not change the toolchain. If you have build steps that involve custom recipes (eg. executing binaries through a shell rule), you will need to take some extra care:
Do not use dependencies that were not declared. Sandboxed execution (--spawn_strategy=sandboxed-linux, only on Linux) can help find undeclared dependencies.
Avoid storing timestamps in generated files. ZIP files and other archives are especially prone to this.
Avoid connecting to the network. Sandboxed execution can help here too.
Avoid processes that use random numbers, in particular, dictionary traversal is randomized in many programming languages.
No, but we should. Stay tuned.
For integrating with external tools, including IDEs, we have the following hooks:
“bazel query”: lets you query the target dependency graph, see TODO(bazel-team): link to doc.
Extra actions: Bazel can emit protobuf data detailing what commands are to be invoked for building certain targets.
Stay tuned for example IDE integration code.
Bazel returns an invalid exit code if the build or test invocation fails, and this should be enough for basic CI integration. Since Bazel does not need clean builds for correctness, the CI system can be configured to not clean before starting a build/test run.
We work on supporting Google‘s internal use-cases. This includes Google’s principal languages (C++, Java, Go) and major platforms (Linux, Android, iOS). For practical reasons, not all of these are currently open-sourced.
TODO(bazel-team): add link to public roadmap.
We haven't made up our mind about these yet.
Our internal usage of Python relies heavily on native extensions, and its supporting infrastructure is specific to us, so we have no plans to open-source it.
It is possible to support other packaging mechanisms, though. See the following files for an example of generating self-contained zip files for python:
https://github.com/google/bazel/blob/master/base_workspace/tools/build_rules/py_rules.bzl https://github.com/google/bazel/tree/master/base_workspace/examples/py
We have an extension mechanism that allows you to add new rules without recompiling Bazel.
For documentation: see TODO(bazel-team).
At present, the extension mechanism is experimental though.
If our extension mechanism is insufficient for your use case, email the mailing list for advice: bazel-discuss@googlegroups.com.
Not yet, but we are working on a process.
Please consider the following:
Before starting to code, discuss your plan to make sure we agree on it. We can be reached at bazel-discuss@googlegroups.com.
All contributors must sign a Contributor License Agreement at
All contributions will have to go through pre-commit code review.
Contributions need a Google team member as sponsor.
TODO(bazel-team): set up a process
We still have to refactor the interfaces between the public code in Bazel and our internal extensions frequently. This makes it hard to do much development in the open.
TODO(bazel-team): link to roadmap.
We are reachable at bazel-discuss@googlegroups.com.
Send us e-mail at bazel-discuss@googlegroups.com.
This is an internal name for the system. Please refer to Bazel as Bazel.
Until now, Bazel was not available externally, so open source projects such as Chromium, Android, etc. could not use it. In addition, lack of Windows support is a problem for building Windows applications, such as Chrome.
The same way as “basil” (the herb) in US English: “BAY-zel”. It rhymes with “hazel”. IPA: /ˈbeɪzˌəl/