Bazel Build System - Deploy and Usage Guide
Prerequisites
System Requirements
- Operating System: Linux (x86_64 or ARM64), macOS (Intel or Apple Silicon), or Windows (via WSL2 or native)
- Java Development Kit: OpenJDK 11 or newer (required for building Bazel from source)
- Python: 3.6+ (for build scripts and Skylark/Starlark tooling)
- Git: 2.20+ for repository cloning
- Bash: For build scripts and wrapper tools
Platform-Specific Dependencies
- macOS: Xcode command line tools (
xcode-select --install) - Linux:
build-essential,zip,unzip - Windows: Visual C++ Redistributable or WSL2 Ubuntu environment
Optional for Advanced Features
- Docker: For sandboxed builds and remote execution testing
- gRPC tools: For remote caching/execution setup (port 443/80 outbound access)
Installation
Method 1: Bazelisk (Recommended for Users)
Bazelisk is the launcher that automatically downloads the correct Bazel version for your project.
# macOS via Homebrew
brew install bazelisk
# Linux
npm install -g @bazel/bazelisk
# OR download directly
wget https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 -O /usr/local/bin/bazel
chmod +x /usr/local/bin/bazel
# Windows via Chocolatey
choco install bazelisk
Method 2: Direct Installation
# Ubuntu/Debian (via APT)
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
wget -qO - https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
sudo apt update && sudo apt install bazel
# macOS via Homebrew (direct bazel)
brew install bazel
Method 3: Build from Source (This Repository)
If you are deploying Bazel itself or contributing to the core:
# Clone the repository
git clone https://github.com/bazelbuild/bazel.git
cd bazel
# Build Bazel using the release script
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk # Adjust path as needed
bazel build //src:bazel --config=release
# The binary is now available at
./bazel-bin/src/bazel
Configuration
Environment Variables
# Set maximum heap size for Bazel's JVM (adjust based on available RAM)
export BAZEL_JVM_FLAGS="-Xmx8g -XX:MaxMetaspaceSize=512m"
# Cache configuration for CI environments
export BAZEL_CACHE_DIR="$HOME/.cache/bazel"
export BAZELISK_GITHUB_TOKEN="ghp_xxx" # For private GitHub releases via Bazelisk
# Remote execution credentials (if using RBE)
export BAZEL_REMOTE_CACHE="grpcs://remote.build.com:443"
export BAZEL_REMOTE_HEADER="Authorization: Bearer $(cat /secrets/token)"
Project Configuration (.bazelrc)
Create .bazelrc in your project root or user home:
# Performance optimization
build --jobs=auto
build --local_cpu_resources=HOST_CPUS*0.75
build --experimental_remote_merkle_tree_cache # Enable Merkle tree caching (as seen in source)
# Language-specific settings
build --java_runtime_version=11
build --tool_java_runtime_version=11
# Remote caching (optional)
build:remote --remote_cache=grpc://cache.example.com:9092
build:remote --remote_upload_local_results=true
build:remote --experimental_remote_cache_compression
# CI-specific flags
build:ci --color=yes
build:ci --curses=no
build:ci --show_timestamps
build:ci --announce_rc
build:ci --experimental_ui_max_stdouterr_bytes=1048576
# Test configuration
test --test_output=errors
test --test_verbose_timeout_warnings
Workspace Configuration (WORKSPACE.bazel)
# Load Starlark rules (referenced in StarlarkActionFactory.java)
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Example external dependency
http_archive(
name = "rules_java",
url = "https://github.com/bazelbuild/rules_java/releases/download/5.0.0/rules_java-5.0.0.tar.gz",
sha256 = "xxx",
)
Build & Run
Building Projects
# Build all targets in the current workspace
bazel build //...
# Build specific target
bazel build //src/main/java/com/google/devtools/build/lib:lib
# Build with specific configuration
bazel build //... --config=ci
# Build with remote execution
bazel build //... --config=remote --remote_executor=grpc://rbe.example.com:443
Running Tests
# Run all tests
bazel test //...
# Run specific test suite
bazel test //src/test/java/com/google/devtools/build/lib:AllTests
# Run with debugging
bazel test //src/test/... --test_output=streamed --test_strategy=standalone
# Flaky test handling (using Skyframe error processing from source)
bazel test //... --flaky_test_attempts=3 --test_verbose_timeout_warnings
Development Workflow
# Query dependency graph (using Resolver.java capabilities)
bazel query "deps(//src:bazel)" --output graph > graph.in
dot -Tpng graph.in -o graph.png
# Analyze build graph
bazel aquery "mnemonic(CppCompile, //src/...)" --output=text
# Clean and rebuild (incremental builds are default)
bazel clean --expunge # Deep clean including external repos
bazel build //src:bazel
Profiling and Debugging
# Generate build profile
bazel build //... --profile=/tmp/profile.gz
bazel analyze-profile /tmp/profile.gz
# Memory debugging
bazel dump --rules
bazel info used-heap-size-after-gc
Deployment
CI/CD Integration
GitHub Actions Example:
name: Build with Bazel
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Mount bazel cache
uses: actions/cache@v3
with:
path: "~/.cache/bazel"
key: bazel-${{ hashFiles('.bazelversion', '.bazelrc', 'WORKSPACE') }}
- name: Setup Bazel
uses: bazelbuild/setup-bazelisk@v2
- name: Build
run: bazel build //... --config=ci
- name: Test
run: bazel test //... --config=ci
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: bazel-bin
path: bazel-bin/**/*.jar
GitLab CI Example:
variables:
BAZEL_CACHE_DIR: "${CI_PROJECT_DIR}/.cache/bazel"
cache:
paths:
- .cache/bazel
build:
image: gcr.io/bazel-public/bazel:latest
script:
- bazel build //... --repository_cache=.cache/bazel-repo
- bazel test //... --test_output=errors
artifacts:
paths:
- bazel-bin/
Remote Execution Deployment
Deploy Bazel with Remote Build Execution (RBE) for distributed builds:
# Configure for remote execution (referencing MerkleTreeComputer.java for content addressing)
bazel build //... \
--remote_executor=grpcs://rbe.example.com:443 \
--remote_instance_name=projects/my-project/instances/default \
--remote_download_toplevel \
--experimental_remote_merkle_tree_cache \
--experimental_remote_merkle_tree_cache_size=1000
Container Deployment
# Build container images using rules_docker
bazel build //:app_image
bazel run //:app_image -- --norun # Load into Docker
# Push to registry
bazel run //:app_image_push
Release Deployment
# Create optimized release build
bazel build //src:bazel --stamp --config=release
# Deploy to artifact repository
cp bazel-bin/src/bazel /releases/bazel-$(cat .bazelversion)-linux-x86_64
Troubleshooting
Common Build Failures
Java Out of Memory Errors
# Error: "java.lang.OutOfMemoryError: Java heap space"
# Solution: Increase JVM heap in .bazelrc
build --host_jvm_args=-Xmx16g
build --host_jvm_args=-XX:ReservedCodeCacheSize=512m
Action Conflict Exceptions
# Error: "file 'path' is generated by conflicting actions"
# Solution: Clean and use --action_env for hermeticity
bazel clean --expunge
bazel build //... --action_env=PATH=/usr/local/bin:/usr/bin:/bin
Skyframe Errors (from SkyframeErrorProcessor.java patterns)
# Error: Cyclic dependency detected
# Solution: Query the cycle
bazel query "deps(//:target)" --output=graph | grep -C5 "cycle"
# Error: Action execution failures
# Solution: Use --verbose_failures and --sandbox_debug
bazel build //... --verbose_failures --sandbox_debug
Cache and Performance Issues
Remote Cache Timeouts
# Adjust timeouts for slow networks
build --remote_timeout=3600
build --remote_upload_local_results=false # If upload is bottleneck
Merkle Tree Computation Issues
# If using remote execution with Merkle tree errors (from MerkleTreeComputer.java)
build --experimental_remote_merkle_tree_cache=false # Disable if corrupted
bazel clean --expunge_async # Async clean to avoid blocking
Platform-Specific Issues
macOS: Xcode License Issues
sudo xcodebuild -license accept
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
Windows: Long Path Issues
# Enable long paths in Windows 10+
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
# Use --enable_runfiles in .bazelrc
Linux: Inotify Limits
# Error: "No space left on device" (often inotify, not disk)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Debug Logging
# Enable verbose Starlark debugging (referencing Resolver.java error handling)
bazel build //... --explain=/tmp/explain.log --verbose_explanations
bazel build //... --java_debug --experimental_worker_debug
# Profile Skylark execution
bazel build //... --starlark_cpu_profile=/tmp/profile.pprof
Getting Help
# Check Bazel version and environment
bazel version
bazel info
bazel dump --memory=full > /tmp/memory.txt
# Report issues with reproducibility
bazel build //... --experimental_ui_max_stdouterr_bytes=1048576 --show_timestamps