Zum Inhalt

Bazel Cheatsheet

Überblick

Bazel ist ein schnelles, skalierbares, mehrsprachiges Build-Tool von Google entwickelt. Es unterstützt große Codebasen, bietet schnelle inkrementelle Builds und bietet reproduzierbare Builds auf verschiedenen Plattformen.

Installation

Paketmanager

# macOS
brew install bazel

# Ubuntu/Debian
curl -fsSL https://bazel.build/bazel-release.pub.gpg|gpg --dearmor > bazel.gpg
sudo mv bazel.gpg /etc/apt/trusted.gpg.d/
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8"|sudo tee /etc/apt/sources.list.d/bazel.list
sudo apt update && sudo apt install bazel

# CentOS/RHEL
sudo dnf copr enable vbatts/bazel
sudo dnf install bazel

# Windows (Chocolatey)
choco install bazel

# Manual installation
wget https://github.com/bazelbuild/bazel/releases/download/6.0.0/bazel-6.0.0-installer-linux-x86_64.sh
chmod +x bazel-6.0.0-installer-linux-x86_64.sh
./bazel-6.0.0-installer-linux-x86_64.sh --user
```_

### Überprüfung
```bash
bazel version
```_

## Grundkonzepte

### Schlüsselbegriffe

Workspace # Root directory containing WORKSPACE file Package # Directory containing BUILD file Target # Buildable unit (binary, library, test) Label # Unique identifier for targets Rule # Function that defines how to build targets


### Projektstruktur

workspace/ ├── WORKSPACE ├── .bazelrc ├── BUILD ├── src/ │ ├── main/ │ │ ├── java/ │ │ └── BUILD │ └── test/ │ ├── java/ │ └── BUILD └── third_party/ └── BUILD


## WORKSPACE Datei

### ARBEITSPACE
```python
workspace(name = "my_project")

# Load rules
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# Java rules
http_archive(
    name = "rules_java",
    urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.0.0/rules_java-6.0.0.tar.gz"],
    sha256 = "469b7f3b580b4fcf8112f4d6d0d5a4ce8e1ad5e21fee67d8e8335d5f018f7a4a",
)

# Python rules
http_archive(
    name = "rules_python",
    sha256 = "8c8fe44ef0a9afc256d1e75ad5f448bb59b81aba149b8958f02f7b3a98f5d9b4",
    strip_prefix = "rules_python-0.13.0",
    url = "https://github.com/bazelbuild/rules_python/archive/refs/tags/0.13.0.tar.gz",
)

# Go rules
http_archive(
    name = "io_bazel_rules_go",
    sha256 = "099a9fb96a376ccbbb7d291ed4ecbdfd42f6bc822ab77ae6f1b5cb9e914e94fa",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains(version = "1.19.3")
```_

### Externe Abhängigkeiten
```python
# Maven dependencies
load("@rules_jvm_external//:defs.bzl", "maven_install")

maven_install(
    artifacts = [
        "junit:junit:4.13.2",
        "com.google.guava:guava:31.1-jre",
        "org.apache.commons:commons-lang3:3.12.0",
    ],
    repositories = [
        "https://repo1.maven.org/maven2",
    ],
)

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

git_repository(
    name = "com_google_protobuf",
    remote = "https://github.com/protocolbuffers/protobuf",
    tag = "v3.21.7",
)

# Local repository
local_repository(
    name = "my_local_repo",
    path = "/path/to/local/repo",
)
```_

## BUILD-Dateien

### Java Beispiel
```python
# Load rules
load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_test")

# Java library
java_library(
    name = "hello-lib",
    srcs = ["src/main/java/com/example/Hello.java"],
    deps = [
        "@maven//:com_google_guava_guava",
        "@maven//:org_apache_commons_commons_lang3",
    ],
    visibility = ["//visibility:public"],
)

# Java binary
java_binary(
    name = "hello-world",
    srcs = ["src/main/java/com/example/Main.java"],
    main_class = "com.example.Main",
    deps = [":hello-lib"],
)

# Java test
java_test(
    name = "hello-test",
    srcs = ["src/test/java/com/example/HelloTest.java"],
    test_class = "com.example.HelloTest",
    deps = [
        ":hello-lib",
        "@maven//:junit_junit",
    ],
)
```_

### Python Beispiel
```python
load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")

# Python library
py_library(
    name = "hello_lib",
    srcs = ["hello_lib.py"],
    deps = [
        "@pip//requests",
        "@pip//numpy",
    ],
    visibility = ["//visibility:public"],
)

# Python binary
py_binary(
    name = "hello_world",
    srcs = ["main.py"],
    deps = [":hello_lib"],
    python_version = "PY3",
)

# Python test
py_test(
    name = "hello_test",
    srcs = ["hello_test.py"],
    deps = [
        ":hello_lib",
        "@pip//pytest",
    ],
)
```_

### Beispiel
```python
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")

# Go library
go_library(
    name = "hello_lib",
    srcs = ["hello.go"],
    importpath = "github.com/example/hello",
    visibility = ["//visibility:public"],
    deps = [
        "@com_github_gorilla_mux//:mux",
    ],
)

# Go binary
go_binary(
    name = "hello_world",
    embed = [":hello_lib"],
)

# Go test
go_test(
    name = "hello_test",
    srcs = ["hello_test.go"],
    embed = [":hello_lib"],
)
```_

### C++ Beispiel
```python
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")

# C++ library
cc_library(
    name = "hello_lib",
    srcs = ["hello.cc"],
    hdrs = ["hello.h"],
    deps = [
        "@com_google_absl//absl/strings",
    ],
    visibility = ["//visibility:public"],
)

# C++ binary
cc_binary(
    name = "hello_world",
    srcs = ["main.cc"],
    deps = [":hello_lib"],
)

# C++ test
cc_test(
    name = "hello_test",
    srcs = ["hello_test.cc"],
    deps = [
        ":hello_lib",
        "@com_google_googletest//:gtest_main",
    ],
)
```_

## Verwendung der Befehlszeile

### Grundlegende Befehle
```bash
# Build target
bazel build //src:hello-world
bazel build //...  # Build all targets

# Run binary
bazel run //src:hello-world

# Test
bazel test //src:hello-test
bazel test //...  # Test all targets

# Clean
bazel clean
bazel clean --expunge  # Deep clean

# Query
bazel query //...
bazel query "deps(//src:hello-world)"

# Info
bazel info
bazel version
```_

### Erweiterte Optionen
```bash
# Parallel builds
bazel build //... --jobs=8

# Verbose output
bazel build //... --verbose_failures

# Compilation mode
bazel build //... --compilation_mode=opt  # optimized
bazel build //... --compilation_mode=dbg  # debug

# Platform-specific builds
bazel build //... --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64

# Remote execution
bazel build //... --remote_executor=grpc://remote-executor:8980

# Build with specific flags
bazel build //... --copt=-O2 --linkopt=-static

# Test with specific options
bazel test //... --test_output=all --test_verbose_timeout_warnings
```_

### Konfiguration
```bash
# Use .bazelrc file
bazel build //...  # Uses settings from .bazelrc

# Override config
bazel build //... --config=release

# Set flags
bazel build //... --define=version=1.0.0
```_

## Konfiguration (.bazelrc)

### Grundkonfiguration
```bash
# Build settings
build --compilation_mode=opt
build --copt=-O2
build --copt=-DNDEBUG

# Test settings
test --test_output=errors
test --test_verbose_timeout_warnings

# Common flags
common --enable_platform_specific_config

# Platform-specific settings
build:linux --copt=-fPIC
build:macos --copt=-Wno-deprecated-declarations
build:windows --copt=/W3

# Configuration aliases
build:release --compilation_mode=opt --strip=always
build:debug --compilation_mode=dbg --strip=never

# Remote execution
build:remote --remote_executor=grpc://remote-executor:8980
build:remote --remote_cache=grpc://remote-cache:8981
```_

### Erweiterte Konfiguration
```bash
# Memory settings
build --local_ram_resources=8192
build --local_cpu_resources=8

# Disk cache
build --disk_cache=/tmp/bazel-cache

# Remote cache
build --remote_cache=https://storage.googleapis.com/my-bazel-cache

# Build event service
build --bes_backend=grpc://build-event-service:8982
build --bes_results_url=https://my-build-results.com/

# Execution strategies
build --spawn_strategy=sandboxed
build --strategy=Javac=worker
build --strategy=CppCompile=sandboxed

# Sandboxing
build --sandbox_debug
build --sandbox_writable_path=/tmp
```_

## Regeln und Makros

### Zollvorschriften
```python
# rules.bzl
def _my_rule_impl(ctx):
    output = ctx.actions.declare_file(ctx.label.name + ".out")
    ctx.actions.run_shell(
        inputs = ctx.files.srcs,
        outputs = [output],
        command = "cat \\\\{\\\\} > \\\\{\\\\}".format(" ".join([f.path for f in ctx.files.srcs]), output.path),
    )
    return [DefaultInfo(files = depset([output]))]

my_rule = rule(
    implementation = _my_rule_impl,
    attrs = \\\\{
        "srcs": attr.label_list(allow_files = True),
    \\\\},
)
```_

### Macros
```python
# macros.bzl
def java_service(name, srcs, deps = [], **kwargs):
    """Macro to create a Java service with common dependencies."""
    java_library(
        name = name + "_lib",
        srcs = srcs,
        deps = deps + [
            "@maven//:com_google_guava_guava",
            "@maven//:org_slf4j_slf4j_api",
        ],
        **kwargs
    )

    java_binary(
        name = name,
        main_class = "com.example.Main",
        runtime_deps = [name + "_lib"],
        **kwargs
    )

# Usage in BUILD file
load("//tools:macros.bzl", "java_service")

java_service(
    name = "my_service",
    srcs = ["Main.java", "Service.java"],
    deps = ["//common:utils"],
)
```_

### Aspekte
```python
# aspects.bzl
def _print_aspect_impl(target, ctx):
    print("Target: %s" % target.label)
    return []

print_aspect = aspect(
    implementation = _print_aspect_impl,
    attr_aspects = ["deps"],
)

# Usage
bazel build //src:hello-world --aspects=//tools:aspects.bzl%print_aspect
```_

## Prüfung

### Testkonfiguration
```python
# BUILD file
java_test(
    name = "integration_test",
    srcs = ["IntegrationTest.java"],
    deps = [
        ":hello_lib",
        "@maven//:junit_junit",
    ],
    size = "large",
    timeout = "long",
    tags = ["integration"],
    data = ["//testdata:sample_files"],
    jvm_flags = ["-Xmx2g"],
)

# Test suite
test_suite(
    name = "all_tests",
    tests = [
        ":unit_tests",
        ":integration_tests",
    ],
)
```_

### Testausführung
```bash
# Run specific test
bazel test //src:hello_test

# Run tests by tag
bazel test //... --test_tag_filters=unit
bazel test //... --test_tag_filters=-integration

# Run tests by size
bazel test //... --test_size_filters=small,medium

# Parallel test execution
bazel test //... --local_test_jobs=4

# Test with coverage
bazel coverage //src:hello_test
```_

## Mehrsprachige Projekte

### Workspace Setup
```python
# WORKSPACE
workspace(name = "multi_lang_project")

# Java
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(name = "rules_java", ...)

# Python
http_archive(name = "rules_python", ...)
load("@rules_python//python:pip.bzl", "pip_install")
pip_install(
    name = "pip",
    requirements = "//python:requirements.txt",
)

# Go
http_archive(name = "io_bazel_rules_go", ...)
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains(version = "1.19.3")

# Protocol Buffers
http_archive(name = "com_google_protobuf", ...)
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
```_

### Querverweise Abhängigkeiten
```python
# proto/BUILD
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_java//java:defs.bzl", "java_proto_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")

proto_library(
    name = "api_proto",
    srcs = ["api.proto"],
    visibility = ["//visibility:public"],
)

java_proto_library(
    name = "api_java_proto",
    deps = [":api_proto"],
)

go_proto_library(
    name = "api_go_proto",
    importpath = "github.com/example/api",
    proto = ":api_proto",
)

# java/BUILD
java_library(
    name = "java_service",
    srcs = ["Service.java"],
    deps = ["//proto:api_java_proto"],
)

# go/BUILD
go_library(
    name = "go_service",
    srcs = ["service.go"],
    deps = ["//proto:api_go_proto"],
)
```_

## Leistungsoptimierung

### Leistung steigern
```bash
# .bazelrc optimizations
build --local_ram_resources=HOST_RAM*.8
build --local_cpu_resources=HOST_CPUS
build --jobs=auto

# Disk cache
build --disk_cache=/tmp/bazel-cache

# Remote cache
build --remote_cache=grpc://cache-server:8080

# Build without the bytes
build --remote_download_minimal

# Incremental builds
build --experimental_reuse_sandbox_directories
```_

### Speicherverwaltung
```bash
# Limit memory usage
build --local_ram_resources=8192  # 8GB
startup --host_jvm_args=-Xmx4g

# Garbage collection
startup --host_jvm_args=-XX:+UseG1GC
startup --host_jvm_args=-XX:MaxGCPauseMillis=200
```_

## Debugging

### Debugging erstellen
```bash
# Verbose output
bazel build //... --verbose_failures
bazel build //... --subcommands

# Explain build
bazel build //... --explain=explain.log
bazel build //... --verbose_explanations

# Profile build
bazel build //... --profile=profile.json

# Sandbox debugging
bazel build //... --sandbox_debug
bazel build //... --spawn_strategy=standalone
```_

### Abfrage und Analyse
```bash
# Dependency analysis
bazel query "deps(//src:hello-world)"
bazel query "rdeps(//..., //common:utils)"

# Build graph
bazel query --output=graph //...|dot -Tpng > graph.png

# Action graph
bazel aquery //src:hello-world

# Configuration
bazel cquery //src:hello-world --output=starlark --starlark:expr="target.label"
```_

## Best Practices

### Projektstruktur

workspace/ ├── WORKSPACE ├── .bazelrc ├── BUILD.bazel ├── tools/ │ ├── BUILD.bazel │ └── rules.bzl ├── third_party/ │ └── BUILD.bazel ├── src/ │ ├── main/ │ │ └── BUILD.bazel │ └── test/ │ └── BUILD.bazel └── docs/ └── BUILD.bazel ```_

Zielvorstellung

```python

Use descriptive names

java_library( name = "user_service_lib", # Not just "lib" srcs = ["UserService.java"], )

Group related targets

java_library(name = "auth_lib", ...) java_test(name = "auth_test", ...) java_binary(name = "auth_server", ...)

Use consistent patterns

cc_library(name = "foo_lib", ...) cc_test(name = "foo_test", ...) ```_

Visibilitätsmanagement

```python

Package-level visibility

package(default_visibility = ["//visibility:private"])

Specific visibility

java_library( name = "internal_lib", visibility = ["//src/main:subpackages"], )

Public libraries

java_library( name = "public_api", visibility = ["//visibility:public"], ) ```_

Fehlerbehebung

Gemeinsame Themen

```bash

Clear cache

bazel clean --expunge

Check workspace

bazel info workspace

Verify dependencies

bazel query "deps(//src:target)"

Check build configuration

bazel config

Analyze failures

bazel build //... --verbose_failures --keep_going ```_

Leistungsfragen

```bash

Profile build

bazel build //... --profile=profile.json bazel analyze-profile profile.json

Memory analysis

bazel dump --rules bazel dump --skylark_memory

Cache analysis

bazel info repository_cache bazel info output_base ```_

Ressourcen