Introduction

Bazel is a tool for building and testing applications. The same thing can be performed by Make, CMakelists or Gradle. What makes Bazel different? It can develop application for different platforms, with different codebases and is highly parallel. The largest repos are built mostly with Bazel now.

Installation

Download and install Bazel.

Terminologies

Workspace

The main directory of the project from where all the sources files are accessible. A workspace is made when bazel finds a WORKSPACE or WORKSPACE.bazel file.

  # Here repo is the workspace and contains WORKSPACE file
  repo/src/module1/BUILD
  repo/src/module1/runner1.cc
  repo/src/module2/BUILD
  repo/src/module2/runner2.cc
  repo/src/tests/data/cases.txt
  repo/src/tests/BUILD
  repo/src/tests/pass.py
  repo/WORKSPACE

Repositories

The directory containing the WORKSPACE file, is also called as @. We can also have several external repositories for a project.

  # Here @repo can be seen as a repository
  repo/src/module1/BUILD
  repo/src/module1/runner1.cc
  repo/src/module2/BUILD
  repo/src/module2/runner2.cc
  repo/src/tests/data/cases.txt
  repo/src/tests/BUILD
  repo/src/tests/pass.py
  repo/WORKSPACE

Packages

All related files for a particular task in the source directory are called as packages. Each package is defined by BUILD file.

  # Here module1, module2 and tests are defined as packages, Not data
  repo/src/module1/BUILD
  repo/src/module1/runner1.cc
  repo/src/module2/BUILD
  repo/src/module2/runner2.cc
  repo/src/tests/data/cases.txt
  repo/src/tests/BUILD
  repo/src/tests/pass.py
  repo/WORKSPACE

Targets and Labels

Contents of the package are called as targets. The contents can be files or rules(defined later). The files can be source files(code files) or generated files(.o/.pyc/.osx/.exe etc).

The name of the target is called as label. Each label is uniquely pointing to a target. So given the previous example, we can have following targets.

@repo//src/module1:runner1
@repo//src/module2:runner2
@repo//src/tests:pass
@repo//src/tests:data/cases.txt

The naming also allows //src/tests:pass if we are inside repo folder. For external repositories, the name should be given in full.

All naming conventions are standard in the above cases i.e. (//,.,..,) are not allowed as names of either package or target. They all should be meaningful in nature.

Rules

It is way to generate outputs from the given inputs. Now for each language we have different rules. For C/C++, we have cc_binary rule. For python, we have py_binary rule. So we have given rules for each file.

  # runner1 is a C++ file, dependencies are defined in deps
  cc_binary(
    name = "runner1",
    srcs = ["runner1.cc"],
    deps = [
        "//absl/base",
        "//absl/strings",
    ],
)

BUILD files

The build file is comparised of following sections.

Extensions

Use the load statement, to import something which can be a particular rule, symbol or constant.

  load("//src/custom:file.bzl", "custom_package")

Rules

All the standard available rules are given here.

Dependencies

  • srcs Files or rules
  • deps Symbols, libraries, generated files
  • data txt,image,audio etc

Bazel commands

  bazel --version -> gives version
  bazel build <labels> -> builds the package
  bazel-bin/<label-names>/<target> -> executes the package
  bazel query --notool_deps --noimplicit_deps "deps(<target>)" --output graph --> generates the graph