Bazel Build System

Bazel - Fast, scalable, multi-language build system from Google.


Installation

 1# Linux (via Bazelisk - recommended)
 2npm install -g @bazel/bazelisk
 3
 4# Or download binary
 5wget https://github.com/bazelbuild/bazel/releases/download/6.4.0/bazel-6.4.0-linux-x86_64
 6chmod +x bazel-6.4.0-linux-x86_64
 7sudo mv bazel-6.4.0-linux-x86_64 /usr/local/bin/bazel
 8
 9# macOS
10brew install bazel
11
12# Windows (via Chocolatey)
13choco install bazel
14
15# Verify
16bazel version

Basic Commands

 1# Build target
 2bazel build //path/to:target
 3
 4# Build all targets
 5bazel build //...
 6
 7# Run target
 8bazel run //path/to:target
 9
10# Test target
11bazel test //path/to:test
12
13# Test all
14bazel test //...
15
16# Clean build
17bazel clean
18
19# Deep clean
20bazel clean --expunge
21
22# Query dependencies
23bazel query 'deps(//path/to:target)'
24
25# Show build graph
26bazel query --output=graph //path/to:target

Workspace Setup

WORKSPACE File

 1# WORKSPACE
 2workspace(name = "my_project")
 3
 4# Load rules
 5load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 6
 7# Go rules
 8http_archive(
 9    name = "io_bazel_rules_go",
10    sha256 = "...",
11    urls = [
12        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
13        "https://github.com/bazelbuild/rules_go/releases/download/v0.41.0/rules_go-v0.41.0.zip",
14    ],
15)
16
17load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
18
19go_rules_dependencies()
20go_register_toolchains(version = "1.21.0")

BUILD Files

Go Example

 1# BUILD.bazel
 2load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
 3
 4go_library(
 5    name = "mylib",
 6    srcs = ["lib.go"],
 7    importpath = "github.com/user/project/mylib",
 8    visibility = ["//visibility:public"],
 9    deps = [
10        "@com_github_pkg_errors//:errors",
11    ],
12)
13
14go_binary(
15    name = "myapp",
16    srcs = ["main.go"],
17    deps = [":mylib"],
18)
19
20go_test(
21    name = "mylib_test",
22    srcs = ["lib_test.go"],
23    embed = [":mylib"],
24)

Python Example

 1# BUILD.bazel
 2load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
 3
 4py_library(
 5    name = "mylib",
 6    srcs = ["mylib.py"],
 7    deps = [
 8        "@pypi//requests",
 9    ],
10)
11
12py_binary(
13    name = "myapp",
14    srcs = ["main.py"],
15    deps = [":mylib"],
16)
17
18py_test(
19    name = "mylib_test",
20    srcs = ["mylib_test.py"],
21    deps = [":mylib"],
22)

Dependencies

External Dependencies (Go)

1# WORKSPACE
2load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
3
4go_repository(
5    name = "com_github_pkg_errors",
6    importpath = "github.com/pkg/errors",
7    sum = "h1:...",
8    version = "v0.9.1",
9)

External Dependencies (Python)

 1# WORKSPACE
 2load("@rules_python//python:pip.bzl", "pip_parse")
 3
 4pip_parse(
 5    name = "pypi",
 6    requirements_lock = "//:requirements.txt",
 7)
 8
 9load("@pypi//:requirements.bzl", "install_deps")
10install_deps()

Gazelle (Go Dependency Management)

 1# Install Gazelle
 2# Add to WORKSPACE:
 3http_archive(
 4    name = "bazel_gazelle",
 5    sha256 = "...",
 6    urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.33.0/bazel-gazelle-v0.33.0.tar.gz"],
 7)
 8
 9# Generate BUILD files
10bazel run //:gazelle
11
12# Update dependencies
13bazel run //:gazelle -- update-repos -from_file=go.mod

Build Configuration

.bazelrc

 1# .bazelrc
 2# Build settings
 3build --jobs=8
 4build --verbose_failures
 5
 6# C++ settings
 7build --cxxopt=-std=c++17
 8build --host_cxxopt=-std=c++17
 9
10# Test settings
11test --test_output=errors
12test --test_summary=detailed
13
14# Remote cache
15build --remote_cache=https://cache.example.com
16
17# Platforms
18build:linux --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64
19build:macos --platforms=@io_bazel_rules_go//go/toolchain:darwin_amd64

Query Commands

 1# Find all targets
 2bazel query //...
 3
 4# Find dependencies
 5bazel query 'deps(//path/to:target)'
 6
 7# Find reverse dependencies
 8bazel query 'rdeps(//..., //path/to:target)'
 9
10# Find tests
11bazel query 'tests(//...)'
12
13# Find by kind
14bazel query 'kind("go_binary", //...)'
15
16# Output as graph
17bazel query --output=graph //path/to:target | dot -Tpng > graph.png

Remote Caching

 1# Setup remote cache
 2bazel build --remote_cache=grpc://cache.example.com:9092 //...
 3
 4# With authentication
 5bazel build \
 6  --remote_cache=grpcs://cache.example.com:443 \
 7  --google_default_credentials \
 8  //...
 9
10# Local disk cache
11bazel build --disk_cache=/tmp/bazel-cache //...

Remote Execution

1# Build with remote execution
2bazel build \
3  --remote_executor=grpc://executor.example.com:8980 \
4  --remote_cache=grpc://cache.example.com:9092 \
5  //...

Docker Integration

1# BUILD.bazel
2load("@io_bazel_rules_docker//container:container.bzl", "container_image")
3
4container_image(
5    name = "myapp_image",
6    base = "@alpine_linux_amd64//image",
7    entrypoint = ["/myapp"],
8    files = [":myapp"],
9)
1# Build Docker image
2bazel build //path/to:myapp_image
3
4# Load into Docker
5bazel run //path/to:myapp_image

Troubleshooting

 1# Clean build
 2bazel clean
 3
 4# Deep clean (removes all caches)
 5bazel clean --expunge
 6
 7# Verbose output
 8bazel build --verbose_failures //...
 9
10# Show commands
11bazel build --subcommands //...
12
13# Explain build
14bazel build --explain=explain.txt //...
15
16# Profile build
17bazel build --profile=profile.json //...
18
19# Analyze profile
20bazel analyze-profile profile.json

Best Practices

  1. Use Bazelisk - Automatically manages Bazel versions
  2. Keep BUILD files simple - One target per file when possible
  3. Use visibility - Control target access
  4. Enable remote caching - Speed up builds
  5. Use Gazelle - Auto-generate BUILD files for Go
  6. Version dependencies - Pin versions in WORKSPACE
  7. Test incrementally - bazel test //... regularly

Common Patterns

Monorepo Structure

 1my-project/
 2β”œβ”€β”€ WORKSPACE
 3β”œβ”€β”€ .bazelrc
 4β”œβ”€β”€ BUILD.bazel
 5β”œβ”€β”€ go.mod
 6β”œβ”€β”€ backend/
 7β”‚   β”œβ”€β”€ BUILD.bazel
 8β”‚   β”œβ”€β”€ main.go
 9β”‚   └── lib/
10β”‚       β”œβ”€β”€ BUILD.bazel
11β”‚       └── lib.go
12β”œβ”€β”€ frontend/
13β”‚   β”œβ”€β”€ BUILD.bazel
14β”‚   └── src/
15└── tools/
16    └── BUILD.bazel

Root BUILD.bazel

 1# BUILD.bazel
 2load("@bazel_gazelle//:def.bzl", "gazelle")
 3
 4# Generate BUILD files
 5gazelle(name = "gazelle")
 6
 7# Update dependencies
 8gazelle(
 9    name = "gazelle-update-repos",
10    args = [
11        "-from_file=go.mod",
12        "-to_macro=deps.bzl%go_dependencies",
13        "-prune",
14    ],
15    command = "update-repos",
16)

Related Snippets