콘텐츠로 이동

Bazel 치트시트

개요

Bazel은 Google에서 개발한 빠르고 확장 가능한 다중 언어 빌드 도구입니다. 대규모 코드베이스를 지원하고, 빠른 증분 빌드를 제공하며, 다양한 플랫폼에서 재현 가능한 빌드를 제공합니다.

설치

패키지 관리자

# 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
```(No text provided)

### 검증
```bash
bazel version
```(No text provided)

## 기본 개념

### 주요 용어

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


### 프로젝트 구조

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


## WORKSPACE 파일

### 기본 WORKSPACE
```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")
```(No text provided)

### 외부 의존성
```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",
)
```(No text provided)

## BUILD 파일

### Java 예시
```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",
    ],
)
```(No text provided)

### Python 예시
```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",
    ],
)
```(No text provided)

### Go 예시
```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"],
)
```(No text provided)

### C++ 예시
```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",
    ],
)
```(No text provided)

## 명령줄 사용법

### 기본 명령어
```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
```(No text provided)

### 고급 옵션
```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
```(No text provided)

### 구성
```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
```(No text provided)

## 구성 (.bazelrc)

### 기본 구성
```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
```(No text provided)

### 고급 구성
```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
```(No text provided)

## 규칙 및 매크로

### 사용자 정의 규칙
```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),
    \\\\},
)
```(No text provided)

### 매크로
```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"],
)
```(No text provided)

### 측면
```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
```(No text provided)

## 테스팅

### 테스트 구성
```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",
    ],
)
```(No text provided)

### 테스트 실행
```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
```## 다국어 프로젝트
```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()
```### 워크스페이스 설정
```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"],
)
```### 크로스 언어 의존성
```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
```## 성능 최적화
```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
```### 빌드 성능
```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
```### 메모리 관리
```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"
```## 디버깅

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

```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", ...)
```### 쿼리 및 분석
```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"],
)
```## 모범 사례
```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
```### 프로젝트 구조
```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
```### 타겟 이름 지정
https://bazel.build/##

# 가시성 관리
https://bazel.build/docs#

# 문제 해결
https://github.com/bazelbuild##

# 일반적인 문제
https://bazel.build/docs/best-practices##

# 성능 문제