Bazel Reference
Kip Landergren
(Updated: )
My cheat sheet for Bazel covering useful resources and FAQs.
Contents
- Installation
- Debugging
- New Project Initialization
- Commands
- Options
- Make Variables
- gazelle
- Rulesets
- ibazel
- Terminology
- Frequently Asked Questions (FAQ)
- Resources
Installation
Use bazelisk, which is a:
- launcher for bazel
- bazel version manager
brew install bazelisk
Note: on installation via homebrew, both bazelisk and bazel are added to $PATH resolving to the bazelisk binary.
Debugging
bazel build --sandbox_debug --verbose_failures //...
New Project Initialization
Bazel 8
echo "module(name = \"myproject\")" > ./MODULE.bazel
If using bazelisk:
echo '8.4.2' > ./.bazelversion
Commands
| info | |
| config | |
| query | query the build graph (specifically: the post-loading phase target graph, before options are evaluated) |
| cquery | configurable query; query the build graph, taking into account select() and build options (specifically: the post-analysis configured target graph) |
| aquery | action graph query; query for actions in the build graph (specifically: actions from the post-analysis configured target graph) |
bazel info
bazel info execution_root
bazel config
bazel config <configuration key>
bazel build
bazel build //foo/bar:baz
bazel build //...
bazel clean
Remove Bazel-created outputs:
bazel clean
Remove the entire working tree created by a Bazel instance:
bazel clean --expunge
bazel help
bazel help [COMMAND]
bazel mod
bazel mod tidy
bazel query
Query all targets in workspace:
bazel query //...
Query all targets in my/package:
bazel query //my/package/...
bazel cquery
Executes a post-analysis dependency graph query. cquery essentially says “what does this target expression resolve to?”.
% bazel cquery 'deps(//:foo)'
Computing main repo mapping:
Loading:
Loading: 0 packages loaded
Analyzing: target //:foo (0 packages loaded, 0 targets configured)
INFO: Analyzed target //:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
//:foo (89f88d5)
@platforms//host:host (8d4a62c)
@bazel_tools//tools/genrule:genrule-setup.sh (null)
//:list.txt (null)
@bazel_tools//tools:host_platform (8d4a62c)
@platforms//os:osx (8d4a62c)
@platforms//cpu:x86_64 (8d4a62c)
@platforms//os:os (8d4a62c)
@platforms//cpu:cpu (8d4a62c)
INFO: Elapsed time: 0.143s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 0 total actions
About the configuration identifiers:
| //:foo (89f88d5) | 89f88d5, the configuration identifier associated with the bazel command-line flags used for this target |
| @platforms//host:host (8d4a62c) | 8d4a62c, the configuration identifier for platform resolution |
| @bazel_tools//tools/genrule:genrule-setup.sh (null) | null configuration identifier because it is a source file |
| //:list.txt (null) | null configuration identifier because it is a source file |
| @bazel_tools//tools:host_platform (8d4a62c) | 8d4a62c |
| @platforms//os:osx (8d4a62c) | 8d4a62c |
| @platforms//cpu:x86_64 (8d4a62c) | 8d4a62c |
| @platforms//os:os (8d4a62c) | 8d4a62c |
| @platforms//cpu:cpu (8d4a62c) | 8d4a62c |
bazel aquery
% bazel aquery //:foo
Computing main repo mapping:
Loading:
Loading: 0 packages loaded
Analyzing: target //:foo (0 packages loaded, 0 targets configured)
INFO: Analyzed target //:foo (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
action 'Executing genrule //:foo'
Mnemonic: Genrule
Target: //:foo
Configuration: darwin_x86_64-fastbuild
Execution platform: @platforms//host:host
ActionKey: 234f068ae935f30a82f3f9778cba12fceb572067fbe4b5cc64e790fbcaa64f5b
Inputs: [external/bazel_tools/tools/genrule/genrule-setup.sh, list.txt]
Outputs: [bazel-out/darwin_x86_64-fastbuild/bin/foo.txt]
Environment: [PATH=/nix/store/93lxfa3hg9944zd0wsb2pvy20l9p0z1n-bash-interactive-5.3p9/bin:/nix/store/5m3k4f22kg542p2lr4ikk2xj6grlmvrg-coreutils-9.11/bin:/nix/store/i8ix8mqzcllzigx9dy046axn3g0w08cp-diffutils-3.12/bin:/nix/store/lnxqsqi2shcq5pidbbadljna7haasy55-file-5.47/bin:/nix/store/ix0a9p3m012l4d59w3g1lfsdx2azdn08-findutils-4.10.0/bin:/nix/store/nrjma0cjf0w66v99chkyayr3lh70q9yp-gawk-5.4.0/bin:/nix/store/b64rpqqkc7c53vd77g48g9hs0hy889s2-gnugrep-3.12/bin:/nix/store/lc3km2yx9pcw5qp5kb7v1pbp11g7n44j-patch-2.8/bin:/nix/store/cvkh602mhz8jyq4hnajkkm22xbyc3ndg-gnused-4.9/bin:/nix/store/9z132234zlrg0fgmsychpi86a762mmwi-gnutar-1.35/bin:/nix/store/cg0dga307n1m8m1hg7hkys3fw2hlxb7d-gzip-1.14/bin:/nix/store/fyyi8b1dpk3xpjnn52rznnpvlyivds97-python3-3.13.13/bin:/nix/store/zbara2rlmdaaf71hxxdq9qrwbx7jly9f-unzip-6.0/bin:/nix/store/vgcvcyndy12521f4p1wfxmz2scbc9852-which-2.23/bin:/nix/store/5yds4f92rf04ld4437x6nkbsbhbaiy7g-zip-3.0/bin]
Command Line: (exec /nix/store/paxx0f0j7n247ydnkr5037zzhlw0g0sm-bash/bin/bash \
-c \
'source external/bazel_tools/tools/genrule/genrule-setup.sh; cat list.txt | grep foo > bazel-out/darwin_x86_64-fastbuild/bin/foo.txt')
# Configuration: 89f88d514ae4f10d9d870a8d4ad4febbb673599e129ca06fb95727563aa99bae
# Execution platform: @@platforms//host:host
INFO: Elapsed time: 0.247s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 0 total actions
ActionKey identifies the action definition, not the contents of the input files. Note too that it appears to be after evaluation and variable expansion.
Same ActionKey (two ways to write the same variable):
cmd = "cat $(<) | grep foo > $(@)",
cmd = "cat $< | grep foo > $(@)",
Different ActionKey (extra space):
cmd = "cat $(<) | grep foo > $(@)",
cmd = "cat $(<) | grep foo > $(@)",
bazel test
Run all test targets:
bazel test //...
Options
| --subcommands | -s | print the full command prior to executing it |
Make Variables
| SRCS | $(SRCS) | the path names of the files corresponding to labels in the srcs list |
| < | $(<) | SRCS, if it is a single file |
Note:
| $(<) | $< | equivalent. single-character make variables do not need to be wrapped in parentheses |
gazelle
bazel run //:gazelle
keep comments
foo_binary(
# keep
bar = "baz",
)
foo_binary(
# keep: my comment explaining why we keep
bar = "baz",
)
Rulesets
bazel-contrib/rules_go
bazel run @rules_go//go -- version
bazel run @rules_go//go -- mod tidy
aspect-build/rules_ts
aspect-build/rules_js
Use the bazel-managed pnpm:
bazel run @pnpm//:pnpm -- [OPTIONS, COMMAND, ARGS]
For a package at $PWD:
bazel run @pnpm//:pnpm -- --dir $PWD [OPTIONS, COMMAND, ARGS]
For the workspace root:
bazel run @pnpm//:pnpm -- --workspace-root [OPTIONS, COMMAND, ARGS]
Removing a package:
bazel run @pnpm//:pnpm -- --dir $PWD remove PACKAGE
Adding a new package:
bazel run @pnpm//:pnpm -- --dir $PWD add PACKAGE
or:
- manually edit
package.jsonto add the dependency - run
bazel run @pnpm//:pnpm -- --dir $PWD install
I have not had success getting:
bazel run @pnpm//:pnpm -- --workspace-root add --save-dev PACKAGE
to work.
More options and commands at pnpm reference doc.
rules_pkg
- unclear how to use the generated manifest file
strip_prefixappears to be necessary to preserve directory structure within generated.tarfilestrip_prefixdoes not support../strip_prefixsupports absolute paths which are relative from WORKSPACE_ROOT
pkg_files
note: attribute prefix (AKA the installation directory) appears to be ignored if consumed by another pkg_files. pkg_filegroup will create the prefix.
possibly a bug as docs say:
pkg_filestargets may be consumed by otherpkg_files
and I don’t see any caveats about prefix.
pkg_filegroup
- consumer of
pkg_filesandpkg_filegroup - will create the directory structure specified by attribute prefix
ibazel
brew install ibazel
ibazel --run_output_interactive=false run //:foo -- bar
Read from .bazel_fix_commands.json and do not prompt for restarting the ibazel process:
ibazel --run_output --run_output_interactive=false run //:foo -- bar
Terminology
- @
-
Alias for the main repository.
- action
-
The lowest level composable unit in the build system.
- aquery (action query)
-
Command to query for actions in your build graph. operates on the post-analysis Configured Target Graph.
Related: cquery
- attribute
-
A named parameter that controls how the rule behaves.
- BUILD.bazel (BUILD file)
-
The main configuration file that tells Bazel what software outputs to build, what their dependencies are, and how to build them.
Related: package
- boundary marker file
-
One of:
- MODULE.bazel
- REPO.bazel
- WORKSPACE
- WORKSPACE.bazel
- cquery (configurable query)
-
Command to query over the configured target graph.
Related: aquery
- dependency hell
-
The frustration from problems involved in managing software dependencies; Dependency hell Wikipedia article
Related: diamond dependency
- diamond dependency
-
A problem where two dependencies have sub-dependency version conflicts.
Related: dependency hell, transitive dependency
- direct dependency
-
Targets that are reachable through a path of length 1 in the build dependency graph.
Related: transitive dependency
- incremental build
-
A build executed where only some dependencies are rebuilt.
Related: null build
- library
-
A collection of code or data that can be imported.
- module
-
Represents a target specifying a buildable unit.
Note: Sometimes used interchangeably with “target”.
Compare: target
- null build
-
A build executed where the target and all its dependencies are already up to date.
Related: incremental build
- package
-
The unit of code organization within a repository.
-
The set of targets defined by a BUILD file.
-
Identified by the BUILD file's relative path to the workspace root.
-
A container of targets.
Related: BUILD.bazel
- repository cache
-
The content-addressed cache for the remote downloader.
- rule
-
The definition of a series of actions and inputs.
- target
-
A buildable unit of a workspace.
-
An object defined in a BUILD file.
-
Declared by instantiating a rule.
-
The “what” of what to build
Note: Someimtes used interchangeably with “module”.
- transitive dependency
-
Targets that are reachable through a path of any length in the build dependency graph.
Related: direct dependency, diamond dependency
- WORKSPACE file
-
File which identifies the directory and its contents as a Bazel workspace and lives at the root of the project's directory structure.
Related: workspace
- workspace
-
A directory that holds your project's source files and Bazel's build outputs.
Related: WORKSPACE file
Frequently Asked Questions (FAQ)
How can I see the build graph?
bazel query 'deps(//:foo)' --output graph > graph.dot
dot -Tpng graph.dot -o graph.png
Can I generate a BUILD file as part of the build?
No because bazel needs all dependend-on files to exist during load time. Look into bazel-contrib/bazel-gazelle.
More info:
- Can I generate a BUILD file in Bazel?
- How to generate files in source folder using Bazel? [closed]
- Add option for genrules to output to source directory #3376
- How to write files to current directory instead of bazel-out
How do I specify which bazel version to use? How do I use different bazel versions per-project?
Via .bazelversion; e.g.:
$ cat .bazelversion
7.0.2
or through other means.
How do I pronounce “bzlmod”?
Possibly as: “BEE ZEE EL mod”
Why am I getting error: could not find common root of directories ?
Is it possible you have a symlink pointing outside the working directory?
I normally debug this by patching bazelbuild/bazel-watcher to get more info:
diff --git a/internal/ibazel/ibazel.go b/internal/ibazel/ibazel.go
index 9796b06..0a9ebac 100644
--- a/internal/ibazel/ibazel.go
+++ b/internal/ibazel/ibazel.go
@@ -616,6 +616,9 @@ func (i *IBazel) watchFiles(toWatch []string, watcher common.Watcher) {
}
watchList := keys(uniqueDirectories)
+
+ log.Errorf("Watching %d directories:\n %s", len(watchList), strings.Join(watchList, "\n "))
+
err := watcher.UpdateAll(watchList)
if err != nil {
log.Errorf("Error(s) updating watch list:\n %v", err)
Resources
- Official Website
- bazelbuild/bazel
- bazelbuild/bazelisk
- bazelbuild/bazel-watcher (ibazel)
- bazelbuild/starlark
- bazel-contrib/bazel-gazelle
- bazelbuild/buildtools
- bazelbuild/examples
- /frontend showing how to use with JavaScript, TypeScript, and libraries like Next.js, React, and Vue.
- aspect-build/bazel-examples
- rulesets
- Official recommended rules
- stackb/rules_proto
- bazelbuild/rules_go
- aspect-build/rules_ts
- Documentation
- /examples showing how to use TypeScript with Protocol Buffers and others
- Troubleshooting
- aspect-build/rules_js
- bazelbuild/rules_pkg
- bazelbuild/rules_swift
- bazel-ios/rules_ios
- bazelbuild/rules_apple
- bazelruby/rules_ruby
- coinbase/rules_ruby
- jekyll docs directory from bazelbuild/bazel to build the bazel website
- bazelbuild/rules_rust
- selected blog posts
- helpful talks:
- resolving editor / lsp / bazel / golang / protocol buffers issues
- Answer:
go mod tidycomplains that the bazel-generated protobuf package is missing - bazelbuild/rules_go issue: Using rules_go with go modules and generated packages
- bazelbuild/rules_go issue: Expose generated Go files to editors and IDEs
- Answer: