bazel query and similar
commands to explore Bazel’s dependency graph for at least one language.
DefinitionA Bazel “package” is a folder containing a
BUILD or BUILD.bazel file, along with subfolders that don’t have one of these files. It is a “collection of related files and a specification of how to use them to produce output artifacts”.BUILD file is written in a subset of Starlark.
Starlark is a configuration language with performance guarantees, and the BUILD file subset is roughly the declarative constructs. Things like for loops are not legal syntax in BUILD files, but list comprehensions are.
glob
The glob function allows you to use wildcard patterns to choose source files. However, it does come with some performance penalties.
Using list comprehensions together with glob is a powerful way to stamp out targets, for example:
Writing BUILD files
There are three typical ways to create and maintain BUILD files.
Automatically
The computer should be expected to maintain 80% of theBUILD files, since most of their content may be inferred from the source files. Product developers consider it a regression to have to repeat import statements as deps for Bazel’s benefit.
Gazelle is a popular tool with extensions available for several languages.
Add an import statement, run the tool, and the relevant BUILD file is updated to reflect it.
The
configure subcommand is specific to Aspect CLI, providing a
straightforward and uniform way to invoke build file generation. Projects using
core Bazel only can direct developer to run a suitable script instead.Machine-editing
You can usebuildozer to script around printing and modifying BUILD file content, which is an essential skill for doing repository-wide refactoring.
Buildozer is purely syntactic, operating on the Starlark Abstract Syntax Tree (AST).
This is convenient if you want to see what the user typed, before loading and macro expansion occur. It’s also guaranteed to be fast, while loading might take a long time.
There’s a dedicated
aspect print command to make this feature easier to access.By Hand
While the situation has improved tremendously in recent years, 20% ofBUILD
files are typically hand-edited, because:
- They do things not described by the source files, or
- They are for languages with no Gazelle support available (yet)
Eager load
Warning: the load statement is evaluated immediately in the loading phase, and extends to every reachable transitive starlark file, including those defined in external repositories. This can lead to long, unnecessary downloads! It’s also difficult for product engineers to understand how the graph shape contributes to slow builds.
When a package requires loading from many different languages or extensions, this can be a smell which indicates the sources should be re-organized. For example you might want a different subfolder for each language.
In this example, a BUILD file loads from @npm:
filegroup named b, the load statement means that the @npm repository must be fetched.
Here’s a fictitious worst-case example, defaults.bzl
Read more: avoid eager fetches

