Skip to main content
Bazel is a fast, scalable build system that works well for large projects and provides excellent support for reproducible builds and remote caching.
Bazel support in Z3 is primarily tested on Ubuntu with Clang but may work on other platforms and compilers.

Prerequisites

  • Bazel - Install from bazel.build
  • C++20 compiler - Clang recommended, GCC also supported
  • Python - For some build steps

Quick Start

Build all Z3 targets:
That’s it! Bazel handles dependency resolution, configuration, and compilation automatically.

Installation

Linux (Ubuntu/Debian)

macOS

Windows

Basic Usage

Build All Targets

Build everything in the repository:

Build Specific Targets

Build only the Z3 library:

Run Tests

Run all tests:

Clean Build

Remove build artifacts:
Deep clean (removes all cached data):

Build Configuration

Optimization Levels

Bazel supports different compilation modes:

Compiler Selection

Use a specific compiler:
Z3’s Bazel build is primarily tested with Clang on Ubuntu. Other configurations may require adjustments.

Platform-Specific Options

For cross-compilation or specific platforms:

Advanced Features

Parallel Builds

Bazel automatically parallelizes builds. Control job count:

Remote Caching

Enable remote caching for faster builds across machines:

Build Event Protocol

Generate build event logs:

Verbose Output

Show detailed build information:

Bazel Configuration File

Create a .bazelrc file in the repository root for persistent settings:
Then simply run:

Workspace Structure

Bazel uses BUILD files to define targets. Z3’s structure includes:

Common Targets

Library Targets

Executable Targets

Test Targets

Querying Build Graph

Bazel provides powerful query capabilities:

Integration with IDEs

VS Code

Install the Bazel extension:

CLion

CLion has built-in Bazel support:
  1. Open the Z3 repository
  2. Select File → Project Structure
  3. Choose Bazel as the project type

Compilation Database

Generate compile_commands.json for other IDEs:

Troubleshooting

Build Failures

Clean and rebuild:
For persistent issues:

Compiler Not Found

Specify compiler explicitly:

Slow Builds

Enable remote caching or increase parallelism:

Dependency Issues

Show the dependency graph:

Cache Problems

Clear the Bazel cache:

Comparison with Other Build Systems

Best Practices

Use Bazelisk

Bazelisk automatically downloads the correct Bazel version:

Configure .bazelrc

Store common options in .bazelrc instead of typing them:

Use Query for Understanding

Before modifying build files, understand dependencies:

Remote Caching for CI

Set up remote caching for continuous integration to speed up builds:

Performance Tips

  1. Use --jobs=auto - Let Bazel optimize parallelism
  2. Enable remote caching - Share build artifacts across machines
  3. Use bazel-compilation-database - For better IDE integration
  4. Avoid bazel clean - Let Bazel manage incremental builds
  5. Use .bazelrc - Configure once, build everywhere

When to Use Bazel

Bazel is ideal when:
  • Building large codebases with many dependencies
  • You need reproducible builds
  • Working in a team with shared build cache
  • Cross-compilation is required
  • Integration with other Bazel projects
Consider CMake instead if:
  • You need extensive IDE support
  • Building small to medium projects
  • You need OCaml bindings (use Make)
  • Team is more familiar with CMake

Next Steps