Technical Documentation: google/bazel
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (README.md)
[Bazel](https://bazel.build)
{Fast, Correct} - Choose two
Build and test software of any size, quickly and reliably.
Speed up your builds and tests:
Bazel rebuilds only what is necessary.
With advanced local and distributed caching, optimized dependency analysis and
parallel execution, you get fast and incremental builds.One tool, multiple languages: Build and test Java, C++, Android, iOS, Go,
and a wide variety of other language platforms. Bazel runs on Windows, macOS,
and Linux.Scalable: Bazel helps you scale your organization, codebase, and
continuous integration solution. It handles codebases of any size, in multiple
repositories or a huge monorepo.Extensible to your needs: Easily add support for new languages and
platforms with Bazel's familiar extension language. Share and re-use language
rules written by the growing Bazel community.
Getting Started
- Install Bazel
- Get started with Bazel
- Follow our tutorials:
Documentation
- Bazel command line
- Rule reference
- Use the query command
- Extend Bazel
- Write tests
- Who is using Bazel?
Reporting a Vulnerability
To report a security issue, please email [email protected] with a description
of the issue, the steps you took to create the issue, affected versions, and, if
known, mitigations for the issue. Our vulnerability management team will respond
within 3 working days of your email. If the issue is confirmed as a
vulnerability, we will open a Security Advisory. This project follows a 90 day
disclosure timeline.
Contributing to Bazel
See CONTRIBUTING.md
About Intro (`docs/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Basics Index (`docs/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Brand Index (`docs/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Contribute Index (`docs/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
External Overview (`docs/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
This document gives an overview of the system before examining some of the
concepts in more detail.
Overview of the system {#overview}
Bazel's external dependency system works on the basis of Bazel modules, each of which is a versioned Bazel project, and
repositories (or repos), which are directory trees containing
source files.
Bazel starts from the root module -- that is, the project you're working on.
Like all modules, it needs to have a MODULE.bazel file at its directory root,
declaring its basic metadata and direct dependencies. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "platforms", version = "0.0.11")From there, Bazel looks up all transitive dependency modules in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
-- that is, how the sources for each dependency module should be fetched. Most
of the time, these are just archives downloaded from the internet and extracted.
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions can perform actions like file I/O
and sending network requests. Among other things, they allow Bazel to interact
with other package management systems while also respecting the dependency graph
built out of Bazel modules.
The three kinds of repos -- the main repo (which is the source tree you're
working in), the repos representing transitive dependency modules, and the repos
created by module extensions -- form the workspace together.
External repos (non-main repos) are fetched on demand, for example when they're
referred to by labels (like @repo//pkg:target) in BUILD files.
Benefits {#benefits}
Bazel's external dependency system offers a wide range of benefits.
Automatic Dependency Resolution {#automatic-dependency-resolution}
- Deterministic Version Resolution: Bazel adopts the deterministic
MVS version resolution algorithm,
minimizing conflicts and addressing diamond dependency issues. - Simplified Dependency Management:
MODULE.bazeldeclares only direct
dependencies, while transitive dependencies are automatically resolved,
providing a clearer overview of the project's dependencies. - Strict Dependency visibility:
Only direct dependencies are visible, ensuring correctness and
predictability.
Ecosystem Integration {#ecosystem-integration}
- Bazel Central Registry: A centralized
repository for discovering and managing common dependencies as Bazel
modules. - Adoption of Non-Bazel Projects: When a non-Bazel project (usually a C++
library) is adapted for Bazel and made available in BCR, it streamlines its
integration for the whole community and eliminates duplicated effort and
conflicts of custom BUILD files. - Unified Integration with Language-Specific Package Managers: Rulesets
streamline integration with external package managers for non-Bazel
dependencies, including:- rules_jvm_external
for Maven, - rules_python
for PyPi, - bazel-gazelle
for Go Modules, - rules_rust
for Cargo.
- rules_jvm_external
Advanced Features {#advanced-features}
- Module Extensions: The
use_repo_ruleand module
extension features allow flexible use of custom repository rules and
resolution logic to introduce any non-Bazel dependencies. bazel modCommand: The sub-command offers
powerful ways to inspect external dependencies. You know exactly how an
external dependency is defined and where it comes from.- Vendor Mode: Pre-fetch the exact external dependencies you
need to facilitate offline builds. - Lockfile: The lockfile improves build reproducibility and
accelerates dependency resolution. - (Upcoming) BCR Provenance Attestations:
Strengthen supply chain security by ensuring verified provenance of
dependencies.
Concepts {#concepts}
This section gives more detail on concepts related to external dependencies.
Module {#module}
A Bazel project that can have multiple versions, each of which can have
dependencies on other modules.
In a local Bazel workspace, a module is represented by a repository.
For more details, see Bazel modules.
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The name by which a repository is always addressable. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name by which a repository is addressable in the context of a certain other
repo. This can be thought of as a repo's "nickname": The repo with the canonical
name michael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost
boundary of the directory tree that constitutes a repo. It doesn't need to
contain anything to serve as a repo boundary file; however, it can also be used
to specify some common attributes for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported. The repo() function takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)The legacy WORKSPACE system {#workspace-system}
In older Bazel versions (before 9.0), external dependencies were introduced by
defining repos in the WORKSPACE (or WORKSPACE.bazel) file. This file has a
similar syntax to BUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years after the WORKSPACE system was introduced, users reported many
pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, the new module-based system (codenamed
"Bzlmod") gradually replaced the legacy WORKSPACE system between Bazel 6 and 9.
Read the Bzlmod migration guide on how to migrate
to Bzlmod.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Install Index (`docs/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Migrate Index (`docs/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Query Quickstart (`docs/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Release Index (`docs/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 10 | Rolling | Check rolling release page | N/A |
| Bazel 9 | Active | 9.3.0 | Dec 2028 |
| Bazel 8 | Maintenance | 8.8.1 | Dec 2027 |
| Bazel 7 | Maintenance | 7.7.1 | Dec 2026 |
| Bazel 6 | Deprecated | 6.6.0 | Dec 2025 |
| Bazel 5 | Deprecated | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub. The "Latest" badge on GitHub always points to the highest semantic version, even if a maintenance patch for an older version is released more recently.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Rules Index (`docs/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions Index (`docs/versions/index.mdx`)
title: 'Documentation Versions'
The default documentation on this website represents the latest version at HEAD.
Each major and minor supported release will have a snapshot of the narrative and
reference documentation that follows the lifecycle of Bazel's version support.
To see documentation for stable Bazel versions, use the "Versioned docs"
drop-down.
To see documentation for older Bazel versions prior to Feb 2022, go to
docs.bazel.build.
Scripts Docs README (`scripts/docs/README.md`)
Bazel Release Documentation
This directory contains scripts to build the versioned documentation for a new Bazel release.
Build release documentation
You can build the release documentation by running this command from within a release branch:
bazel build //scripts/docs:gen_release_docs --config=docsThis is only necessary for testing, though. There is a separate pipeline that handles this task for actual Bazel releases.
Test scripts
You can test some of the scripts by running the following command:
bazel test --test_output=streamed //scripts/docs:rewriter_testVersions 7.6.1 About Intro (`docs/versions/7.6.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 7.6.1 Basics Index (`docs/versions/7.6.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 7.6.1 Contribute Index (`docs/versions/7.6.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 7.6.1 External Overview (`docs/versions/7.6.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//pac/kage:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//pac/kage:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 7.6.1 Install Index (`docs/versions/7.6.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 7.6.1 Migrate Index (`docs/versions/7.6.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 7.6.1 Query Quickstart (`docs/versions/7.6.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 7.6.1 Release Index (`docs/versions/7.6.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 7 | Rolling | Check GitHub release page | N/A |
| Bazel 6 | Active | 6.4.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Maintenance | 4.2.4 | Jan 2024 |
All Bazel releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 4 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
- Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
- Create a release branch in the name of
release-<version>from the baseline
commit. - Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
- Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
- Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created.
- The release candidate is announced on
- Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 7.6.1 Rules Index (`docs/versions/7.6.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Kubernetes
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 7.6.1 Versions Index (`docs/versions/7.6.1/versions/index.mdx`)
title: 'Documentation Versions'
The documentation on this website represents the latest in Bazel. Documentation
is updated at head. Each major supported release will have a snapshot of the
narrative and reference documentation that follows the lifecycle of Bazel's
version support.
For now, to see documentation for older Bazel versions, go to
docs.bazel.build.
Versions 7.7.1 About Intro (`docs/versions/7.7.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 7.7.1 Basics Index (`docs/versions/7.7.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 7.7.1 Contribute Index (`docs/versions/7.7.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 7.7.1 External Overview (`docs/versions/7.7.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//pac/kage:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//pac/kage:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 7.7.1 Install Index (`docs/versions/7.7.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 7.7.1 Migrate Index (`docs/versions/7.7.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 7.7.1 Query Quickstart (`docs/versions/7.7.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 7.7.1 Release Index (`docs/versions/7.7.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 7 | Rolling | Check GitHub release page | N/A |
| Bazel 6 | Active | 6.4.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Maintenance | 4.2.4 | Jan 2024 |
All Bazel releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 4 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
- Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
- Create a release branch in the name of
release-<version>from the baseline
commit. - Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
- Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
- Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created.
- The release candidate is announced on
- Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 7.7.1 Rules Index (`docs/versions/7.7.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Kubernetes
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 8.0.1 About Intro (`docs/versions/8.0.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 8.0.1 Basics Index (`docs/versions/8.0.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 8.0.1 Brand Index (`docs/versions/8.0.1/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Versions 8.0.1 Contribute Index (`docs/versions/8.0.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 8.0.1 External Overview (`docs/versions/8.0.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 8.0.1 Install Index (`docs/versions/8.0.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 8.0.1 Migrate Index (`docs/versions/8.0.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 8.0.1 Query Quickstart (`docs/versions/8.0.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 8.0.1 Release Index (`docs/versions/8.0.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 8 | Rolling | Check rolling release page | N/A |
| Bazel 7 | Active | 7.4.1 | Dec 2026 |
| Bazel 6 | Maintenance | 6.5.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 5 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 8.0.1 Rules Index (`docs/versions/8.0.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 8.0.1 Versions Index (`docs/versions/8.0.1/versions/index.mdx`)
title: 'Documentation Versions'
The default documentation on this website represents the latest version at HEAD.
Each major and minor supported release will have a snapshot of the narrative and
reference documentation that follows the lifecycle of Bazel's version support.
To see documentation for stable Bazel versions, use the "Versioned docs"
drop-down.
To see documentation for older Bazel versions prior to Feb 2022, go to
docs.bazel.build.
Versions 8.1.1 About Intro (`docs/versions/8.1.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 8.1.1 Basics Index (`docs/versions/8.1.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 8.1.1 Brand Index (`docs/versions/8.1.1/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Versions 8.1.1 Contribute Index (`docs/versions/8.1.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 8.1.1 External Overview (`docs/versions/8.1.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 8.1.1 Install Index (`docs/versions/8.1.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 8.1.1 Migrate Index (`docs/versions/8.1.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 8.1.1 Query Quickstart (`docs/versions/8.1.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 8.1.1 Release Index (`docs/versions/8.1.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 9 | Rolling | Check rolling release page | N/A |
| Bazel 8 | Active | 8.0.0 | December 2027 |
| Bazel 7 | Maintenance | 7.4.1 | Dec 2026 |
| Bazel 6 | Maintenance | 6.5.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 5 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 8.1.1 Rules Index (`docs/versions/8.1.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 8.1.1 Versions Index (`docs/versions/8.1.1/versions/index.mdx`)
title: 'Documentation Versions'
The default documentation on this website represents the latest version at HEAD.
Each major and minor supported release will have a snapshot of the narrative and
reference documentation that follows the lifecycle of Bazel's version support.
To see documentation for stable Bazel versions, use the "Versioned docs"
drop-down.
To see documentation for older Bazel versions prior to Feb 2022, go to
docs.bazel.build.
Versions 8.2.1 About Intro (`docs/versions/8.2.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 8.2.1 Basics Index (`docs/versions/8.2.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 8.2.1 Brand Index (`docs/versions/8.2.1/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Versions 8.2.1 Contribute Index (`docs/versions/8.2.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 8.2.1 External Overview (`docs/versions/8.2.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 8.2.1 Install Index (`docs/versions/8.2.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 8.2.1 Migrate Index (`docs/versions/8.2.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 8.2.1 Query Quickstart (`docs/versions/8.2.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 8.2.1 Release Index (`docs/versions/8.2.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 9 | Rolling | Check rolling release page | N/A |
| Bazel 8 | Active | 8.0.0 | December 2027 |
| Bazel 7 | Maintenance | 7.4.1 | Dec 2026 |
| Bazel 6 | Maintenance | 6.5.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 5 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 8.2.1 Rules Index (`docs/versions/8.2.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 8.2.1 Versions Index (`docs/versions/8.2.1/versions/index.mdx`)
title: 'Documentation Versions'
The default documentation on this website represents the latest version at HEAD.
Each major and minor supported release will have a snapshot of the narrative and
reference documentation that follows the lifecycle of Bazel's version support.
To see documentation for stable Bazel versions, use the "Versioned docs"
drop-down.
To see documentation for older Bazel versions prior to Feb 2022, go to
docs.bazel.build.
Versions 8.3.1 About Intro (`docs/versions/8.3.1/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 8.3.1 Basics Index (`docs/versions/8.3.1/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 8.3.1 Brand Index (`docs/versions/8.3.1/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Versions 8.3.1 Contribute Index (`docs/versions/8.3.1/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 8.3.1 External Overview (`docs/versions/8.3.1/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 8.3.1 Install Index (`docs/versions/8.3.1/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 8.3.1 Migrate Index (`docs/versions/8.3.1/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 8.3.1 Query Quickstart (`docs/versions/8.3.1/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 8.3.1 Release Index (`docs/versions/8.3.1/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 9 | Rolling | Check rolling release page | N/A |
| Bazel 8 | Active | 8.0.0 | December 2027 |
| Bazel 7 | Maintenance | 7.4.1 | Dec 2026 |
| Bazel 6 | Maintenance | 6.5.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 5 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 8.3.1 Rules Index (`docs/versions/8.3.1/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
- Platform
- Workspace
Embedded non-native rules {#embedded-rules}
Bazel also embeds additional rules written in Starlark. Those can be loaded from
the @bazel_tools built-in external repository.
- Repository rules
Versions 8.3.1 Versions Index (`docs/versions/8.3.1/versions/index.mdx`)
title: 'Documentation Versions'
The default documentation on this website represents the latest version at HEAD.
Each major and minor supported release will have a snapshot of the narrative and
reference documentation that follows the lifecycle of Bazel's version support.
To see documentation for stable Bazel versions, use the "Versioned docs"
drop-down.
To see documentation for older Bazel versions prior to Feb 2022, go to
docs.bazel.build.
Versions 8.4.2 About Intro (`docs/versions/8.4.2/about/intro.mdx`)
title: 'Intro to Bazel'
Bazel is an open-source build and test tool similar to Make, Maven, and Gradle.
It uses a human-readable, high-level build language. Bazel supports projects in
multiple languages and builds outputs for multiple platforms. Bazel supports
large codebases across multiple repositories, and large numbers of users.
Benefits {#benefits}
Bazel offers the following advantages:
High-level build language. Bazel uses an abstract, human-readable
language to describe the build properties of your project at a high
semantical level. Unlike other tools, Bazel operates on the concepts
of libraries, binaries, scripts, and data sets, shielding you from the
complexity of writing individual calls to tools such as compilers and
linkers.Bazel is fast and reliable. Bazel caches all previously done work and
tracks changes to both file content and build commands. This way, Bazel
knows when something needs to be rebuilt, and rebuilds only that. To further
speed up your builds, you can set up your project to build in a highly
parallel and incremental fashion.Bazel is multi-platform. Bazel runs on Linux, macOS, and Windows. Bazel
can build binaries and deployable packages for multiple platforms, including
desktop, server, and mobile, from the same project.Bazel scales. Bazel maintains agility while handling builds with 100k+
source files. It works with multiple repositories and user bases in the tens
of thousands.Bazel is extensible. Many languages are
supported, and you can extend Bazel to support any other language or
framework.
Using Bazel {#using-bazel}
To build or test a project with Bazel, you typically do the following:
Set up Bazel. Download and install Bazel.
Set up a project workspace, which is a
directory where Bazel looks for build inputs andBUILDfiles, and where it
stores build outputs.Write a
BUILDfile, which tells Bazel what to build and how to
build it.You write your
BUILDfile by declaring build targets using
Starlark, a domain-specific language. (See example
here.)A build target specifies a set of input artifacts that Bazel will build plus
their dependencies, the build rule Bazel will use to build it, and options
that configure the build rule.A build rule specifies the build tools Bazel will use, such as compilers and
linkers, and their configurations. Bazel ships with a number of build rules
covering the most common artifact types in the supported languages on
supported platforms.Run Bazel from the command line. Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
tests and query the build
to trace dependencies in your code.
Bazel build process {#bazel-build-process}
When running a build or a test, Bazel does the following:
Loads the
BUILDfiles relevant to the target.Analyzes the inputs and their
dependencies, applies the specified build
rules, and produces an action
graph.Executes the build actions on the inputs until the final build outputs
are produced.
Since all previous build work is cached, Bazel can identify and reuse cached
artifacts and only rebuild or retest what's changed. To further enforce
correctness, you can set up Bazel to run builds and tests
hermetically through sandboxing, minimizing skew
and maximizing reproducibility.
Action graph {#action-graph}
The action graph represents the build artifacts, the relationships between them,
and the build actions that Bazel will perform. Thanks to this graph, Bazel can
track changes to
file content as well as changes to actions, such as build or test commands, and
know what build work has previously been done. The graph also enables you to
easily trace dependencies in your code.
Getting started tutorials {#getting-started-tutorials}
To get started with Bazel, see Getting Started or jump
directly to the Bazel tutorials:
- Tutorial: Build a C++ Project
- Tutorial: Build a Java Project
- Tutorial: Build an Android Application
- Tutorial: Build an iOS Application
Versions 8.4.2 Basics Index (`docs/versions/8.4.2/basics/index.mdx`)
title: 'Build Basics'
A build system is one of the most important parts of an engineering organization
because each developer interacts with it potentially dozens or hundreds of times
per day. A fully featured build system is necessary to enable developer
productivity as an organization scales. For individual developers, it's
straightforward to just compile your code and so a build system might seem
excessive. But at a larger scale, having a build system helps with managing
shared dependencies, such as relying on another part of the code base, or an
external resource, such as a library. Build systems help to make sure that you
have everything you need to build your code before it starts building. Build
systems also increase velocity when they're set up to help engineers share
resources and results.
This section covers some history and basics of building and build systems,
including design decisions that went into making Bazel. If you're
familiar with artifact-based build systems, such as Bazel, Buck, and Pants, you
can skip this section, but it's a helpful overview to understand why
artifact-based build systems are excellent at enabling scale.
Note: Much of this section's content comes from the Build Systems and
Build Philosophy chapter of the
Software Engineering at Google book.
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
-
If you haven't used a build system before, start here. This page covers why
you should use a build system, and why compilers and build scripts aren't
the best choice once your organization starts to scale beyond a few
developers. -
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges. -
This page discusses artifact-based build systems in response to the pain
points of task-based build systems. -
This page covers distributed builds, or builds that are executed outside of
your local machine. This requires more robust infrastructure to share
resources and build results (and is where the true wizardry happens!) -
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
Versions 8.4.2 Brand Index (`docs/versions/8.4.2/brand/index.mdx`)
title: 'Bazel Brand Guidelines'
The Bazel trademark and logo ("Bazel Trademarks") are trademarks of Google, and
are treated separately from the copyright or patent license grants contained in
the Apache-licensed Bazel repositories on GitHub. Any use of the Bazel
Trademarks other than those permitted in these guidelines must be approved in
advance.
Purpose of the Brand Guidelines {#purpose-brand}
These guidelines exist to ensure that the Bazel project can share its technology
under open source licenses while making sure that the "Bazel" brand is protected
as a meaningful source identifier in a way that's consistent with trademark law.
By adhering to these guidelines, you help to promote the freedom to use and
develop high-quality Bazel technology.
Acceptable Uses {#acceptable-uses}
Given the open nature of Bazel, you may use the Bazel trademark to refer to the
project without prior written permission. Examples of these approved references
include the following:
- To refer to the Bazel Project itself;
- To link to bazel.build;
- To refer to unmodified source code or other files shared by the Bazel
repositories on GitHub; - In blog posts, news articles, or educational materials about Bazel;
- To accurately identify that your design or implementation is based on, is
for use with, or is compatible with Bazel technology.
Examples:
- [Your Product] for Bazel
- [Your Product] is compatible with Bazel
- [XYZ] Conference for Bazel Users
General Guidelines {#general-guidelines}
- The Bazel name may never be used or registered in a manner that would cause
confusion as to Google's sponsorship, affiliation, or endorsement. - Don't use the Bazel name as part of your company name, product name, domain
name, or social media profile. - Other than as permitted by these guidelines, the Bazel name should not be
combined with other trademarks, terms, or source identifiers. - Don't remove, distort or alter any element of the Bazel Trademarks. That
includes modifying the Bazel Trademark, for example, through hyphenation,
combination or abbreviation. Do not shorten, abbreviate, or create acronyms
out of the Bazel Trademarks. - Don't display the word Bazel using any different stylization, color, or font
from the surrounding text. - Don't use the term Bazel as a verb or use it in possessive form.
- Don't use the Bazel logo on any website, product UI, or promotional
materials without prior written permission from
[email protected].
Usage for Events and Community Groups {#usage-events}
The Bazel word mark may be used referentially in events, community groups, or
other gatherings related to the Bazel build system, but it may not be used in a
manner that implies official status or endorsement.
Examples of appropriate naming conventions are:
- [XYZ] Bazel User Group
- Bazel Community Day at [XYZ]
- [XYZ] Conference for Bazel Users
where [XYZ] represents the location and optionally other wordings.
Any naming convention that may imply official status or endorsement requires
review for approval from [email protected].
Examples of naming conventions that require prior written permission:
- BazelCon
- Bazel Conference
Contact Us {#contact-us}
Please do not hesitate to contact us at
[email protected] if you are unsure whether your
intended use of the Bazel Trademarks is in compliance with these guidelines, or
to ask for permission to use the Bazel Trademarks, clearly describing the
intended usage and duration.
Versions 8.4.2 Contribute Index (`docs/versions/8.4.2/contribute/index.mdx`)
title: 'Contributing to Bazel'
There are many ways to help the Bazel project and ecosystem.
Provide feedback {#feedback}
As you use Bazel, you may find things that can be improved.
You can help by reporting issues
when:
- Bazel crashes or you encounter a bug that can only be resolved using
bazel clean. - The documentation is incomplete or unclear. You can also report issues
from the page you are viewing by using the "Create issue"
link at the top right corner of the page. - An error message could be improved.
Participate in the community {#community}
You can engage with the Bazel community by:
- Answering questions on Stack Overflow.
- Helping other users on Slack.
- Improving documentation or contributing examples.
- Sharing your experience or your tips, for example, on a blog or social media.
Contribute code {#contribute-code}
Bazel is a large project and making a change to the Bazel source code
can be difficult.
You can contribute to the Bazel ecosystem by:
- Helping rules maintainers by contributing pull requests.
- Creating new rules and open-sourcing them.
- Contributing to Bazel-related tools, for example, migration tools.
- Improving Bazel integration with other IDEs and tools.
Before making a change, create a GitHub issue
or email bazel-discuss@.
The most helpful contributions fix bugs or add features (as opposed
to stylistic, refactoring, or "cleanup" changes). Your change should
include tests and documentation, keeping in mind backward-compatibility,
portability, and the impact on memory usage and performance.
To learn about how to submit a change, see the
patch acceptance process.
Bazel's code description {#code-description}
Bazel has a large codebase with code in multiple locations. See the codebase guide for more details.
Bazel is organized as follows:
- Client code is in
src/main/cppand provides the command-line interface. - Protocol buffers are in
src/main/protobuf. - Server code is in
src/main/javaandsrc/test/java.- Core code which is mostly composed of SkyFrame
and some utilities. - Built-in rules are in
com.google.devtools.build.lib.rulesand in
com.google.devtools.build.lib.bazel.rules. You might want to read about
the Challenges of Writing Rules first.
- Core code which is mostly composed of SkyFrame
- Java native interfaces are in
src/main/native. - Various tooling for language support are described in the list in the
compiling Bazel section.
Searching Bazel's source code {#search-code}
To quickly search through Bazel's source code, use
Bazel Code Search. You can navigate Bazel's
repositories, branches, and files. You can also view history, diffs, and blame
information. To learn more, see the
Bazel Code Search User Guide.
Versions 8.4.2 External Overview (`docs/versions/8.4.2/external/overview.mdx`)
title: 'External dependencies overview'
Bazel supports external dependencies, source files (both text and binary) used
in your build that are not from your workspace. For example, they could be a
ruleset hosted in a GitHub repo, a Maven artifact, or a directory on your local
machine outside your current workspace.
As of Bazel 6.0, there are two ways to manage external dependencies with Bazel:
the traditional, repository-focused WORKSPACE system, and
the newer module-focused MODULE.bazel system (codenamed Bzlmod,
and enabled with the flag --enable_bzlmod). The two systems can be used
together, but Bzlmod is replacing the WORKSPACE system in future Bazel
releases, check the Bzlmod migration guide on how to
migrate.
This document explains the concepts surrounding external dependency management
in Bazel, before going into a bit more detail about the two systems in order.
Concepts {#concepts}
Repository {#repository}
A directory tree with a boundary marker file at its root, containing source
files that can be used in a Bazel build. Often shortened to just repo.
A repo boundary marker file can be MODULE.bazel (signaling that this repo
represents a Bazel module), REPO.bazel (see below), or in
legacy contexts, WORKSPACE or WORKSPACE.bazel. Any repo boundary marker file
will signify the boundary of a repo; multiple such files can coexist in a
directory.
Main repository {#main-repository}
The repository in which the current Bazel command is being run.
The root of the main repository is also known as the
workspace root.
Workspace {#workspace}
The environment shared by all Bazel commands run in the same main repository. It
encompasses the main repo and the set of all defined external repos.
Note that historically the concepts of "repository" and "workspace" have been
conflated; the term "workspace" has often been used to refer to the main
repository, and sometimes even used as a synonym of "repository".
Canonical repository name {#canonical-repo-name}
The canonical name a repository is addressable by. Within the context of a
workspace, each repository has a single canonical name. A target inside a repo
whose canonical name is canonical_name can be addressed by the label@@canonical_name//package:target (note the double @).
The main repository always has the empty string as the canonical name.
Apparent repository name {#apparent-repo-name}
The name a repository is addressable by in the context of a certain other repo.
This can be thought of as a repo's "nickname": The repo with the canonical namemichael might have the apparent name mike in the context of the repoalice, but might have the apparent name mickey in the context of the repobob. In this case, a target inside michael can be addressed by the label@mike//package:target in the context of alice (note the single @).
Conversely, this can be understood as a repository mapping: each repo
maintains a mapping from "apparent repo name" to a "canonical repo name".
Repository rule {#repo-rule}
A schema for repository definitions that tells Bazel how to materialize a
repository. For example, it could be "download a zip archive from a certain URL
and extract it", or "fetch a certain Maven artifact and make it available as ajava_import target", or simply "symlink a local directory". Every repo is
defined by calling a repo rule with an appropriate number of arguments.
See Repository rules for more information about how to write
your own repository rules.
The most common repo rules by far arehttp_archive, which downloads an archive
from a URL and extracts it, andlocal_repository, which symlinks a
local directory that is already a Bazel repository.
Fetch a repository {#fetch-repository}
The action of making a repo available on local disk by running its associated
repo rule. The repos defined in a workspace are not available on local disk
before they are fetched.
Normally, Bazel only fetches a repo when it needs something from the repo,
and the repo hasn't already been fetched. If the repo has already been fetched
before, Bazel only re-fetches it if its definition has changed.
The fetch command can be used to initiate a pre-fetch for a repository,
target, or all necessary repositories to perform any build. This capability
enables offline builds using the --nofetch option.
The --fetch option serves to manage network access. Its default value is true.
However, when set to false (--nofetch), the command will utilize any cached
version of the dependency, and if none exists, the command will result in
failure.
See fetch options for more
information about controlling fetch.
Directory layout {#directory-layout}
After being fetched, the repo can be found in the subdirectory external in the
output base, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name canonical_name:
ls $(bazel info output_base)/external/<var> canonical_name </var>REPO.bazel file {#repo.bazel}
The REPO.bazel file is used to mark the topmost boundary of the directory tree
that constitutes a repo. It doesn't need to contain anything to serve as a repo
boundary file; however, it can also be used to specify some common attributes
for all build targets inside the repo.
The syntax of a REPO.bazel file is similar to BUILD files, except that noload statements are supported, and only a single function, repo(), is
available. repo() takes the same arguments as the package() function in BUILD files; whereas package()
specifies common attributes for all build targets inside the package, repo()
analogously does so for all build targets inside the repo.
For example, you can specify a common license for all targets in your repo by
having the following REPO.bazel file:
repo(
default_package_metadata = ["//:my_license"],
)Manage external dependencies with Bzlmod
Bzlmod, the new external dependency subsystem, does not directly work with repo
definitions. Instead, it builds a dependency graph from modules, runs
extensions on top of the graph, and defines repos accordingly.
A Bazel module is a Bazel project that can have multiple
versions, each of which publishes metadata about other modules that it depends
on. A module must have a MODULE.bazel file at its repo root, next to theWORKSPACE file. This file is the module's manifest, declaring its name,
version, list of dependencies, among other information. The following is a basic
example:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")A module must only list its direct dependencies, which Bzlmod looks up in a
Bazel registry — by default, the Bazel Central Registry. The registry provides the
dependencies' MODULE.bazel files, which allows Bazel to discover the entire
transitive dependency graph before performing version resolution.
After version resolution, in which one version is selected for each module,
Bazel consults the registry again to learn how to define a repo for each module
(in most cases, using http_archive).
Modules can also specify customized pieces of data called tags, which are
consumed by module extensions after module resolution
to define additional repos. These extensions have capabilities similar to repo
rules, enabling them to perform actions like file I/O and sending network
requests. Among other things, they allow Bazel to interact with other package
management systems while also respecting the dependency graph built out of Bazel
modules.
External links on Bzlmod {#external-links}
- Bzlmod usage examples in bazelbuild/examples
- Bazel External Dependencies Overhaul
(original Bzlmod design doc) - BazelCon 2021 talk on Bzlmod
- Bazel Community Day talk on Bzlmod
Define repos with `WORKSPACE`
Historically, you can manage external dependencies by defining repos in theWORKSPACE (or WORKSPACE.bazel) file. This file has a similar syntax toBUILD files, employing repo rules instead of build rules.
The following snippet is an example to use the http_archive repo rule in theWORKSPACE file:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)The snippet defines a repo whose canonical name is foo. In the WORKSPACE
system, by default, the canonical name of a repo is also its apparent name to
all other repos.
See the full list of functions available inWORKSPACE files.
Shortcomings of the `WORKSPACE` system {#workspace-shortcomings}
In the years since the WORKSPACE system was introduced, users have reported
many pain points, including:
- Bazel does not evaluate the
WORKSPACEfiles of any dependencies, so all
transitive dependencies must be defined in theWORKSPACEfile of the main
repo, in addition to direct dependencies. - To work around this, projects have adopted the "deps.bzl" pattern, in which
they define a macro which in turn defines multiple repos, and ask users to
call this macro in theirWORKSPACEfiles.- This has its own problems: macros cannot
loadother.bzlfiles, so
these projects have to define their transitive dependencies in this
"deps" macro, or work around this issue by having the user call multiple
layered "deps" macros. - Bazel evaluates the
WORKSPACEfile sequentially. Additionally,
dependencies are specified usinghttp_archivewith URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (Adepends onBandC;BandCboth depend on different versions ofD).
- This has its own problems: macros cannot
Due to the shortcomings of WORKSPACE, Bzlmod is going to replace the legacy
WORKSPACE system in future Bazel releases. Please read the Bzlmod migration guide on how to migrate to Bzlmod.
Versions 8.4.2 Install Index (`docs/versions/8.4.2/install/index.mdx`)
title: 'Installing Bazel'
This page describes the various platforms supported by Bazel and links
to the packages for more details.
Bazelisk is the recommended way to install Bazel on Ubuntu Linux, macOS, and Windows.
You can find available Bazel releases on our release page.
Community-supported packages {#community-supported-packages}
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
Community-supported architectures {#community-supported-architectures}
For other platforms, you can try to compile from source.
Versions 8.4.2 Migrate Index (`docs/versions/8.4.2/migrate/index.mdx`)
title: 'Migrating to Bazel'
This page links to migration guides for Bazel.
Versions 8.4.2 Query Quickstart (`docs/versions/8.4.2/query/quickstart.mdx`)
title: 'Query quickstart'
This tutorial covers how to work with Bazel to trace dependencies in your code using a premade Bazel project.
For language and --output flag details, see the Bazel query reference and Bazel cquery reference manuals. Get help in your IDE by typing bazel help query or bazel help cquery on the command line.
Objective
This guide runs you through a set of basic queries you can use to learn more about your project's file dependencies. It is intended for new Bazel developers with a basic knowledge of how Bazel and BUILD files work.
Prerequisites
Start by installing Bazel, if you haven’t already. This tutorial uses Git for source control, so for best results, install Git as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can download in order to follow along.
Get the sample project
Next, retrieve the sample app from Bazel's Examples repository by running the following in your command-line tool of choice:
git clone https://github.com/bazelbuild/examples.gitThe sample project for this tutorial is in the examples/query-quickstart directory.
Getting started
What are Bazel queries?
Queries help you to learn about a Bazel codebase by analyzing the relationships between BUILD files and examining the resulting output for useful information. This guide previews some basic query functions, but for more options see the query guide. Queries help you learn about dependencies in large scale projects without manually navigating through BUILD files.
To run a query, open your command line terminal and enter:
bazel query 'query_function'Scenario
Imagine a scenario that delves into the relationship between Cafe Bazel and its respective chef. This Cafe exclusively sells pizza and mac & cheese. Take a look below at how the project is structured:
bazelqueryguide
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── customers
│ │ ├── Jenny.java
│ │ ├── Amir.java
│ │ └── BUILD
│ ├── dishes
│ │ ├── Pizza.java
│ │ ├── MacAndCheese.java
│ │ └── BUILD
│ ├── ingredients
│ │ ├── Cheese.java
│ │ ├── Tomatoes.java
│ │ ├── Dough.java
│ │ ├── Macaroni.java
│ │ └── BUILD
│ ├── restaurant
│ │ ├── Cafe.java
│ │ ├── Chef.java
│ │ └── BUILD
│ ├── reviews
│ │ ├── Review.java
│ │ └── BUILD
│ └── Runner.java
└── MODULE.bazelThroughout this tutorial, unless directed otherwise, try not to look in the BUILD files to find the information you need and instead solely use the query function.
A project consists of different packages that make up a Cafe. They are separated into: restaurant, ingredients, dishes, customers, and reviews. Rules within these packages define different components of the Cafe with various tags and dependencies.
Running a build
This project contains a main method inside of Runner.java that you can execute
to print out a menu of the Cafe. Build the project using Bazel with the commandbazel build and use : to signal that the target is named runner. See
target names to learn how to
reference targets.
To build this project, paste this command into a terminal:
bazel build :runnerYour output should look something like this if the build is successful.
INFO: Analyzed target //:runner (49 packages loaded, 784 targets configured).
INFO: Found 1 target...
Target //:runner up-to-date:
bazel-bin/runner.jar
bazel-bin/runner
INFO: Elapsed time: 16.593s, Critical Path: 4.32s
INFO: 23 processes: 4 internal, 10 darwin-sandbox, 9 worker.
INFO: Build completed successfully, 23 total actionsAfter it has built successfully, run the application by pasting this command:
bazel-bin/runner--------------------- MENU -------------------------
Pizza - Cheesy Delicious Goodness
Macaroni & Cheese - Kid-approved Dinner
----------------------------------------------------This leaves you with a list of the menu items given along with a short description.
Exploring targets
The project lists ingredients and dishes in their own packages. To use a query to view the rules of a package, run the command bazel query *package*/…
In this case, you can use this to look through the ingredients and dishes that this Cafe has by running:
bazel query //src/main/java/com/example/dishes/...bazel query //src/main/java/com/example/ingredients/...If you query for the targets of the ingredients package, the output should look like:
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomatoFinding dependencies
What targets does your runner rely on to run?
Say you want to dive deeper into the structure of your project without prodding into the filesystem (which may be untenable for large projects). What rules does Cafe Bazel use?
If, like in this example, the target for your runner is runner, discover the underlying dependencies of the target by running the command:
bazel query --noimplicit_deps "deps(target)"bazel query --noimplicit_deps "deps(:runner)"//:runner
//:src/main/java/com/example/Runner.java
//src/main/java/com/example/dishes:MacAndCheese.java
//src/main/java/com/example/dishes:Pizza.java
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:Cheese.java
//src/main/java/com/example/ingredients:Dough.java
//src/main/java/com/example/ingredients:Macaroni.java
//src/main/java/com/example/ingredients:Tomato.java
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/ingredients:dough
//src/main/java/com/example/ingredients:macaroni
//src/main/java/com/example/ingredients:tomato
//src/main/java/com/example/restaurant:Cafe.java
//src/main/java/com/example/restaurant:Chef.java
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefNote: Adding the flag --noimplicit_deps removes configurations and potential toolchains to simplify the list. When you omit this flag, Bazel returns implicit dependencies not specified in the BUILD file and clutters the output.
In most cases, use the query function deps() to see individual output dependencies of a specific target.
Visualizing the dependency graph (optional)
Note: This section uses Graphviz, so make sure to download Graphviz to follow along.
The section describes how you can visualize the dependency paths for a specific query. Graphviz helps to see the path as a directed acyclic graph image as opposed to a flattened list. You can alter the display of the Bazel query graph by using various --output command line options. See Output Formats for options.
Start by running your desired query and add the flag --noimplicit_deps to remove excessive tool dependencies. Then, follow the query with the output flag and store the graph into a file called graph.in to create a text representation of the graph.
To search for all dependencies of the target :runner and format the output as a graph:
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.inThis creates a file called graph.in, which is a text representation of the build graph. Graphviz uses [dot](https://graphviz.org/docs/layouts/dot/) – a tool that processes text into a visualization — to create a png:
dot -Tpng < graph.in > graph.pngIf you open up graph.png, you should see something like this. The graph below has been simplified to make the essential path details clearer in this guide.
This helps when you want to see the outputs of the different query functions throughout this guide.
Finding reverse dependencies
If instead you have a target you’d like to analyze what other targets use it, you can use a query to examine what targets depend on a certain rule. This is called a “reverse dependency”. Using rdeps() can be useful when editing a file in a codebase that you’re unfamiliar with, and can save you from unknowingly breaking other files which depended on it.
For instance, you want to make some edits to the ingredient cheese. To avoid causing an issue for Cafe Bazel, you need to check what dishes rely on cheese.
Caution: Since ingredients is its own package, you must use a different naming convention for the target cheese in the form of //package:target. Read more about referencing targets, or Labels.
To see what targets depend on a particular target/package, you can use rdeps(universe_scope, target). The rdeps() query function takes in at least two arguments: a universe_scope — the relevant directory — and a target. Bazel searches for the target’s reverse dependencies within the universe_scope provided. The rdeps() operator accepts an optional third argument: an integer literal specifying the upper bound on the depth of the search.
Tip: To search within the whole scope of the project, set the universe_scope to //...
To look for reverse dependencies of the target cheese within the scope of the entire project ‘//…’ run the command:
bazel query "rdeps(universe_scope, target)"ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"//:runner
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe query return shows that cheese is relied on by both pizza and macAndCheese. What a surprise!
Finding targets based on tags
Two customers walk into Bazel Cafe: Amir and Jenny. There is nothing known about them except for their names. Luckily, they have their orders tagged in the 'customers' BUILD file. How can you access this tag?
Developers can tag Bazel targets with different identifiers, often for testing purposes. For instance, tags on tests can annotate a test's role in your debug and release process, especially for C++ and Python tests, which lack any runtime annotation ability. Using tags and size elements gives flexibility in assembling suites of tests based around a codebase’s check-in policy.
In this example, the tags are either one of pizza or macAndCheese to represent the menu items. This command queries for targets that have tags matching your identifier within a certain package.
bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'This query returns all of the targets in the 'customers' package that have a tag of "pizza".
Test yourself
Use this query to learn what Jenny wants to order.
Adding a new dependency
Cafe Bazel has expanded its menu — customers can now order a Smoothie! This specific smoothie consists of the ingredients Strawberry and Banana.
First, add the ingredients that the smoothie depends on: Strawberry.java and Banana.java. Add the empty Java classes.
src/main/java/com/example/ingredients/Strawberry.java
package com.example.ingredients;
public class Strawberry {
}src/main/java/com/example/ingredients/Banana.java
package com.example.ingredients;
public class Banana {
}Next, add Smoothie.java to the appropriate directory: dishes.
src/main/java/com/example/dishes/Smoothie.java
package com.example.dishes;
public class Smoothie {
public static final String DISH_NAME = "Smoothie";
public static final String DESCRIPTION = "Yummy and Refreshing";
}Lastly, add these files as rules in the appropriate BUILD files. Create a new java library for each new ingredient, including its name, public visibility, and its newly created 'src' file. You should wind up with this updated BUILD file:
src/main/java/com/example/ingredients/BUILD
java_library(
name = "cheese",
visibility = ["//visibility:public"],
srcs = ["Cheese.java"],
)
java_library(
name = "dough",
visibility = ["//visibility:public"],
srcs = ["Dough.java"],
)
java_library(
name = "macaroni",
visibility = ["//visibility:public"],
srcs = ["Macaroni.java"],
)
java_library(
name = "tomato",
visibility = ["//visibility:public"],
srcs = ["Tomato.java"],
)
java_library(
name = "strawberry",
visibility = ["//visibility:public"],
srcs = ["Strawberry.java"],
)
java_library(
name = "banana",
visibility = ["//visibility:public"],
srcs = ["Banana.java"],
)In the BUILD file for dishes, you want to add a new rule for Smoothie. Doing so includes the Java file created for Smoothie as a 'src' file, and the new rules you made for each ingredient of the smoothie.
src/main/java/com/example/dishes/BUILD
java_library(
name = "macAndCheese",
visibility = ["//visibility:public"],
srcs = ["MacAndCheese.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:macaroni",
],
)
java_library(
name = "pizza",
visibility = ["//visibility:public"],
srcs = ["Pizza.java"],
deps = [
"//src/main/java/com/example/ingredients:cheese",
"//src/main/java/com/example/ingredients:dough",
"//src/main/java/com/example/ingredients:tomato",
],
)
java_library(
name = "smoothie",
visibility = ["//visibility:public"],
srcs = ["Smoothie.java"],
deps = [
"//src/main/java/com/example/ingredients:strawberry",
"//src/main/java/com/example/ingredients:banana",
],
)Lastly, you want to include the smoothie as a dependency in the Chef’s BUILD file.
src/main/java/com/example/restaurant/BUILD
java\_library(
name = "chef",
visibility = ["//visibility:public"],
srcs = [
"Chef.java",
],
deps = [
"//src/main/java/com/example/dishes:macAndCheese",
"//src/main/java/com/example/dishes:pizza",
"//src/main/java/com/example/dishes:smoothie",
],
)
java\_library(
name = "cafe",
visibility = ["//visibility:public"],
srcs = [
"Cafe.java",
],
deps = [
":chef",
],
)Build cafe again to confirm that there are no errors. If it builds successfully, congratulations! You’ve added a new dependency for the 'Cafe'. If not, look out for spelling mistakes and package naming. For more information about writing BUILD files see BUILD Style Guide.
Now, visualize the new dependency graph with the addition of the Smoothie to compare with the previous one. For clarity, name the graph input as graph2.in and graph2.png.
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.indot -Tpng < graph2.in > graph2.pngLooking at graph2.png, you can see that Smoothie has no shared dependencies with other dishes but is just another target that the Chef relies on.
somepath() and allpaths()
What if you want to query why one package depends on another package? Displaying a dependency path between the two provides the answer.
Two functions can help you find dependency paths: somepath() and allpaths(). Given a starting target S and an end point E, find a path between S and E by using somepath(S,E).
Explore the differences between these two functions by looking at the relationships between the 'Chef' and 'Cheese' targets. There are different possible paths to get from one target to the other:
- Chef → MacAndCheese → Cheese
- Chef → Pizza → Cheese
somepath() gives you a single path out of the two options, whereas 'allpaths()' outputs every possible path.
Using Cafe Bazel as an example, run the following:
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chef
//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/ingredients:cheeseThe output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use allpaths(), you get:
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"//src/main/java/com/example/dishes:macAndCheese
//src/main/java/com/example/dishes:pizza
//src/main/java/com/example/ingredients:cheese
//src/main/java/com/example/restaurant:cafe
//src/main/java/com/example/restaurant:chefThe output of allpaths() is a little harder to read as it is a flattened list of the dependencies. Visualizing this graph using Graphviz makes the relationship clearer to understand.
Test yourself
One of Cafe Bazel’s customers gave the restaurant's first review! Unfortunately, the review is missing some details such as the identity of the reviewer and what dish it’s referencing. Luckily, you can access this information with Bazel. The reviews package contains a program that prints a review from a mystery customer. Build and run it with:
bazel build //src/main/java/com/example/reviews:reviewbazel-bin/src/main/java/com/example/reviews/reviewGoing off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
Wrapping up
Congratulations! You have now run several basic queries, which you can try out on own projects. To learn more about the query language syntax, refer to the Query reference page. Want more advanced queries? The Query guide showcases an in-depth list of more use cases than are covered in this guide.
Versions 8.4.2 Release Index (`docs/versions/8.4.2/release/index.mdx`)
title: 'Release Model'
As announced in the original blog post, Bazel
4.0 and higher versions provides support for two release tracks: rolling
releases and long term support (LTS) releases. This page covers the latest
information about Bazel's release model.
Support matrix {#support-matrix}
| LTS release | Support stage | Latest version | End of support |
|---|---|---|---|
| Bazel 9 | Rolling | Check rolling release page | N/A |
| Bazel 8 | Active | 8.0.0 | December 2027 |
| Bazel 7 | Maintenance | 7.4.1 | Dec 2026 |
| Bazel 6 | Maintenance | 6.5.0 | Dec 2025 |
| Bazel 5 | Maintenance | 5.4.1 | Jan 2025 |
| Bazel 4 | Deprecated | 4.2.4 | Jan 2024 |
All Bazel LTS releases can be found on the release page on GitHub.
Note: Bazel version older than Bazel 5 are no longer supported, Bazel users are
recommended to upgrade to the latest LTS release or use rolling releases if you
want to keep up with the latest changes at HEAD.
Release versioning {#bazel-versioning}
Bazel uses a major.minor.patch Semantic Versioning scheme.
- A major release contains features that are not backward compatible with
the previous release. Each major Bazel version is an LTS release. - A minor release contains backward-compatible bug fixes and features
back-ported from the main branch. - A patch release contains critical bug fixes.
Additionally, pre-release versions are indicated by appending a hyphen and a
date suffix to the next major version number.
For example, a new release of each type would result in these version numbers:
- Major: 6.0.0
- Minor: 6.1.0
- Patch: 6.1.2
- Pre-release: 7.0.0-pre.20230502.1
Support stages {#support-stages}
For each major Bazel version, there are four support stages:
- Rolling: This major version is still in pre-release, the Bazel team
publishes rolling releases from HEAD. - Active: This major version is the current active LTS release. The Bazel
team backports important features and bug fixes into its minor releases. - Maintenance: This major version is an old LTS release in maintenance
mode. The Bazel team only promises to backport critical bug fixes for
security issues and OS-compatibility issues into this LTS release. - Deprecated: The Bazel team no longer provides support for this major
version, all users should migrate to newer Bazel LTS releases.
Release cadence {#release-cadence}
Bazel regularly publish releases for two release tracks.
Rolling releases {#rolling-releases}
- Rolling releases are coordinated with Google Blaze release and are released
from HEAD around every two weeks. It is a preview of the next Bazel LTS
release. - Rolling releases can ship incompatible changes. Incompatible flags are
recommended for major breaking changes, rolling out incompatible changes
should follow our backward compatibility policy.
LTS releases {#lts-releases}
- Major release: A new LTS release is expected to be cut from HEAD roughly
every
12 months. Once a new LTS release is out, it immediately enters the Active
stage, and the previous LTS release enters the Maintenance stage. - Minor release: New minor verions on the Active LTS track are expected to
be released once every 2 months. - Patch release: New patch versions for LTS releases in Active and
Maintenance stages are expected to be released on demand for critical bug
fixes. - A Bazel LTS release enters the Deprecated stage after being in the
Maintenance stage for 2 years.
For planned releases, please check our release issues
on Github.
Release procedure & policies {#release-procedure-policies}
For rolling releases, the process is straightforward: about every two weeks, a
new release is created, aligning with the same baseline as the Google internal
Blaze release. Due to the rapid release schedule, we don't backport any changes
to rolling releases.
For LTS releases, the procedure and policies below are followed:
Determine a baseline commit for the release.
- For a new major LTS release, the baseline commit is the HEAD of the main
branch. - For a minor or patch release, the baseline commit is the HEAD of the
current latest version of the same LTS release.
- For a new major LTS release, the baseline commit is the HEAD of the main
Create a release branch in the name of
release-<version>from the baseline
commit.Backport changes via PRs to the release branch.
- The community can suggest certain commits to be back-ported by replying
"@bazel-io flag" on relevant GitHub issues or PRs to mark them as potential
release blockers, the Bazel team triages them and decide whether to
back-port the commits. - Only backward-compatible commits on the main branch can be back-ported,
additional minor changes to resolve merge conflicts are acceptable.
- The community can suggest certain commits to be back-ported by replying
Backport changes using Cherry-Pick Request Issue for Bazel maintainers.
Bazel maintainers can request to cherry-pick specific commit(s)
to a release branch. This process is initiated by creating a
cherry-pick request on GitHub. Here's how to do it.- Open the cherry-pick request
- Fill in the request details
- Title: Provide a concise and descriptive title for the request.
- Commit ID(s): Enter the ID(s) of the commit(s) you want to
cherry-pick. If there are multiple commits, then separate
them with commas. - Category: Specify the category of the request.
- Reviewer(s): For multiple reviewers, separate their GitHub
ID's with commas.
- Set the milestone
- Find the "Milestone" section and click the setting.
- Select the appropriate X.Y.Z release blockers. This action
triggers the cherry-pick bot to process your request
for the "release-X.Y.Z" branch.
- Submit the Issue
- Once all details are filled in and the miestone is set,
submit the issue.
- Once all details are filled in and the miestone is set,
The cherry-pick bot will process the request and notify
if the commit(s) are eligible for cherry-picking. If
the commits are cherry-pickable, which means there's no
merge conflict while cherry-picking the commit, then
the bot will create a new pull request. When the pull
request is approved by a member of the Bazel team, the
commits are cherry-picked and merged to the release branch.
For a visual example of a completed cherry-pick request,
refer to this
example
.
Identify release blockers and fix issues found on the release branch.
- The release branch is tested with the same test suite in
postsubmit and
downstream test pipeline
on Bazel CI. The Bazel team monitors testing results of the release
branch and fixes any regressions found.
- The release branch is tested with the same test suite in
Create a new release candidate from the release branch when all known
release blockers are resolved.- The release candidate is announced on
bazel-discuss,
the Bazel team monitors community bug reports for the candidate. - If new release blockers are identified, go back to the last step and
create a new release candidate after resolving all the issues. - New features are not allowed to be added to the release branch after the
first release candidate is created; cherry-picks are limited to critical
fixes only. If a cherry-pick is needed, the requester must answer the
following questions: Why is this change critical, and what benefits does
it provide? What is the likelihood of this change introducing a
regression?
- The release candidate is announced on
Push the release candidate as the official release if no further release
blockers are found- For patch releases, push the release at least two business days after
the last release candidate is out. - For major and minor releases, push the release two business days after
the last release candidate is out, but not earlier than one week after
the first release candidate is out. - The release is only pushed on a day where the next day is a business
day. - The release is announced on
bazel-discuss,
the Bazel team monitors and addresses community bug reports for the new
release.
- For patch releases, push the release at least two business days after
Report regressions {#report-regressions}
If a user finds a regression in a new Bazel release, release candidate or even
Bazel at HEAD, please file a bug on
GitHub. You can use
Bazelisk to bisect the culprit commit and include this information in the bug
report.
For example, if your build succeeds with Bazel 6.1.0 but fails with the second
release candidate of 6.2.0, you can do bisect via
bazelisk --bisect=6.1.0..release-6.2.0rc2 build //foo:barYou can set BAZELISK_SHUTDOWN or BAZELISK_CLEAN environment variable to run
corresponding bazel commands to reset the build state if it's needed to
reproduce the issue. For more details, check out documentation about Bazelisk
[bisect feature] (https://github.com/bazelbuild/bazelisk#--bisect).
Remember to upgrade Bazelisk to the latest version to use the bisect
feature.
Rule compatibility {#rule-compatibility}
If you are a rule authors and want to maintain compatibility with different
Bazel versions, please check out the Rule Compatibility page.
Versions 8.4.2 Rules Index (`docs/versions/8.4.2/rules/index.mdx`)
title: 'Rules'
The Bazel ecosystem has a growing and evolving set of rules to support popular
languages and packages. Much of Bazel's strength comes from the ability to
define new rules that can be used by others.
This page describes the recommended, native, and non-native Bazel rules.
Recommended rules {#recommended-rules}
Here is a selection of recommended rules:
- Android
- C / C++
- Docker/OCI
- Go
- Haskell
- Java
- JavaScript / NodeJS
- Maven dependency management
- Objective-C
- Package building
- Protocol Buffers
- Python
- Rust
- Scala
- Shell
- Webtesting (Webdriver)
The repository Skylib contains
additional functions that can be useful when writing new rules and new
macros.
The rules above were reviewed and follow our
requirements for recommended rules.
Contact the respective rule set's maintainers regarding issues and feature
requests.
To find more Bazel rules, use a search engine, take a look on
awesomebazel.com, or search on
GitHub.
Native rules that do not apply to a specific programming language
Native rules are shipped with the Bazel binary, they are always available in
BUILD files without a load statement.
- Extra actions
- General
filegroup- [
genquery](/versions/8.4.2/reference/be/genera