This article is written by Mohammed Babelly
Building software can be as easy as baking a cake, or as hard as rocket science. It all depends on the tools you use. As a developer, you’ve probably encountered issues like inconsistent builds, long build times, and dependency hell.
If you want to make your life easier and your software better, you may want to try Bazel, the ultimate build tool that can handle anything from cupcakes to spaceships.
In this article, we will introduce you to the basics of Bazel and show you how it can help you stop worrying and love building systems.
What is Bazel?
Bazel is a free and open-source software tool used for the automation of building and testing software. Google uses the build tool Blaze internally and released an open-sourced port of the Blaze tool as Bazel, named as an anagram of Blaze.
Why Bazel?
Bazel is great for developers who work on large and complex software projects, especially those that involve multiple languages, platforms, tools, and environments. And it’s always better to adopt it early than migrate later.
It is similar to other build tools, such as Make, Maven, and Gradle, but far more flexible, it can be used to build projects in a variety of programming languages, including Kotlin, Swift, Go, and Python. It also has some unique features that make it stand out. Some of these features are:
- Speed: Bazel is designed to be fast and efficient. It uses a technique called Incremental Builds, meaning it only rebuilds the parts of the software that have changed since the last build. It also uses caching and parallelism to speed up the build process.
- Correctness: Bazel is designed to ensure that the software is built and tested correctly. It uses a technique called Hermetic Builds, which means that it isolates the built environment from external factors, such as the operating system, the network, or the file system. This ensures that the build results are reproducible and consistent across different machines and platforms. Bazel is so smart, it can figure out what you want to build and test, even if you don’t know it yourself.
- Scalability: Bazel is designed to handle large and complex software projects. It uses a modular and hierarchical structure, which allows the developers to organize the code into smaller and reusable units, called packages and targets. Speaking of which, let’s look into some of Bazel’s fundamental concepts.
Understanding Bazel Concepts
Before start using Bazel, you need first to understand its concepts.
- Workspace: The workspace is the root directory of your Bazel project. It contains a file named
WORKSPACE
(orWORKSPACE.bazel
), which is a configuration file for Bazel. This file can define external dependencies, such as libraries or tools, and set up workspace-wide settings. - Build: Each package in your workspace should contain a
BUILD
(orBUILD.bazel
) file which is an essential part of Bazel, and it describes the process of creating executable software from source code by defining targets, dependencies, and rules. These files specify what should be built and how it should be built. - Library: Libraries in Bazel are reusable units of code that can be shared across multiple targets.
- Label: Labels are unique names assigned to targets and packages. A label consists of the target’s path within the workspace and its name. For example,
//project_android:app
refers to the target namedapp
in theproject_android
directory of the workspace. - Binary: A binary target in Bazel represents an executable program. It could be a standalone application, a script, or any other executable artifact. Binary targets are defined in
BUILD
files and can depend on libraries and other targets. - Rule: Rules are instructions that tell Bazel how to build or test the target. A rule can have one or more commands, which are the actual commands that Bazel executes to perform the build or test action. You can use Bazel’s built-in rules, or create your own. Check out the documentation for a full language-specific rules guide.
Let’s see these concepts in action.
Consider we have a Python Flask app and an Android app that uses some API from that app, and we want to use Bazel to build both of them.
Simple project structure:👇🏻
- WORKSPACE
- project_python
- BUILD
- server.py
- …
- project_android
- BUILD
- AndroidManifest.xml
- src/
- …
First, we should have our WORKSPACE
file at the root of the Bazel project. It can be empty to just identify the entry point for Bazel.
Second, we need to create a BUILD
file for each of the packages.
# project_python/BUILD.bazel
load("@bazel_tools//tools/build_defs/python/rules:python_binary.bzl", "python_binary")
python_binary(
name = "server",
srcs = ["server.py"],
deps = [
"@pip//:flask",
],
)
We’re loading python_binary from Python rules and use it to build our server.
Same for Android:
# project_android/BUILD.bazel
load("@rules_android//android:rules.bzl", "android_binary")
android_binary(
name = "app",
resource_files = glob(["res/**/*"]),
manifest = "AndroidManifest.xml",
resource_files = glob(["res/**/*"]),
)
Building the targets
Using the bazel build <target>
command you can build your packages.
bazel build //project_python:server
bazel build //project_android:app
Or using the bazel build //...
command, which builds all of the targets in the current workspace, recursively. This includes targets in all subdirectories, as well as targets that are declared as dependencies of other targets.
Using Bazel in your CI/CD system
If you’ve taken the leap into the world of Bazel, congratulations! You’ve already made a savvy decision, now, keep riding the wave of good decisions and let a CI/CD pipeline be the wind beneath your Bazel-powered wings. Your codebase and your team will thank you!
To use Bazel in your Codemagic workflows, you’ll first have to install Bazel on the build machine. Once that’s done, you can run your build script. Below is an example of how you would add these steps to the “scripts” section of your codemagic.yaml
configuration file.
scripts:
...
- name: Install Bazel
script: |
HOMEBREW_NO_AUTO_UPDATE=1
brew install bazel
- name: Build all targets in workspace
script: bazel build //...
Conclusion
Bazel is a tool that can rock your world. Bazel can do the hard work of building and testing software for you, making it quick, accurate, scalable, and flexible. So, stop worrying about building systems, you just learned how to use Bazel. Happy building!