Bazel Notes

Bazel is an open-source build and test tool similar to Make, Maven, and Gradle. It uses a human-readable, high-level build language. Bazel supports projects in multiple languages and builds outputs for multiple platforms. Bazel supports large codebases across multiple repositories, and large numbers of users.

Installing on Ubuntu

It’s easy and recommended to install bazel via the binary installer, which can be downloaded from Bazel’s Github releases page

Run the binary directly, and it should be done gracefully. Note that some libraries must be installed for Bazel to work. Run command:

1
sudo apt install pkg-config zip g++ zlib1g-dev unzip python

Official examples

Bazel can be used to build various projects, while we just focus on C++ in this blog. The codes can be found here.

The directory structure looks like this:

1
2
3
4
5
6
7
8
root-dir
|-------main
|-------BUILD
|-------hello-world.cc
|-------[OTHER FILES]
|
|-------WORKSPACE
|

The WORKSPACE file is necessary for Bazel to work, although it can be remained empty for now.

Single file

To build a runable file from a single file, we can write BUILD like this:

1
2
3
4
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)

To build binary file we use

1
bazel build //main:hello-world

After the build completed, the executable will be genereted in bazel-bin/main/hello-world.

Multiple files using library

Use cc_library rule to build a library:

1
2
3
4
5
cc_library(
name = "hello-util",
srcs = ["hello-util.cc"],
hdrs = ["hello-util.h"],
)

To use the library, we can use deps in cc_binary:

1
2
3
4
5
6
7
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-util",
],
)

Integrate multiple cc_library targets

In Bazel, subdirectories containing BUILD files are known as packages. The property visibility will tell Bazel which packages(s) can reference this target.

The directory structure are changed to:

1
2
3
4
5
6
7
8
9
10
11
12
root-dir
|-------main
|-------BUILD
|-------hello-world.cc
|
|-------util
|-------BUILD
|-------str-utl.cc
|-------str-util.h
|
|-------WORKSPACE
|

In util package, the target of BUILD is library:

1
2
3
4
5
6
cc_library(
name = "str-util",
srcs = ["str-util.cc"],
hdrs = ["str-util.h"],
visibility = ["//main:__pkg__"],
)

The visibility property tells Bazel that the //main package can use str-util library.

In main package, there is a slight change: we should assign the package name explictly.

1
2
3
4
5
6
7
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
"//util:str-util",
],
)