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
- *offizielle Dokumentation: bazel.build
- Benutzerhandbuch: bazel.build/docs
- *Rules Repository: [github.com/bazelbuild](https://__LINK_4___
- Beste Praktiken: bazel.build/docs/best-practices