Skip to content

Configuration and Toolchains

This guide explains how Bazel ensures consistent builds across different environments through configuration and toolchains.

Understanding Build Configuration

When you build software, you need to consider:

  • What machine will run the code? (target platform)
  • What machine will build the code? (host platform)
  • What tools are needed to build the code? (toolchain)

For example, you might want to:

  • Build Android apps on a Linux machine
  • Compile Windows executables on macOS
  • Build ARM64 binaries on an x86_64 system

Bazel handles this through three key concepts:

  1. Platforms (define where code runs and builds)
  2. Toolchains (provide the tools needed)
  3. Configuration (connect platforms to toolchains)

Platforms

A platform represents a specific environment where code either:

  • Runs (target platform)
  • Gets built (host platform)
python
platform(
    name = "linux_arm64",
    constraint_values = [
        "@platforms//cpu:arm64",
        "@platforms//os:linux",
    ],
)

Common platform examples:

  • @platforms//cpu:x86_64 + @platforms//os:linux
  • @platforms//cpu:arm64 + @platforms//os:android
  • @platforms//cpu:x86_64 + @platforms//os:windows

Toolchains

A toolchain is a set of tools needed to build code, such as:

  • Compilers
  • Linkers
  • Code generators
  • Build utilities

Instead of specifying these tools directly, Bazel uses toolchains to:

  1. Define what tools are needed
  2. Select the right tools for each platform
  3. Configure the tools correctly

Example: C++ Toolchain

python
# No need to specify compiler directly
cc_binary(
    name = "hello",
    srcs = ["hello.cc"],
)

# Bazel automatically:
# 1. Finds the right C++ toolchain for your platform
# 2. Uses the correct compiler and flags
# 3. Links with the right libraries

Cross-compilation

One of the main benefits of toolchains is cross-compilation:

python
# Build an ARM64 binary on an x86_64 machine
bazel build //my:binary \
    --platforms=@platforms//cpu:arm64

Bazel will:

  1. Use your x86_64 machine as the host platform
  2. Target ARM64 as the target platform
  3. Find a toolchain that can build ARM64 code
  4. Configure the toolchain correctly

Configuration Files

Common settings go in .bazelrc:

python
# Default to optimized builds
build --compilation_mode=opt

# Build for ARM64 by default
build --platforms=@platforms//cpu:arm64

# Use specific C++ compiler
build --cpp_compiler=clang

Advanced Topics

Creating Custom Toolchains

For specialized build requirements, you can create custom toolchains:

python
toolchain_type(
    name = "custom_compiler_toolchain",
)

# Implementation details in later sections...

Platform Constraints

Platforms can have custom constraints:

python
constraint_setting(name = "gpu")
constraint_value(
    name = "cuda",
    constraint_setting = ":gpu",
)

Best Practices

  1. Platform Selection

    • Use standard platforms when possible
    • Define custom platforms only when needed
    • Document platform requirements
  2. Toolchain Management

    • Keep toolchains self-contained
    • Provide clear interfaces
    • Test with all supported platforms
  3. Configuration

    • Use .bazelrc for common settings
    • Keep platform-specific configs separate
    • Document configuration options

Common Issues

Wrong Platform

bash
ERROR: Target platform does not match constraints
  • Check platform constraints
  • Verify toolchain compatibility
  • Review build configuration

Missing Toolchain

bash
ERROR: no matching toolchain found
  • Ensure toolchain is registered
  • Check platform compatibility
  • Verify toolchain implementation

Next Steps

Released under the MIT License.