load()
The load() function is used to include definitions (functions, macros, rules,
and constants) from another .bzl file.
In Buck2, load() executes a .bzl file and imports the specified symbols into
the current file's namespace. This allows you to share code across multiple
build files and create reusable build components.
Overview
The primary use cases for load() include:
- Sharing constants - Common configuration values used across multiple targets
- Defining macros - Functions that generate one or more build rules
- Importing rules - Custom rule definitions for specific build scenarios
- Utility functions - Helper functions for build logic
The load() function can be used in:
BUCKfiles (build files)PACKAGEfiles (package configuration)- Other
.bzlfiles (creating libraries of build code)
Syntax
load("//path/to/file:name.bzl", "symbol1", "symbol2", ...)
Or with aliases:
load("//path/to/file:name.bzl", alias1="symbol1", alias2="symbol2")
Arguments
-
Path (required): The first argument is a string specifying the label of the
.bzlfile to load. This follows Buck2's target label syntax:- Absolute:
//package/path:file.bzl - Relative to cell:
//package:defs.bzl - From external cell:
@cell//package:defs.bzl
- Absolute:
-
Symbols (required): One or more symbols to import from the specified file. These can be:
- Positional arguments - Import symbols with their original names:
"symbol1", "symbol2" - Keyword arguments - Import symbols with different names:
local_name="remote_name"
- Positional arguments - Import symbols with their original names:
Examples
Loading Constants
Suppose the file //core:defs.bzl contains:
COMPILER_FLAGS = [
"-Wall",
"-Werror",
"-O2",
]
JARS_TO_EXCLUDE = [
"//third_party/guava:guava",
"//third_party/jackson:jackson-core",
]
You can load these constants in a BUCK file:
load("//core:defs.bzl", "COMPILER_FLAGS", "JARS_TO_EXCLUDE")
cxx_binary(
name = "example",
srcs = ["main.cpp"],
compiler_flags = COMPILER_FLAGS,
)
Loading with Aliases
To avoid name collisions, you can rename symbols during import:
load("//core:defs.bzl", my_flags="COMPILER_FLAGS")
cxx_binary(
name = "example",
srcs = ["main.cpp"],
compiler_flags = my_flags,
)
Loading Macros
If //build_defs:macros.bzl contains:
def custom_library(name, srcs, **kwargs):
cxx_library(
name = name,
srcs = srcs,
compiler_flags = ["-std=c++17"],
**kwargs
)
You can load and use the macro:
load("//build_defs:macros.bzl", "custom_library")
custom_library(
name = "mylib",
srcs = ["lib.cpp"],
deps = ["//other:dep"],
)
Loading Custom Rules
load("//rules:custom.bzl", "my_custom_rule")
my_custom_rule(
name = "custom_target",
src = "input.txt",
)
Multiple Symbols
You can load multiple symbols in a single statement:
load(
"//common:defs.bzl",
"COMMON_FLAGS",
"helper_function",
local_rule="exported_rule",
)
Best Practices
Naming
- Use
UPPER_CASEfor constants - Use
snake_casefor functions and macros - Use descriptive names that indicate purpose
Visibility
.bzlfiles are automatically visible to any target that can see the package they're in- Use package visibility to control access to
.bzlfiles
Performance
- Avoid expensive computation in
.bzlfiles during load time .bzlfiles are evaluated once and cached, so minimize side effects- Keep
load()statements at the top of files for clarity
Common Patterns
Conditional Loading
While you cannot conditionally execute load() statements (they must be at the
top level), you can conditionally use the loaded symbols:
load("//config:settings.bzl", "ENABLE_FEATURE")
def maybe_add_feature(name, srcs):
if ENABLE_FEATURE:
feature_library(name=name, srcs=srcs)
else:
regular_library(name=name, srcs=srcs)
Re-exporting
You can create a .bzl file that re-exports symbols from other files:
# //defs:all.bzl
load("//defs:cpp.bzl", "cpp_macro")
load("//defs:python.bzl", "py_macro")
# Re-export for convenience
__all__ = ["cpp_macro", "py_macro"]
See Also
- Writing Rules - How to create custom build rules
- PACKAGE Files - Package-level configuration
- Build APIs - Available Starlark functions and types