Bazel Introduction

Introduction

Bazel is an open-source, cross-platform build system that is used to build software projects. It is a meta-build system, which means that it does not directly generate the build files for a project. Instead, it generates scripts that are used by other build systems, such as Make or Ninja.

Bazel is written in the Go programming language and is available for Windows, macOS, Linux, and other platforms. It is a popular choice for building software projects, as it is fast, scalable, and flexible.

project

In a real project, we should create the following files for Bazel:

  • A WORKSPACE file: This file specifies the location of the Bazel repository and the dependencies of the project.
  • A BUILD file: This file contains the build instructions for the project.
  • A .bzl file: This file contains Starlark code that is used to define the build process.
  • Other files: These files may contain source code, documentation, or other assets for the project.

Here is an example of a WORKSPACE file:

workspace(name = "my_project")

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

git_repository(
    name = "my_dependency",
    commit = "master",
    url = "https://github.com/my_user/my_dependency.git",
)

This WORKSPACE file specifies the location of the Bazel repository and the dependency of the project, which is the my_dependency repository.

Here is an example of a BUILD file:

load("@my_dependency//:defs.bzl", "my_rule")

my_rule(name = "my_target")

This BUILD file imports the defs.bzl file, which contains the definition of the my_rule rule. The my_rule rule is then used to create a target named my_target.

Here is an example of a .bzl file:

def my_rule(name):
  """A rule that creates an executable target."""

  command = "gcc main.cpp -o $TARGET"
  build_target = name

  return rule(
      name = name,
      command = command,
      build_target = build_target,
  )

This .bzl file defines the my_rule rule. The my_rule rule creates an executable target with the given name. The command attribute specifies the command that is used to build the target. The build_target attribute specifies the name of the target.

grammar

WORKSPACE

The grammar in a WORKSPACE file for Bazel is a set of rules that define how the dependencies of the project are defined. The WORKSPACE file is a text file that contains the build instructions for the project.

The basic building block of a WORKSPACE file is a repository rule. A repository rule is a statement that tells Bazel how to fetch a dependency from an external repository.

Here is an example of a repository rule that fetches the gtest dependency from the GitHub repository:

git_repository(
    name = "gtest",
    commit = "master",
    url = "https://github.com/google/gtest.git",
)

The git_repository rule takes three arguments:

  • name: The name of the dependency.
  • commit: The commit hash of the dependency.
  • url: The URL of the dependency repository.

WORKSPACE files can also contain functions, variables, and other statements.

For more information on the grammar in WORKSPACE file for Bazel, please refer to the Bazel documentation: https://docs.bazel.build/versions/master/be/workspace.html.

Here are some of the most common repository rules that are used in WORKSPACE files:

  • git_repository: This rule fetches a dependency from a Git repository.
  • http_archive: This rule fetches a dependency from a HTTP archive.
  • git_submodule: This rule fetches a dependency as a submodule.

BUILD

The grammar in a BUILD file for Bazel is a set of rules that define how the build process is defined. The BUILD file is a text file that contains the build instructions for a Bazel project.

The basic building block of a BUILD file is a rule. A rule is a statement that tells Bazel how to build a target. Targets can be executables, libraries, tests, and other types of artifacts.

Here is an example of a rule that defines an executable target named my_executable:

rule my_executable
  command = gcc main.cpp -o my_executable
  build_target = my_executable

The rule keyword defines a new rule. The command attribute specifies the command that is used to build the target. The build_target attribute specifies the name of the target.

BUILD files can also contain functions, variables, and other statements.

Here is an example of a function that prints the message “Hello, world!” to the console:

def hello_world():
  print("Hello, world!")

The def keyword defines a new function. The hello_world function takes no arguments and returns no value. The body of the function is a block of statements that are executed when the function is called.

For more information on the grammar in BUILD file for Bazel, please refer to the Bazel documentation: https://docs.bazel.build/versions/master/build-ref.html.

Here are some of the most common rules that are used in BUILD files:

  • rule: This rule defines a new rule.
  • build_target: This attribute specifies the name of the target.
  • command: This attribute specifies the command that is used to build the target.
  • deps: This attribute specifies the dependencies of the target.
  • visibility: This attribute specifies the visibility of the target.

.bzl

The grammar in a .bzl file for Bazel is a set of rules that define how the build process is defined. The .bzl file is a text file that contains Starlark code that is used to define the build process.

Starlark is a language that is similar to Python. The Starlark code in the .bzl file can be used to define rules, macros, and functions that are used to build the project.

Here is an example of a rule that defines an executable target named my_executable:

def my_rule(name):
  """A rule that creates an executable target."""

  command = "gcc main.cpp -o $TARGET"
  build_target = name

  return rule(
      name = name,
      command = command,
      build_target = build_target,
  )

The def keyword defines a new function. The my_rule function takes one argument, which is the name of the target. The body of the function defines the build process for the target.

The rule keyword returns a new rule. The name attribute specifies the name of the rule. The command attribute specifies the command that is used to build the target. The build_target attribute specifies the name of the target.

.bzl files can also contain functions, variables, and other statements.

For more information on the grammar in .bzl file for Bazel, please refer to the Bazel documentation: https://docs.bazel.build/versions/master/skylark/language.html.

Here are some of the most common rules that are used in .bzl files:

  • rule: This rule defines a new rule.
  • build_target: This attribute specifies the name of the target.
  • command: This attribute specifies the command that is used to build the target.
  • deps: This attribute specifies the dependencies of the target.
  • visibility: This attribute specifies the visibility of the target.

Summary

Here are some of the benefits of using Bazel:

  • It is fast: Bazel is very fast at building projects. This is because Bazel uses a distributed build system that can take advantage of multiple CPUs and cores.
  • It is scalable: Bazel can be used to build large and complex projects. This is because Bazel uses a dependency graph to track the dependencies between files and targets.
  • It is flexible: Bazel can be used to build projects with different languages and frameworks. This is because Bazel uses a generic build language that can be used to define the build process for any project.

Here are some of the limitations of using Bazel:

  • It can be complex: Bazel can be complex to learn and use, especially for complex projects.
  • It can be inflexible: Bazel can be inflexible in some cases, such as when trying to integrate with existing build systems.

Overall, Bazel is a powerful and flexible build system that can be used to build software projects on different platforms. It is well-documented and there are many resources available to help users learn how to use it. However, it can be complex to learn and use, especially for complex projects.