Introduction
New to Bazel? You’re in the right place. Follow this First Build tutorial for a simplified introduction to using Bazel. This tutorial defines key terms as they are used in Bazel’s context and walks you through the basics of the Bazel workflow. Starting with the tools you need, you will build and run three projects with increasing complexity and learn how and why they get more complex. While Bazel is a build system that supports multi-language builds, this tutorial uses a C++ project as an example and provides the general guidelines and flow that apply to most languages. Estimated completion time: 30 minutes.Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results install Git as well. Next, retrieve the sample project from Bazel’s GitHub repository by running the following in your command-line tool of choice:examples/cpp-tutorial
directory.
Take a look at how it’s structured:
Summary: Introduction
By installing Bazel (and Git) and cloning the repository for this tutorial, you have laid the foundation for your first build with Bazel. Continue to the next section to define some terms and set up your workspace.Getting started
Before you can build a project, you need to set up its workspace. A workspace is a directory that holds your project’s source files and Bazel’s build outputs. It also contains these significant files:- The
MODULE.bazelfile, which identifies the directory and its contents as a Bazel workspace and lives at the root of the project’s directory structure. It’s also where you specify your external dependencies. - One or more
BUILDfiles, which tell Bazel how to build different parts of the project. A directory within the workspace that contains aBUILDfile is a package. (More on packages later in this tutorial.)
MODULE.bazel in that directory. For the purposes of this
tutorial, a MODULE.bazel file is already present in each stage.
Understand the BUILD file
ABUILD file contains several different types of instructions for Bazel. Each
BUILD file requires at least one
rule as a set of instructions,
which tells Bazel how to build the outputs you want, such as executable binaries
or libraries. Each instance of a build rule in the BUILD file is called a
target and points to a specific
set of source files and
dependencies. A target can
also point to other targets.
Take a look at the BUILD file in the cpp-tutorial/stage1/main directory:
hello-world target instantiates Bazel’s built-in
cc_binary rule. The rule
tells Bazel to build a self-contained executable binary from the
hello-world.cc> source file with no dependencies.
Summary: getting started
Now you are familiar with some key terms, and what they mean in the context of this project and Bazel in general. In the next section, you will build and test Stage 1 of the project.Stage 1: single target, single package
It’s time to build the first part of the project. For a visual reference, the structure of the Stage 1 section of the project is:cpp-tutorial/stage1 directory:
//main: part is the location of the BUILD file
relative to the root of the workspace, and hello-world is the target name in
the BUILD file.
Bazel produces something that looks like this:
bazel-bin directory at the root of the workspace.
Now test your freshly built binary, which is:
Hello world” message.
Here’s the dependency graph of Stage 1:
Summary: stage 1
Now that you have completed your first build, you have a basic idea of how a build is structured. In the next stage, you will add complexity by adding another target.Stage 2: multiple build targets
While a single target is sufficient for small projects, you may want to split larger projects into multiple targets and packages. This allows for fast incremental builds – that is, Bazel only rebuilds what’s changed – and speeds up your builds by building multiple parts of a project at once. This stage of the tutorial adds a target, and the next adds a package. This is the directory you are working with for Stage 2:BUILD file in the cpp-tutorial/stage2/main directory:
BUILD file, Bazel first builds the hello-greet library (using
Bazel’s built-in cc_library
rule), then the
hello-world binary. The deps attribute in the hello-world target tells
Bazel that the hello-greet library is required to build the hello-world
binary.
Before you can build this new version of the project, you need to change
directories, switching to the cpp-tutorial/stage2 directory by running:
Hello world”:
hello-greet.cc and rebuild the project, Bazel only
recompiles that file.
Looking at the dependency graph, you can see that hello-world depends on an
extra input named hello-greet:
Summary: stage 2
You’ve now built the project with two targets. Thehello-world target builds
one source file and depends on one other target (//main:hello-greet), which
builds two additional source files. In the next section, take it a step further
and add another package.
Stage 3: multiple packages
This next stage adds another layer of complication and builds a project with multiple packages. Take a look at the structure and contents of thecpp-tutorial/stage3 directory:
BUILD
file. Therefore, to Bazel, the workspace now contains two packages: lib and
main.
Take a look at the lib/BUILD file:
main/BUILD file:
hello-world target in the main package depends on the hello-time target
in the lib package (hence the target label //lib:hello-time) - Bazel knows
this through the deps attribute. You can see this reflected in the dependency
graph:
For the build to succeed, you make the //lib:hello-time target in lib/BUILD
explicitly visible to targets in main/BUILD using the visibility attribute.
This is because by default targets are only visible to other targets in the same
BUILD file. Bazel uses target visibility to prevent issues such as libraries
containing implementation details leaking into public APIs.
Now build this final version of the project. Switch to the cpp-tutorial/stage3
directory by running:
Hello world message:
Summary: stage 3
You’ve now built the project as two packages with three targets and understand the dependencies between them, which equips you to go forth and build future projects with Bazel. In the next section, take a look at how to continue your Bazel journey.Next steps
You’ve now completed your first basic build with Bazel, but this is just the start. Here are some more resources to continue learning with Bazel:- To keep focusing on C++, read about common C++ build use cases.
- To get started with building other applications with Bazel, see the tutorials for Java, Android application, or iOS application.
- To learn more about working with local and remote repositories, read about external dependencies.
- To learn more about Bazel’s other rules, see this reference guide.