BUILD Files in Bazel
This guide explains how to write and organize BUILD files effectively.
What are BUILD Files?
BUILD files are the core of Bazel's build system. They define:
- Targets that can be built
- Dependencies between targets
- Build rules and their attributes
- Package visibility and constraints
Basic Structure
python
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
package(default_visibility = ["//visibility:private"])
cc_library(
name = "hello_lib",
srcs = ["hello.cc"],
hdrs = ["hello.h"],
visibility = ["//visibility:public"],
)
cc_binary(
name = "hello_world",
srcs = ["main.cc"],
deps = [":hello_lib"],
)Target Naming
Target names should be:
- Descriptive and meaningful
- Lowercase with underscores
- Unique within the package
- Related to their function
Example:
python
cc_library(
name = "string_utils", # Good: descriptive
srcs = ["string_utils.cc"],
)Common Rules
Built-in rules for various languages:
python
# C/C++
cc_binary(name = "app")
cc_library(name = "lib")
cc_test(name = "test")
# Java
java_binary(name = "app")
java_library(name = "lib")
java_test(name = "test")
# Python
py_binary(name = "app")
py_library(name = "lib")
py_test(name = "test")
# Protocol Buffers
proto_library(name = "proto")Visibility
Control who can depend on your targets:
python
package(default_visibility = ["//visibility:private"])
cc_library(
name = "internal_lib",
# Uses package default visibility
)
cc_library(
name = "public_lib",
visibility = ["//visibility:public"],
)
cc_library(
name = "limited_lib",
visibility = [
"//my/package:__subpackages__",
"//other/package:__pkg__",
],
)Dependencies
Different types of dependencies:
python
cc_binary(
name = "app",
deps = [
":local_lib", # Within same package
"//other/package:lib", # Different package
"@external_repo//:lib", # External repository
],
data = ["//path/to:data_file"], # Runtime dependencies
)Best Practices
Package Organization
- Keep BUILD files close to source
- One BUILD file per directory
- Group related targets together
Target Design
- Make targets as small as practical
- Avoid circular dependencies
- Use appropriate visibility
Dependencies
- Minimize dependency chains
- Use precise dependencies
- Document non-obvious deps
Maintainability
- Use buildifier for formatting
- Document complex build rules
- Use macros for repetitive patterns
Common Patterns
Test Targets
python
cc_test(
name = "lib_test",
srcs = ["lib_test.cc"],
deps = [
":lib",
"@com_google_googletest//:gtest_main",
],
)Data Dependencies
python
py_binary(
name = "tool",
srcs = ["tool.py"],
data = [
"//path/to:config.json",
"//path/to:resources",
],
)