# FAQ
Source: https://bazel.build/about/faq
If you have questions or need support, see [Getting Help](/help).
## What is Bazel?
Bazel is a tool that automates software builds and tests. Supported build tasks include running compilers and linkers to produce executable programs and libraries, and assembling deployable packages for Android, iOS and other target environments. Bazel is similar to other tools like Make, Ant, Gradle, Buck, Pants and Maven.
## What is special about Bazel?
Bazel was designed to fit the way software is developed at Google. It has the following features:
* Multi-language support: Bazel supports [many languages](/reference/be/overview), and can be extended to support arbitrary programming languages.
* High-level build language: Projects are described in the `BUILD` language, a concise text format that describes a project as sets of small interconnected libraries, binaries and tests. In contrast, with tools like Make, you have to describe individual files and compiler invocations.
* Multi-platform support: The same tool and the same `BUILD` files can be used to build software for different architectures, and even different platforms. At Google, we use Bazel to build everything from server applications running on systems in our data centers to client apps running on mobile phones.
* Reproducibility: In `BUILD` files, each library, test and binary must specify its direct dependencies completely. Bazel uses this dependency information to know what must be rebuilt when you make changes to a source file, and which tasks can run in parallel. This means that all builds are incremental and will always produce the same result.
* Scalable: Bazel can handle large builds; at Google, it is common for a server binary to have 100k source files, and builds where no files were changed take about \~200ms.
## Why doesn’t Google use...?
* Make, Ninja: These tools give very exact control over what commands get invoked to build files, but it’s up to the user to write rules that are correct.
* Users interact with Bazel on a higher level. For example, Bazel has built-in rules for “Java test”, “C++ binary”, and notions such as “target platform” and “host platform”. These rules have been battle tested to be foolproof.
* Ant and Maven: Ant and Maven are primarily geared toward Java, while Bazel handles multiple languages. Bazel encourages subdividing codebases in smaller reusable units, and can rebuild only ones that need rebuilding. This speeds up development when working with larger codebases.
* Gradle: Bazel configuration files are much more structured than Gradle’s, letting Bazel understand exactly what each action does. This allows for more parallelism and better reproducibility.
* Pants, Buck: Both tools were created and developed by ex-Googlers at Twitter and Foursquare, and Facebook respectively. They have been modeled after Bazel, but their feature sets are different, so they aren’t viable alternatives for us.
## Where did Bazel come from?
Bazel is a flavor of the tool that Google uses to build its server software internally. It has expanded to build other software as well, like mobile apps (iOS, Android) that connect to our servers.
## Did you rewrite your internal tool as open-source? Is it a fork?
Bazel shares most of its code with the internal tool and its rules are used for millions of builds every day.
## Why did Google build Bazel?
A long time ago, Google built its software using large, generated Makefiles. These led to slow and unreliable builds, which began to interfere with our developers’ productivity and the company’s agility. Bazel was a way to solve these problems.
## Does Bazel require a build cluster?
Bazel runs build operations locally by default. However, Bazel can also connect to a build cluster for even faster builds and tests. See our documentation on [remote execution and caching](/remote/rbe) and [remote caching](/remote/caching) for further details.
## How does the Google development process work?
For our server code base, we use the following development workflow:
* All our server code is in a single, gigantic version control system.
* Everybody builds their software with Bazel.
* Different teams own different parts of the source tree, and make their components available as `BUILD` targets.
* Branching is primarily used for managing releases, so everybody develops their software at the head revision.
Bazel is a cornerstone of this philosophy: since Bazel requires all dependencies to be fully specified, we can predict which programs and tests are affected by a change, and vet them before submission.
More background on the development process at Google can be found on the [eng tools blog](http://google-engtools.blogspot.com/).
## Why did you open up Bazel?
Building software should be fun and easy. Slow and unpredictable builds take the fun out of programming.
## Why would I want to use Bazel?
* Bazel may give you faster build times because it can recompile only the files that need to be recompiled. Similarly, it can skip re-running tests that it knows haven’t changed.
* Bazel produces deterministic results. This eliminates skew between incremental and clean builds, laptop and CI system, etc.
* Bazel can build different client and server apps with the same tool from the same workspace. For example, you can change a client/server protocol in a single commit, and test that the updated mobile app works with the updated server, building both with the same tool, reaping all the aforementioned benefits of Bazel.
## Can I see examples?
Yes; see a [simple example](https://github.com/bazelbuild/bazel/blob/master/examples/cpp/BUILD)
or read the [Bazel source code](https://github.com/bazelbuild/bazel/blob/master/src/BUILD) for a more complex example.
## What is Bazel best at?
Bazel shines at building and testing projects with the following properties:
* Projects with a large codebase
* Projects written in (multiple) compiled languages
* Projects that deploy on multiple platforms
* Projects that have extensive tests
## Where can I run Bazel?
Bazel runs on Linux, macOS (OS X), and Windows.
Porting to other UNIX platforms should be relatively easy, as long as a JDK is available for the platform.
## What should I not use Bazel for?
* Bazel tries to be smart about caching. This means that it is not good for running build operations whose outputs should not be cached. For example, the following steps should not be run from Bazel:
* A compilation step that fetches data from the internet.
* A test step that connects to the QA instance of your site.
* A deployment step that changes your site’s cloud configuration.
* If your build consists of a few long, sequential steps, Bazel may not be able to help much. You’ll get more speed by breaking long steps into smaller, discrete targets that Bazel can run in parallel.
## How stable is Bazel’s feature set?
The core features (C++, Java, and shell rules) have extensive use inside Google, so they are thoroughly tested and have very little churn. Similarly, we test new versions of Bazel across hundreds of thousands of targets every day to find regressions, and we release new versions multiple times every month.
In short, except for features marked as experimental, Bazel should Just Work. Changes to non-experimental rules will be backward compatible. A more detailed list of feature support statuses can be found in our [support document](/contribute/support).
## How stable is Bazel as a binary?
Inside Google, we make sure that Bazel crashes are very rare. This should also hold for our open source codebase.
## How can I start using Bazel?
See [Getting Started](/start/).
## Doesn’t Docker solve the reproducibility problems?
With Docker you can easily create sandboxes with fixed OS releases, for example, Ubuntu 12.04, Fedora 21. This solves the problem of reproducibility for the system environment – that is, “which version of /usr/bin/c++ do I need?”
Docker does not address reproducibility with regard to changes in the source code. Running Make with an imperfectly written Makefile inside a Docker container can still yield unpredictable results.
Inside Google, we check tools into source control for reproducibility. In this way, we can vet changes to tools (“upgrade GCC to 4.6.1”) with the same mechanism as changes to base libraries (“fix bounds check in OpenSSL”).
## Can I build binaries for deployment on Docker?
With Bazel, you can build standalone, statically linked binaries in C/C++, and self-contained jar files for Java. These run with few dependencies on normal UNIX systems, and as such should be simple to install inside a Docker container.
Bazel has conventions for structuring more complex programs, for example, a Java program that consumes a set of data files, or runs another program as subprocess. It is possible to package up such environments as standalone archives, so they can be deployed on different systems, including Docker images.
## Can I build Docker images with Bazel?
Yes, you can use our [Docker rules](https://github.com/bazelbuild/rules_docker) to build reproducible Docker images.
## Will Bazel make my builds reproducible automatically?
For Java and C++ binaries, yes, assuming you do not change the toolchain. If you have build steps that involve custom recipes (for example, executing binaries through a shell script inside a rule), you will need to take some extra care:
* Do not use dependencies that were not declared. Sandboxed execution (–spawn\_strategy=sandboxed, only on Linux) can help find undeclared dependencies.
* Avoid storing timestamps and user-IDs in generated files. ZIP files and other archives are especially prone to this.
* Avoid connecting to the network. Sandboxed execution can help here too.
* Avoid processes that use random numbers, in particular, dictionary traversal is randomized in many programming languages.
## Do you have binary releases?
Yes, you can find the latest [release binaries](https://github.com/bazelbuild/bazel/releases/latest) and review our [release policy](/release/)
## I use Eclipse/IntelliJ/XCode. How does Bazel interoperate with IDEs?
For IntelliJ, check out the [IntelliJ with Bazel plugin](https://ij.bazel.build/).
For XCode, check out [Tulsi](http://tulsi.bazel.build/).
For Eclipse, check out [E4B plugin](https://github.com/bazelbuild/e4b).
For other IDEs, check out the [blog post](https://blog.bazel.build/2016/06/10/ide-support.html) on how these plugins work.
## I use Jenkins/CircleCI/TravisCI. How does Bazel interoperate with CI systems?
Bazel returns a non-zero exit code if the build or test invocation fails, and this should be enough for basic CI integration. Since Bazel does not need clean builds for correctness, the CI system should not be configured to clean before starting a build/test run.
Further details on exit codes are in the [Scripts guide](/run/scripts#exit-codes).
## Can I use Bazel for my INSERT LANGUAGE HERE project?
Bazel is extensible. Anyone can add support for new languages. Many languages are supported: see the [build encyclopedia](/reference/be/overview) for a list of recommendations and [awesomebazel.com](https://awesomebazel.com/) for a more comprehensive list.
If you would like to develop extensions or learn how they work, see the documentation for [extending Bazel](/extending/concepts).
## Can I contribute to the Bazel code base?
See our [contribution guidelines](/contribute/).
## Why isn’t all development done in the open?
We still have to refactor the interfaces between the public code in Bazel and our internal extensions frequently. This makes it hard to do much development in the open.
## Are you done open sourcing Bazel?
Open sourcing Bazel is a work-in-progress. In particular, we’re still working on open sourcing:
* Many of our unit and integration tests (which should make contributing patches easier).
* Full IDE integration.
Beyond code, we’d like to eventually have all code reviews, bug tracking, and design decisions happen publicly, with the Bazel community involved. We are not there yet, so some changes will simply appear in the Bazel repository without clear explanation. Despite this lack of transparency, we want to support external developers and collaborate. Thus, we are opening up the code, even though some of the development is still happening internal to Google. Please let us know if anything seems unclear or unjustified as we transition to an open model.
## Are there parts of Bazel that will never be open sourced?
Yes, some of the code base either integrates with Google-specific technology or we have been looking for an excuse to get rid of (or is some combination of the two). These parts of the code base are not available on GitHub and probably never will be.
## How do I contact the team?
We are reachable at [bazel-discuss@googlegroups.com](mailto:bazel-discuss@googlegroups.com).
## Where do I report bugs?
Open an issue [on GitHub](https://github.com/bazelbuild/bazel/issues).
## What’s up with the word “Blaze” in the codebase?
This is an internal name for the tool. Please refer to Blaze as Bazel.
## Why do other Google projects (Android, Chrome) use other build tools?
Until the first (Alpha) release, Bazel was not available externally, so open source projects such as Chromium and Android could not use it. In addition, the original lack of Windows support was a problem for building Windows applications, such as Chrome. Since the project has matured and become more stable, the [Android Open Source Project](https://source.android.com/) is in the process of migrating to Bazel.
## How do you pronounce “Bazel”?
The same way as “basil” (the herb) in US English: “BAY-zel”. It rhymes with “hazel”. IPA: /ˈbeɪzˌəl/
# Intro to Bazel
Source: https://bazel.build/about/intro
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
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](/rules) are
supported, and you can extend Bazel to support any other language or
framework.
## Using Bazel
To build or test a project with Bazel, you typically do the following:
1. **Set up Bazel.** Download and [install Bazel](/install).
2. **Set up a project [workspace](/concepts/build-ref#workspaces)**, which is a
directory where Bazel looks for build inputs and `BUILD` files, and where it
stores build outputs.
3. **Write a `BUILD` file**, which tells Bazel what to build and how to
build it.
You write your `BUILD` file by declaring build targets using
[Starlark](/rules/language), a domain-specific language. (See example
[here](https://github.com/bazelbuild/bazel/blob/master/examples/cpp/BUILD).)
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.
4. **Run Bazel** from the [command line](/reference/command-line-reference). Bazel
places your outputs within the workspace.
In addition to building, you can also use Bazel to run
[tests](/reference/test-encyclopedia) and [query](/query/guide) the build
to trace dependencies in your code.
## Bazel build process
When running a build or a test, Bazel does the following:
1. **Loads** the `BUILD` files relevant to the target.
2. **Analyzes** the inputs and their
[dependencies](/concepts/dependencies), applies the specified build
rules, and produces an [action](/extending/concepts#evaluation-model)
graph.
3. **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](/basics/hermeticity) through sandboxing, minimizing skew
and maximizing [reproducibility](/run/build#correct-incremental-rebuilds).
### 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](/run/build#build-consistency) 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](/query/guide) in your code.
## Getting started tutorials
To get started with Bazel, see [Getting Started](/start/) or jump
directly to the Bazel tutorials:
* [Tutorial: Build a C++ Project](/start/cpp)
* [Tutorial: Build a Java Project](/start/java)
* [Tutorial: Build an Android Application](/start/android-app)
* [Tutorial: Build an iOS Application](/start/ios-app)
# Bazel Vision
Source: https://bazel.build/about/vision
Any software developer can efficiently build, test, and package
any project, of any size or complexity, with tooling that's easy to adopt and
extend.
* **Engineers can take build fundamentals for granted.** Software developers
focus on the creative process of authoring code because the mechanical
process of build and test is solved. When customizing the build system to
support new languages or unique organizational needs, users focus on the
aspects of extensibility that are unique to their use case, without having
to reinvent the basic plumbing.
* **Engineers can easily contribute to any project.** A developer who wants to
start working on a new project can simply clone the project and run the
build. There's no need for local configuration - it just works. With
cross-platform remote execution, they can work on any machine anywhere and
fully test their changes against all platforms the project targets.
Engineers can quickly configure the build for a new project or incrementally
migrate an existing build.
* **Projects can scale to any size codebase, any size team.** Fast,
incremental testing allows teams to fully validate every change before it is
committed. This remains true even as repos grow, projects span multiple
repos, and multiple languages are introduced. Infrastructure does not force
developers to trade test coverage for build speed.
**We believe Bazel has the potential to fulfill this vision.**
Bazel was built from the ground up to enable builds that are reproducible (a
given set of inputs will always produce the same outputs) and portable (a build
can be run on any machine without affecting the output).
These characteristics support safe incrementality (rebuilding only changed
inputs doesn't introduce the risk of corruption) and distributability (build
actions are isolated and can be offloaded). By minimizing the work needed to do
a correct build and parallelizing that work across multiple cores and remote
systems, Bazel can make any build fast.
Bazel's abstraction layer — instructions specific to languages, platforms, and
toolchains implemented in a simple extensibility language — allows it to be
easily applied to any context.
## Bazel core competencies
1. Bazel supports **multi-language, multi-platform** builds and tests. You can
run a single command to build and test your entire source tree, no matter
which combination of languages and platforms you target.
2. Bazel builds are **fast and correct**. Every build and test run is
incremental, on your developers' machines and on CI.
3. Bazel provides a **uniform, extensible language** to define builds for any
language or platform.
4. Bazel allows your builds **to scale** by connecting to remote execution and
caching services.
5. Bazel works across **all major development platforms** (Linux, MacOS, and
Windows).
6. We accept that adopting Bazel requires effort, but **gradual adoption** is
possible. Bazel interfaces with de-facto standard tools for a given
language/platform.
## Serving language communities
Software engineering evolves in the context of language communities — typically,
self-organizing groups of people who use common tools and practices.
To be of use to members of a language community, high-quality Bazel rules must be
available that integrate with the workflows and conventions of that community.
Bazel is committed to be extensible and open, and to support good rulesets for
any language.
### Requirements of a good ruleset
1. The rules need to support efficient **building and testing** for the
language, including code coverage.
2. The rules need to **interface with a widely-used "package manager"** for the
language (such as Maven for Java), and support incremental migration paths
from other widely-used build systems.
3. The rules need to be **extensible and interoperable**, following
["Bazel sandwich"](https://github.com/bazelbuild/bazel-website/blob/master/designs/_posts/2016-08-04-extensibility-for-native-rules.md)
principles.
4. The rules need to be **remote-execution ready**. In practice, this means
**configurable using the [toolchains](/extending/toolchains) mechanism**.
5. The rules (and Bazel) need to interface with a **widely-used IDE** for the
language, if there is one.
6. The rules need to have **thorough, usable documentation,** with introductory
material for new users, comprehensive docs for expert users.
Each of these items is essential and only together do they deliver on Bazel's
competencies for their particular ecosystem.
They are also, by and large, sufficient - once all are fulfilled, Bazel fully
delivers its value to members of that language community.
# Why Bazel?
Source: https://bazel.build/about/why
Bazel is a [fast](#fast), [correct](#correct), and [extensible](#extensible)
build tool with [integrated testing](#integrated-testing) that supports multiple
[languages](#multi-language), [repositories](#multi-repository), and
[platforms](#multi-platform) in an industry-leading [ecosystem](#ecosystem).
## Bazel is fast
Bazel knows exactly what input files each build command needs, avoiding
unnecessary work by re-running only when the set of input files have
changed between each build.
It runs build commands with as much parallelism as possible, either within the
same computer or on [remote build nodes](/remote/rbe). If the structure of build
allows for it, it can run thousands of build or test commands at the same time.
This is supported by multiple caching layers, in memory, on disk and on the
remote build farm, if available. At Google, we routinely achieve cache hit rates
north of 99%.
## Bazel is correct
Bazel ensures that your binaries are built *only* from your own
source code. Bazel actions run in individual sandboxes and Bazel tracks
every input file of the build, only and always re-running build
commands when it needs to. This keeps your binaries up-to-date so that the
[same source code always results in the same binary](/basics/hermeticity), bit
by bit.
Say goodbye to endless `make clean` invocations and to chasing phantom bugs
that were in fact resolved in source code that never got built.
## Bazel is extensible
Harness the full power of Bazel by writing your own rules and macros to
customize Bazel for your specific needs across a wide range of projects.
Bazel rules are written in [Starlark](/rules/language), our
in-house programming language that's a subset of Python. Starlark makes
rule-writing accessible to most developers, while also creating rules that can
be used across the ecosystem.
## Integrated testing
Bazel's [integrated test runner](/docs/user-manual#running-tests)
knows and runs only those tests needing to be re-run, using remote execution
(if available) to run them in parallel. Detect flakes early by using remote
execution to quickly run a test thousands of times.
Bazel [provides facilities](/remote/bep) to upload test results to a central
location, thereby facilitating efficient communication of test outcomes, be it
on CI or by individual developers.
## Multi-language support
Bazel supports many common programming languages including C++, Java,
Kotlin, Python, Go, and Rust. You can build multiple binaries (for example,
backend, web UI and mobile app) in the same Bazel invocation without being
constrained to one language's idiomatic build tool.
## Multi-repository support
Bazel can [gather source code from multiple locations](/external/overview): you
don't need to vendor your dependencies (but you can!), you can instead point
Bazel to the location of your source code or prebuilt artifacts (e.g. a git
repository or Maven Central), and it takes care of the rest.
## Multi-platform support
Bazel can simultaneously build projects for multiple platforms including Linux,
macOS, Windows, and Android. It also provides powerful
[cross-compilation capabilities](/extending/platforms) to build code for one
platform while running the build on another.
## Wide ecosystem
[Industry leaders](/community/users) love Bazel, building a large
community of developers who use and contribute to Bazel. Find a tools, services
and documentation, including [consulting and SaaS offerings](/community/experts)
Bazel can use. Explore extensions like support for programming languages in
our [open source software repositories](/rules).
# Breaking down build performance
Source: https://bazel.build/advanced/performance/build-performance-breakdown
Bazel is complex and does a lot of different things over the course of a build,
some of which can have an impact on build performance. This page attempts to map
some of these Bazel concepts to their implications on build performance. While
not extensive, we have included some examples of how to detect build performance
issues through [extracting metrics](/configure/build-performance-metrics)
and what you can do to fix them. With this, we hope you can apply these concepts
when investigating build performance regressions.
### Clean vs Incremental builds
A clean build is one that builds everything from scratch, while an incremental
build reuses some already completed work.
We suggest looking at clean and incremental builds separately, especially when
you are collecting / aggregating metrics that are dependent on the state of
Bazel’s caches (for example
[build request size metrics](#deterministic-build-metrics-as-a-proxy-for-build-performance)
). They also represent two different user experiences. As compared to starting
a clean build from scratch (which takes longer due to a cold cache), incremental
builds happen far more frequently as developers iterate on code (typically
faster since the cache is usually already warm).
You can use the `CumulativeMetrics.num_analyses` field in the BEP to classify
builds. If `num_analyses <= 1`, it is a clean build; otherwise, we can broadly
categorize it to likely be an incremental build - the user could have switched
to different flags or different targets causing an effectively clean build. Any
more rigorous definition of incrementality will likely have to come in the form
of a heuristic, for example looking at the number of packages loaded
(`PackageMetrics.packages_loaded`).
### Deterministic build metrics as a proxy for build performance
Measuring build performance can be difficult due to the non-deterministic nature
of certain metrics (for example Bazel’s CPU time or queue times on a remote
cluster). As such, it can be useful to use deterministic metrics as a proxy for
the amount of work done by Bazel, which in turn affects its performance.
The size of a build request can have a significant implication on build
performance. A larger build could represent more work in analyzing and
constructing the build graphs. Organic growth of builds comes naturally with
development, as more dependencies are added/created, and thus grow in complexity
and become more expensive to build.
We can slice this problem into the various build phases, and use the following
metrics as proxy metrics for work done at each phase:
1. `PackageMetrics.packages_loaded`: the number of packages successfully loaded.
A regression here represents more work that needs to be done to read and parse
each additional BUILD file in the loading phase.
* This is often due to the addition of dependencies and having to load their
transitive closure.
* Use [query](/query/quickstart) / [cquery](/query/cquery) to find
where new dependencies might have been added.
2. `TargetMetrics.targets_configured`: representing the number of targets and
aspects configured in the build. A regression represents more work in
constructing and traversing the configured target graph.
* This is often due to the addition of dependencies and having to construct
the graph of their transitive closure.
* Use [cquery](/query/cquery) to find where new
dependencies might have been added.
3. `ActionSummary.actions_created`: represents the actions created in the build,
and a regression represents more work in constructing the action graph. Note
that this also includes unused actions that might not have been executed.
* Use [aquery](/query/aquery) for debugging regressions;
we suggest starting with
[`--output=summary`](/reference/command-line-reference#flag--output)
before further drilling down with
[`--skyframe_state`](/reference/command-line-reference#flag--skyframe_state).
4. `ActionSummary.actions_executed`: the number of actions executed, a
regression directly represents more work in executing these actions.
* The [BEP](/remote/bep) writes out the action statistics
`ActionData` that shows the most executed action types. By default, it
collects the top 20 action types, but you can pass in the
[`--experimental_record_metrics_for_all_mnemonics`](/reference/command-line-reference#flag--experimental_record_metrics_for_all_mnemonics)
to collect this data for all action types that were executed.
* This should help you to figure out what kind of actions were executed
(additionally).
5. `BuildGraphSummary.outputArtifactCount`: the number of artifacts created by
the executed actions.
* If the number of actions executed did not increase, then it is likely that
a rule implementation was changed.
These metrics are all affected by the state of the local cache, hence you will
want to ensure that the builds you extract these metrics from are
**clean builds**.
We have noted that a regression in any of these metrics can be accompanied by
regressions in wall time, cpu time and memory usage.
### Usage of local resources
Bazel consumes a variety of resources on your local machine (both for analyzing
the build graph and driving the execution, and for running local actions), this
can affect the performance / availability of your machine in performing the
build, and also other tasks.
#### Time spent
Perhaps the metrics most susceptible to noise (and can vary greatly from build
to build) is time; in particular - wall time, cpu time and system time. You can
use [bazel-bench](https://github.com/bazelbuild/bazel-bench) to get
a benchmark for these metrics, and with a sufficient number of `--runs`, you can
increase the statistical significance of your measurement.
* **Wall time** is the real world time elapsed.
* If *only* wall time regresses, we suggest collecting a
[JSON trace profile](/advanced/performance/json-trace-profile) and looking
for differences. Otherwise, it would likely be more efficient to
investigate other regressed metrics as they could have affected the wall
time.
* **CPU time** is the time spent by the CPU executing user code.
* If the CPU time regresses across two project commits, we suggest collecting
a Starlark CPU profile. You should probably also use `--nobuild` to
restrict the build to the analysis phase since that is where most of the
CPU heavy work is done.
* System time is the time spent by the CPU in the kernel.
* If system time regresses, it is mostly correlated with I/O when Bazel reads
files from your file system.
#### System-wide load profiling
Using the
[`--experimental_collect_load_average_in_profiler`](https://github.com/bazelbuild/bazel/blob/6.0.0/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java#L306-L312)
flag introduced in Bazel 6.0, the
[JSON trace profiler](/advanced/performance/json-trace-profile) collects the
system load average during the invocation.

**Figure 1.** Profile that includes system load average.
A high load during a Bazel invocation can be an indication that Bazel schedules
too many local actions in parallel for your machine. You might want to look into
adjusting
[`--local_cpu_resources`](/reference/command-line-reference#flag--local_cpu_resources)
and [`--local_ram_resources`](/reference/command-line-reference#flag--local_ram_resources),
especially in container environments (at least until
[#16512](https://github.com/bazelbuild/bazel/pull/16512) is merged).
#### Monitoring Bazel memory usage
There are two main sources to get Bazel’s memory usage, Bazel `info` and the
[BEP](/remote/bep).
* `bazel info used-heap-size-after-gc`: The amount of used memory in bytes after
a call to `System.gc()`.
* [Bazel bench](https://github.com/bazelbuild/bazel-bench)
provides benchmarks for this metric as well.
* Additionally, there are `peak-heap-size`, `max-heap-size`, `used-heap-size`
and `committed-heap-size` (see
[documentation](/docs/user-manual#configuration-independent-data)), but are
less relevant.
* [BEP](/remote/bep)’s
`MemoryMetrics.peak_post_gc_heap_size`: Size of the peak JVM heap size in
bytes post GC (requires setting
[`--memory_profile`](/reference/command-line-reference#flag--memory_profile)
that attempts to force a full GC).
A regression in memory usage is usually a result of a regression in
[build request size metrics](#deterministic_build_metrics_as_a_proxy_for_build_performance),
which are often due to addition of dependencies or a change in the rule
implementation.
To analyze Bazel’s memory footprint on a more granular level, we recommend using
the [built-in memory profiler](/rules/performance#memory-profiling)
for rules.
#### Memory profiling of persistent workers
While [persistent workers](/remote/persistent) can help to speed up builds
significantly (especially for interpreted languages) their memory footprint can
be problematic. Bazel collects metrics on its workers, in particular, the
`WorkerMetrics.WorkerStats.worker_memory_in_kb` field tells how much memory
workers use (by mnemonic).
The [JSON trace profiler](/advanced/performance/json-trace-profile) also
collects persistent worker memory usage during the invocation by passing in the
[`--experimental_collect_system_network_usage`](https://github.com/bazelbuild/bazel/blob/6.0.0/src/main/java/com/google/devtools/build/lib/runtime/CommonCommandOptions.java#L314-L320)
flag (new in Bazel 6.0).

**Figure 2.** Profile that includes workers memory usage.
Lowering the value of
[`--worker_max_instances`](/reference/command-line-reference#flag--worker_max_instances)
(default 4) might help to reduce
the amount of memory used by persistent workers. We are actively working on
making Bazel’s resource manager and scheduler smarter so that such fine tuning
will be required less often in the future.
### Monitoring network traffic for remote builds
In remote execution, Bazel downloads artifacts that were built as a result of
executing actions. As such, your network bandwidth can affect the performance
of your build.
If you are using remote execution for your builds, you might want to consider
monitoring the network traffic during the invocation using the
`NetworkMetrics.SystemNetworkStats` proto from the [BEP](/remote/bep)
(requires passing `--experimental_collect_system_network_usage`).
Furthermore, [JSON trace profiles](/advanced/performance/json-trace-profile)
allow you to view system-wide network usage throughout the course of the build
by passing the `--experimental_collect_system_network_usage` flag (new in Bazel
6.0).

**Figure 3.** Profile that includes system-wide network usage.
A high but rather flat network usage when using remote execution might indicate
that network is the bottleneck in your build; if you are not using it already,
consider turning on Build without the Bytes by passing
[`--remote_download_minimal`](/reference/command-line-reference#flag--remote_download_minimal).
This will speed up your builds by avoiding the download of unnecessary intermediate artifacts.
Another option is to configure a local
[disk cache](/reference/command-line-reference#flag--disk_cache) to save on
download bandwidth.
# Extracting build performance metrics
Source: https://bazel.build/advanced/performance/build-performance-metrics
Probably every Bazel user has experienced builds that were slow or slower than
anticipated. Improving the performance of individual builds has particular value
for targets with significant impact, such as:
1. Core developer targets that are frequently iterated on and (re)built.
2. Common libraries widely depended upon by other targets.
3. A representative target from a class of targets (e.g. custom rules),
diagnosing and fixing issues in one build might help to resolve issues at the
larger scale.
An important step to improving the performance of builds is to understand where
resources are spent. This page lists different metrics you can collect.
[Breaking down build performance](/configure/build-performance-breakdown) showcases
how you can use these metrics to detect and fix build performance issues.
There are a few main ways to extract metrics from your Bazel builds, namely:
## Build Event Protocol (BEP)
Bazel outputs a variety of protocol buffers
[`build_event_stream.proto`](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto)
through the [Build Event Protocol (BEP)](/remote/bep), which
can be aggregated by a backend specified by you. Depending on your use cases,
you might decide to aggregate the metrics in various ways, but here we will go
over some concepts and proto fields that would be useful in general to consider.
## Bazel’s query / cquery / aquery commands
Bazel provides 3 different query modes ([query](/query/quickstart),
[cquery](/query/cquery) and [aquery](/query/aquery)) that allow users
to query the target graph, configured target graph and action graph
respectively. The query language provides a
[suite of functions](/query/language#functions) usable across the different
query modes, that allows you to customize your queries according to your needs.
## JSON Trace Profiles
For every build-like Bazel invocation, Bazel writes a trace profile in JSON
format. The [JSON trace profile](/advanced/performance/json-trace-profile) can
be very useful to quickly understand what Bazel spent time on during the
invocation.
## Execution Log
The [execution log](/remote/cache-remote) can help you to troubleshoot and fix
missing remote cache hits due to machine and environment differences or
non-deterministic actions. If you pass the flag
[`--experimental_execution_log_spawn_metrics`](/reference/command-line-reference#flag--experimental_execution_log_spawn_metrics)
(available from Bazel 5.2) it will also contain detailed spawn metrics, both for
locally and remotely executed actions. You can use these metrics for example to
make comparisons between local and remote machine performance or to find out
which part of the spawn execution is consistently slower than expected (for
example due to queuing).
## Execution Graph Log
While the JSON trace profile contains the critical path information, sometimes
you need additional information on the dependency graph of the executed actions.
Starting with Bazel 6.0, you can pass the flags
`--experimental_execution_graph_log` and
`--experimental_execution_graph_log_dep_type=all` to write out a log about the
executed actions and their inter-dependencies.
This information can be used to understand the drag that is added by a node on
the critical path. The drag is the amount of time that can potentially be saved
by removing a particular node from the execution graph.
The data helps you predict the impact of changes to the build and action graph
before you actually do them.
## Benchmarking with bazel-bench
[Bazel bench](https://github.com/bazelbuild/bazel-bench) is a
benchmarking tool for Git projects to benchmark build performance in the
following cases:
* **Project benchmark:** Benchmarking two git commits against each other at a
single Bazel version. Used to detect regressions in your build (often through
the addition of dependencies).
* **Bazel benchmark:** Benchmarking two versions of Bazel against each other at
a single git commit. Used to detect regressions within Bazel itself (if you
happen to maintain / fork Bazel).
Benchmarks monitor wall time, CPU time and system time and Bazel’s retained
heap size.
It is also recommended to run Bazel bench on dedicated, physical machines that
are not running other processes so as to reduce sources of variability.
# Optimize Iteration Speed
Source: https://bazel.build/advanced/performance/iteration-speed
This page describes how to optimize Bazel's build performance when running Bazel
repeatedly.
## Bazel's Runtime State
A Bazel invocation involves several interacting parts.
* The `bazel` command line interface (CLI) is the user-facing front-end tool
and receives commands from the user.
* The CLI tool starts a [*Bazel server*](https://bazel.build/run/client-server)
for each distinct [output base](https://bazel.build/remote/output-directories).
The Bazel server is generally persistent, but will shut down after some idle
time so as to not waste resources.
* The Bazel server performs the loading and analysis steps for a given command
(`build`, `run`, `cquery`, etc.), in which it constructs the necessary parts
of the build graph in memory. The resulting data structures are retained in
the Bazel server as part of the *analysis cache*.
* The Bazel server can also perform the action execution, or it can send
actions off for remote execution if it is set up to do so. The results of
action executions are also cached, namely in the *action cache* (or
*execution cache*, which may be either local or remote, and it may be shared
among Bazel servers).
* The result of the Bazel invocation is made available in the output tree.
## Running Bazel Iteratively
In a typical developer workflow, it is common to build (or run) a piece of code
repeatedly, often at a very high frequency (e.g. to resolve some compilation
error or investigate a failing test). In this situation, it is important that
repeated invocations of `bazel` have as little overhead as possible relative to
the underlying, repeated action (e.g. invoking a compiler, or executing a test).
With this in mind, we take another look at Bazel's runtime state:
The analysis cache is a critical piece of data. A significant amount of time can
be spent just on the loading and analysis phases of a cold run (i.e. a run just
after the Bazel server was started or when the analysis cache was discarded).
For a single, successful cold build (e.g. for a production release) this cost is
bearable, but for repeatedly building the same target it is important that this
cost be amortized and not repeated on each invocation.
The analysis cache is rather volatile. First off, it is part of the in-process
state of the Bazel server, so losing the server loses the cache. But the cache
is also *invalidated* very easily: for example, many `bazel` command line flags
cause the cache to be discarded. This is because many flags affect the build
graph (e.g. because of
[configurable attributes](https://bazel.build/configure/attributes)). Some flag
changes can also cause the Bazel server to be restarted (e.g. changing
[startup options](https://bazel.build/docs/user-manual#startup-options)).
A good execution cache is also valuable for build performance. An execution
cache can be kept locally
[on disk](https://bazel.build/remote/caching#disk-cache), or
[remotely](https://bazel.build/remote/caching). The cache can be shared among
Bazel servers, and indeed among developers.
## Avoid discarding the analysis cache
Bazel will print a warning if either the analysis cache was discarded or the
server was restarted. Either of these should be avoided during iterative use:
* Be mindful of changing `bazel` flags in the middle of an iterative
workflow. For example, mixing a `bazel build -c opt` with a `bazel cquery`
causes each command to discard the analysis cache of the other. In general,
try to use a fixed set of flags for the duration of a particular workflow.
* Losing the Bazel server loses the analysis cache. The Bazel server has a
[configurable](https://bazel.build/docs/user-manual#max-idle-secs) idle
time, after which it shuts down. You can configure this time via your
bazelrc file to suit your needs. The server also restarted when startup
flags change, so, again, avoid changing those flags if possible.
* Beware that the Bazel server is killed if you press
Ctrl-C repeatedly while Bazel is running. It is tempting to try to save time
by interrupting a running build that is no longer needed, but only press
Ctrl-C once to request a graceful end of the current invocation.
* If you want to use multiple sets of flags from the same workspace, you can
use multiple, distinct output bases, switched with the `--output_base`
flag. Each output base gets its own Bazel server.
To make this condition an error rather than a warning, you can use the
`--noallow_analysis_cache_discard` flag (introduced in Bazel 6.4.0)
# JSON Trace Profile
Source: https://bazel.build/advanced/performance/json-trace-profile
The JSON trace profile can be very useful to quickly understand what Bazel spent
time on during the invocation.
By default, for all build-like commands and query, Bazel writes a profile into
the output base named `command-$INVOCATION_ID.profile.gz`, where
`$INVOCATION_ID` is the invocation identifier of the command. Bazel also creates
a symlink called `command.profile.gz` in the output base that points the profile
of the latest command. You can configure whether a profile is written with the
[`--generate_json_trace_profile`](/reference/command-line-reference#flag--generate_json_trace_profile)
flag, and the location it is written to with the
[`--profile`](/docs/user-manual#profile) flag. Locations ending with `.gz` are
compressed with GZIP. Bazel keeps the last 5 profiles, configurable by
[`--profiles_to_retain`](/reference/command-line-reference#flag--generate_json_trace_profile),
in the output base by default for post-build analysis. Explicitly passing a
profile path with `--profile` disables automatic garbage collection.
## Tools
You can load this profile into `chrome://tracing` or analyze and
post-process it with other tools.
### `chrome://tracing`
To visualize the profile, open `chrome://tracing` in a Chrome browser tab,
click "Load" and pick the (potentially compressed) profile file. For more
detailed results, click the boxes in the lower left corner.
Example profile:

**Figure 1.** Example profile.
You can use these keyboard controls to navigate:
* Press `1` for "select" mode. In this mode, you can select
particular boxes to inspect the event details (see lower left corner).
Select multiple events to get a summary and aggregated statistics.
* Press `2` for "pan" mode. Then drag the mouse to move the view. You
can also use `a`/`d` to move left/right.
* Press `3` for "zoom" mode. Then drag the mouse to zoom. You can
also use `w`/`s` to zoom in/out.
* Press `4` for "timing" mode where you can measure the distance
between two events.
* Press `?` to learn about all controls.
### Bazel Invocation Analyzer
The open-source
[Bazel Invocation Analyzer](https://github.com/EngFlow/bazel_invocation_analyzer)
consumes a profile format and prints suggestions on how to improve
the build’s performance. This analysis can be performed using its CLI or on
[https://analyzer.engflow.com](https://analyzer.engflow.com).
### `jq`
`jq` is like `sed` for JSON data. An example usage of `jq` to extract all
durations of the sandbox creation step in local action execution:
```
$ zcat $(../bazel-6.0.0rc1-linux-x86_64 info output_base)/command.profile.gz | jq '.traceEvents | .[] | select(.name == "sandbox.createFileSystem") | .dur'
6378
7247
11850
13756
6555
7445
8487
15520
[...]
```
## Profile information
The profile contains multiple rows. Usually the bulk of rows represent Bazel
threads and their corresponding events, but some special rows are also included.
The special rows included depend on the version of Bazel invoked when the
profile was created, and may be customized by different flags.
Figure 1 shows a profile created with Bazel v5.3.1 and includes these rows:
* `action count`: Displays how many concurrent actions were in flight. Click
on it to see the actual value. Should go up to the value of
[`--jobs`](/reference/command-line-reference#flag--jobs) in clean
builds.
* `CPU usage (Bazel)`: For each second of the build, displays the amount of
CPU that was used by Bazel (a value of 1 equals one core being 100% busy).
* `Critical Path`: Displays one block for each action on the critical path.
* `Main Thread`: Bazel’s main thread. Useful to get a high-level picture of
what Bazel is doing, for example "Launch Blaze", "evaluateTargetPatterns",
and "runAnalysisPhase".
* `Garbage Collector`: Displays minor and major Garbage Collection (GC)
pauses.
## Common performance issues
When analyzing performance profiles, look for:
* Slower than expected analysis phase (`runAnalysisPhase`), especially on
incremental builds. This can be a sign of a poor rule implementation, for
example one that flattens depsets. Package loading can be slow by an
excessive amount of targets, complex macros or recursive globs.
* Individual slow actions, especially those on the critical path. It might be
possible to split large actions into multiple smaller actions or reduce the
set of (transitive) dependencies to speed them up. Also check for an unusual
high non-`PROCESS_TIME` (such as `REMOTE_SETUP` or `FETCH`).
* Bottlenecks, that is a small number of threads is busy while all others are
idling / waiting for the result (see around 22s and 29s in Figure 1).
Optimizing this will most likely require touching the rule implementations
or Bazel itself to introduce more parallelism. This can also happen when
there is an unusual amount of GC.
## Profile file format
The top-level object contains metadata (`otherData`) and the actual tracing data
(`traceEvents`). The metadata contains extra info, for example the invocation ID
and date of the Bazel invocation.
Example:
```json theme={null}
{
"otherData": {
"build_id": "101bff9a-7243-4c1a-8503-9dc6ae4c3b05",
"date": "Wed Oct 26 08:22:35 CEST 2022",
"profile_finish_ts": "1677666095162000",
"output_base": "/usr/local/google/_bazel_johndoe/573d4be77eaa72b91a3dfaa497bf8cd0"
},
"traceEvents": [
{"name":"thread_name","ph":"M","pid":1,"tid":0,"args":{"name":"Critical Path"}},
...
{"cat":"build phase marker","name":"Launch Blaze","ph":"X","ts":-1306000,"dur":1306000,"pid":1,"tid":21},
...
{"cat":"package creation","name":"foo","ph":"X","ts":2685358,"dur":784,"pid":1,"tid":246},
...
{"name":"thread_name","ph":"M","pid":1,"tid":11,"args":{"name":"Garbage Collector"}},
{"cat":"gc notification","name":"minor GC","ph":"X","ts":825986,"dur":11000,"pid":1,"tid":11},
...
{"cat":"action processing","name":"Compiling foo/bar.c","ph":"X","ts":54413389,"dur":357594,"pid":1,"args":{"mnemonic":"CppCompile"},"tid":341},
]
}
```
Timestamps (`ts`) and durations (`dur`) in the trace events are given in
microseconds. The category (`cat`) is one of enum values of `ProfilerTask`.
Note that some events are merged together if they are very short and close to
each other; pass
[`--noslim_profile`](/reference/command-line-reference#flag--slim_profile)
if you would like to prevent event merging.
See also the
[Chrome Trace Event Format Specification](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview).
# Optimize Memory
Source: https://bazel.build/advanced/performance/memory
This page describes how to limit and reduce the memory Bazel uses.
## Running Bazel with Limited RAM
In certain situations, you may want Bazel to use minimal memory. You can set the
maximum heap via the startup flag
[`--host_jvm_args`](/docs/user-manual#host-jvm-args),
like `--host_jvm_args=-Xmx2g`.
### Trade incremental build speeds for memory
If your builds are too big, Bazel may throw an `OutOfMemoryError` (OOM) when
it doesn't have enough memory. You can make Bazel use less memory, at the cost
of slower incremental builds, by passing the following command flags:
[`--discard_analysis_cache`](/docs/user-manual#discard-analysis-cache),
[`--nokeep_state_after_build`](/reference/command-line-reference#flag--keep_state_after_build),
and
[`--notrack_incremental_state`](/reference/command-line-reference#flag--track_incremental_state).
These flags will minimize the memory that Bazel uses in a build, at the cost of
making future builds slower than a standard incremental build would be.
You can also pass any one of these flags individually:
* `--discard_analysis_cache` will reduce the memory used during execution (not
analysis). Incremental builds will not have to redo package loading, but will
have to redo analysis and execution (although the on-disk action cache can
prevent most re-execution).
* `--notrack_incremental_state` will not store any edges in Bazel's internal
dependency graph, so that it is unusable for incremental builds. The next build
will discard that data, but it is preserved until then, for internal debugging,
unless `--nokeep_state_after_build` is specified.
* `--nokeep_state_after_build` will discard all data after the build, so that
incremental builds have to build from scratch (except for the on-disk action
cache). Alone, it does not affect the high-water mark of the current build.
## Memory Profiling
Bazel comes with a built-in memory profiler that can help you check your rule’s
memory use. Read more about this process on the
[Memory Profiling section](/rules/performance#memory-profiling) of our
documentation on how to improve the performance of custom rules.
# Artifact-Based Build Systems
Source: https://bazel.build/basics/artifact-based-builds
This page covers artifact-based build systems and the philosophy behind their
creation. Bazel is an artifact-based build system. While task-based build
systems are good step above build scripts, they give too much power to
individual engineers by letting them define their own tasks.
Artifact-based build systems have a small number of tasks defined by the system
that engineers can configure in a limited way. Engineers still tell the system
**what** to build, but the build system determines **how** to build it. As with
task-based build systems, artifact-based build systems, such as Bazel, still
have buildfiles, but the contents of those buildfiles are very different. Rather
than being an imperative set of commands in a Turing-complete scripting language
describing how to produce an output, buildfiles in Bazel are a declarative
manifest describing a set of artifacts to build, their dependencies, and a
limited set of options that affect how they’re built. When engineers run `bazel`
on the command line, they specify a set of targets to build (the **what**), and
Bazel is responsible for configuring, running, and scheduling the compilation
steps (the **how**). Because the build system now has full control over what
tools to run when, it can make much stronger guarantees that allow it to be far
more efficient while still guaranteeing correctness.
## A functional perspective
It’s easy to make an analogy between artifact-based build systems and functional
programming. Traditional imperative programming languages (such as, Java, C, and
Python) specify lists of statements to be executed one after another, in the
same way that task-based build systems let programmers define a series of steps
to execute. Functional programming languages (such as, Haskell and ML), in
contrast, are structured more like a series of mathematical equations. In
functional languages, the programmer describes a computation to perform, but
leaves the details of when and exactly how that computation is executed to the
compiler.
This maps to the idea of declaring a manifest in an artifact-based build system
and letting the system figure out how to execute the build. Many problems can't
be easily expressed using functional programming, but the ones that do benefit
greatly from it: the language is often able to trivially parallelize such
programs and make strong guarantees about their correctness that would be
impossible in an imperative language. The easiest problems to express using
functional programming are the ones that simply involve transforming one piece
of data into another using a series of rules or functions. And that’s exactly
what a build system is: the whole system is effectively a mathematical function
that takes source files (and tools like the compiler) as inputs and produces
binaries as outputs. So, it’s not surprising that it works well to base a build
system around the tenets of functional programming.
## Understanding artifact-based build systems
Google's build system, Blaze, was the first artifact-based build system. Bazel
is the open-sourced version of Blaze.
Here’s what a buildfile (normally named `BUILD`) looks like in Bazel:
```python theme={null}
java_binary(
name = "MyBinary",
srcs = ["MyBinary.java"],
deps = [
":mylib",
],
)
java_library(
name = "mylib",
srcs = ["MyLibrary.java", "MyHelper.java"],
visibility = ["//java/com/example/myproduct:__subpackages__"],
deps = [
"//java/com/example/common",
"//java/com/example/myproduct/otherlib",
],
)
```
In Bazel, `BUILD` files define targets—the two types of targets here are
`java_binary` and `java_library`. Every target corresponds to an artifact that
can be created by the system: binary targets produce binaries that can be
executed directly, and library targets produce libraries that can be used by
binaries or other libraries. Every target has:
* `name`: how the target is referenced on the command line and by other
targets
* `srcs`: the source files to be compiled to create the artifact for the target
* `deps`: other targets that must be built before this target and linked into
it
Dependencies can either be within the same package (such as `MyBinary`’s
dependency on `:mylib`) or on a different package in the same source hierarchy
(such as `mylib`’s dependency on `//java/com/example/common`).
As with task-based build systems, you perform builds using Bazel’s command-line
tool. To build the `MyBinary` target, you run `bazel build :MyBinary`. After
entering that command for the first time in a clean repository, Bazel:
1. Parses every `BUILD` file in the workspace to create a graph of dependencies
among artifacts.
2. Uses the graph to determine the transitive dependencies of `MyBinary`; that
is, every target that `MyBinary` depends on and every target that those
targets depend on, recursively.
3. Builds each of those dependencies, in order. Bazel starts by building each
target that has no other dependencies and keeps track of which dependencies
still need to be built for each target. As soon as all of a target’s
dependencies are built, Bazel starts building that target. This process
continues until every one of `MyBinary`’s transitive dependencies have been
built.
4. Builds `MyBinary` to produce a final executable binary that links in all of
the dependencies that were built in step 3.
Fundamentally, it might not seem like what’s happening here is that much
different than what happened when using a task-based build system. Indeed, the
end result is the same binary, and the process for producing it involved
analyzing a bunch of steps to find dependencies among them, and then running
those steps in order. But there are critical differences. The first one appears
in step 3: because Bazel knows that each target only produces a Java library, it
knows that all it has to do is run the Java compiler rather than an arbitrary
user-defined script, so it knows that it’s safe to run these steps in parallel.
This can produce an order of magnitude performance improvement over building
targets one at a time on a multicore machine, and is only possible because the
artifact-based approach leaves the build system in charge of its own execution
strategy so that it can make stronger guarantees about parallelism.
The benefits extend beyond parallelism, though. The next thing that this
approach gives us becomes apparent when the developer types `bazel
build :MyBinary` a second time without making any changes: Bazel exits in less
than a second with a message saying that the target is up to date. This is
possible due to the functional programming paradigm we talked about
earlier—Bazel knows that each target is the result only of running a Java
compiler, and it knows that the output from the Java compiler depends only on
its inputs, so as long as the inputs haven’t changed, the output can be reused.
And this analysis works at every level; if `MyBinary.java` changes, Bazel knows
to rebuild `MyBinary` but reuse `mylib`. If a source file for
`//java/com/example/common` changes, Bazel knows to rebuild that library,
`mylib`, and `MyBinary`, but reuse `//java/com/example/myproduct/otherlib`.
Because Bazel knows about the properties of the tools it runs at every step,
it’s able to rebuild only the minimum set of artifacts each time while
guaranteeing that it won’t produce stale builds.
Reframing the build process in terms of artifacts rather than tasks is subtle
but powerful. By reducing the flexibility exposed to the programmer, the build
system can know more about what is being done at every step of the build. It can
use this knowledge to make the build far more efficient by parallelizing build
processes and reusing their outputs. But this is really just the first step, and
these building blocks of parallelism and reuse form the basis for a distributed
and highly scalable build system.
## Other nifty Bazel tricks
Artifact-based build systems fundamentally solve the problems with parallelism
and reuse that are inherent in task-based build systems. But there are still a
few problems that came up earlier that we haven’t addressed. Bazel has clever
ways of solving each of these, and we should discuss them before moving on.
### Tools as dependencies
One problem we ran into earlier was that builds depended on the tools installed
on our machine, and reproducing builds across systems could be difficult due to
different tool versions or locations. The problem becomes even more difficult
when your project uses languages that require different tools based on which
platform they’re being built on or compiled for (such as, Windows versus Linux),
and each of those platforms requires a slightly different set of tools to do the
same job.
Bazel solves the first part of this problem by treating tools as dependencies to
each target. Every `java_library` in the workspace implicitly depends on a Java
compiler, which defaults to a well-known compiler. Whenever Bazel builds a
`java_library`, it checks to make sure that the specified compiler is available
at a known location. Just like any other dependency, if the Java compiler
changes, every artifact that depends on it is rebuilt.
Bazel solves the second part of the problem, platform independence, by setting
[build configurations](/run/build#build-config-cross-compilation). Rather than
targets depending directly on their tools, they depend on types of configurations:
* **Host configuration**: building tools that run during the build
* **Target configuration**: building the binary you ultimately requested
### Extending the build system
Bazel comes with targets for several popular programming languages out of the
box, but engineers will always want to do more—part of the benefit of task-based
systems is their flexibility in supporting any kind of build process, and it
would be better not to give that up in an artifact-based build system.
Fortunately, Bazel allows its supported target types to be extended by
[adding custom rules](/extending/rules).
To define a rule in Bazel, the rule author declares the inputs that the rule
requires (in the form of attributes passed in the `BUILD` file) and the fixed
set of outputs that the rule produces. The author also defines the actions that
will be generated by that rule. Each action declares its inputs and outputs,
runs a particular executable or writes a particular string to a file, and can be
connected to other actions via its inputs and outputs. This means that actions
are the lowest-level composable unit in the build system—an action can do
whatever it wants so long as it uses only its declared inputs and outputs, and
Bazel takes care of scheduling actions and caching their results as appropriate.
The system isn’t foolproof given that there’s no way to stop an action developer
from doing something like introducing a nondeterministic process as part of
their action. But this doesn’t happen very often in practice, and pushing the
possibilities for abuse all the way down to the action level greatly decreases
opportunities for errors. Rules supporting many common languages and tools are
widely available online, and most projects will never need to define their own
rules. Even for those that do, rule definitions only need to be defined in one
central place in the repository, meaning most engineers will be able to use
those rules without ever having to worry about their implementation.
### Isolating the environment
Actions sound like they might run into the same problems as tasks in other
systems—isn’t it still possible to write actions that both write to the same
file and end up conflicting with one another? Actually, Bazel makes these
conflicts impossible by using *[sandboxing](/docs/sandboxing)*. On supported
systems, every action is isolated from every other action via a filesystem
sandbox. Effectively, each action can see only a restricted view of the
filesystem that includes the inputs it has declared and any outputs it has
produced. This is enforced by systems such as LXC on Linux, the same technology
behind Docker. This means that it’s impossible for actions to conflict with one
another because they are unable to read any files they don’t declare, and any
files that they write but don’t declare will be thrown away when the action
finishes. Bazel also uses sandboxes to restrict actions from communicating via
the network.
### Making external dependencies deterministic
There’s still one problem remaining: build systems often need to download
dependencies (whether tools or libraries) from external sources rather than
directly building them. This can be seen in the example via the
`@com_google_common_guava_guava//jar` dependency, which downloads a `JAR` file
from Maven.
Depending on files outside of the current workspace is risky. Those files could
change at any time, potentially requiring the build system to constantly check
whether they’re fresh. If a remote file changes without a corresponding change
in the workspace source code, it can also lead to unreproducible builds—a build
might work one day and fail the next for no obvious reason due to an unnoticed
dependency change. Finally, an external dependency can introduce a huge security
risk when it is owned by a third party: if an attacker is able to infiltrate
that third-party server, they can replace the dependency file with something of
their own design, potentially giving them full control over your build
environment and its output.
The fundamental problem is that we want the build system to be aware of these
files without having to check them into source control. Updating a dependency
should be a conscious choice, but that choice should be made once in a central
place rather than managed by individual engineers or automatically by the
system. This is because even with a “Live at Head” model, we still want builds
to be deterministic, which implies that if you check out a commit from last
week, you should see your dependencies as they were then rather than as they are
now.
Bazel and some other build systems address this problem by requiring a
workspacewide manifest file that lists a *cryptographic hash* for every external
dependency in the workspace. The hash is a concise way to uniquely represent the
file without checking the entire file into source control. Whenever a new
external dependency is referenced from a workspace, that dependency’s hash is
added to the manifest, either manually or automatically. When Bazel runs a
build, it checks the actual hash of its cached dependency against the expected
hash defined in the manifest and redownloads the file only if the hash differs.
If the artifact we download has a different hash than the one declared in the
manifest, the build will fail unless the hash in the manifest is updated. This
can be done automatically, but that change must be approved and checked into
source control before the build will accept the new dependency. This means that
there’s always a record of when a dependency was updated, and an external
dependency can’t change without a corresponding change in the workspace source.
It also means that, when checking out an older version of the source code, the
build is guaranteed to use the same dependencies that it was using at the point
when that version was checked in (or else it will fail if those dependencies are
no longer available).
Of course, it can still be a problem if a remote server becomes unavailable or
starts serving corrupt data—this can cause all of your builds to begin failing
if you don’t have another copy of that dependency available. To avoid this
problem, we recommend that, for any nontrivial project, you mirror all of its
dependencies onto servers or services that you trust and control. Otherwise you
will always be at the mercy of a third party for your build system’s
availability, even if the checked-in hashes guarantee its security.
# Why a Build System?
Source: https://bazel.build/basics/build-systems
This page discusses what build systems are, what they do, why you should use a
build system, and why compilers and build scripts aren't the best choice as your
organization starts to scale. It's intended for developers who don't have much
experience with a build system.
## What is a build system?
Fundamentally, all build systems have a straightforward purpose: they transform
the source code written by engineers into executable binaries that can be read
by machines. Build systems aren't just for human-authored code; they also allow
machines to create builds automatically, whether for testing or for releases to
production. In an organization with thousands of engineers, it's common that
most builds are triggered automatically rather than directly by engineers.
### Can't I just use a compiler?
The need for a build system might not be immediately obvious. Most engineers
don't use a build system while learning to code: most start by invoking tools
like `gcc` or `javac` directly from the command line, or the equivalent in an
integrated development environment (IDE). As long as all the source code is in
the same directory, a command like this works fine:
```posix-terminal theme={null}
javac *.java
```
This instructs the Java compiler to take every Java source file in the current
directory and turn it into a binary class file. In the simplest case, this is
all you need.
However, as soon as code expands, the complications begin. `javac` is smart
enough to look in subdirectories of the current directory to find code to
import. But it has no way of finding code stored in *other parts* of the
filesystem (perhaps a library shared by several projects). It also only knows
how to build Java code. Large systems often involve different pieces written in
a variety of programming languages with webs of dependencies among those pieces,
meaning no compiler for a single language can possibly build the entire system.
Once you're dealing with code from multiple languages or multiple compilation
units, building code is no longer a one-step process. Now you must evaluate what
your code depends on and build those pieces in the proper order, possibly using
a different set of tools for each piece. If any dependencies change, you must
repeat this process to avoid depending on stale binaries. For a codebase of even
moderate size, this process quickly becomes tedious and error-prone.
The compiler also doesn’t know anything about how to handle external
dependencies, such as third-party `JAR` files in Java. Without a build system,
you could manage this by downloading the dependency from the internet, sticking
it in a `lib` folder on the hard drive, and configuring the compiler to read
libraries from that directory. Over time, it's difficult to maintain the
updates, versions, and source of these external dependencies.
### What about shell scripts?
Suppose that your hobby project starts out simple enough that you can build it
using just a compiler, but you begin running into some of the problems described
previously. Maybe you still don’t think you need a build system and can automate
away the tedious parts using some simple shell scripts that take care of
building things in the correct order. This helps out for a while, but pretty
soon you start running into even more problems:
* It becomes tedious. As your system grows more complex, you begin spending
almost as much time working on your build scripts as on real code. Debugging
shell scripts is painful, with more and more hacks being layered on top of
one another.
* It’s slow. To make sure you weren’t accidentally relying on stale libraries,
you have your build script build every dependency in order every time you
run it. You think about adding some logic to detect which parts need to be
rebuilt, but that sounds awfully complex and error prone for a script. Or
you think about specifying which parts need to be rebuilt each time, but
then you’re back to square one.
* Good news: it’s time for a release! Better go figure out all the arguments
you need to pass to the jar command to make your final build. And remember
how to upload it and push it out to the central repository. And build and
push the documentation updates, and send out a notification to users. Hmm,
maybe this calls for another script...
* Disaster! Your hard drive crashes, and now you need to recreate your entire
system. You were smart enough to keep all of your source files in version
control, but what about those libraries you downloaded? Can you find them
all again and make sure they were the same version as when you first
downloaded them? Your scripts probably depended on particular tools being
installed in particular places—can you restore that same environment so that
the scripts work again? What about all those environment variables you set a
long time ago to get the compiler working just right and then forgot about?
* Despite the problems, your project is successful enough that you’re able to
begin hiring more engineers. Now you realize that it doesn’t take a disaster
for the previous problems to arise—you need to go through the same painful
bootstrapping process every time a new developer joins your team. And
despite your best efforts, there are still small differences in each
person’s system. Frequently, what works on one person’s machine doesn’t work
on another’s, and each time it takes a few hours of debugging tool paths or
library versions to figure out where the difference is.
* You decide that you need to automate your build system. In theory, this is
as simple as getting a new computer and setting it up to run your build
script every night using cron. You still need to go through the painful
setup process, but now you don’t have the benefit of a human brain being
able to detect and resolve minor problems. Now, every morning when you get
in, you see that last night’s build failed because yesterday a developer
made a change that worked on their system but didn’t work on the automated
build system. Each time it’s a simple fix, but it happens so often that you
end up spending a lot of time each day discovering and applying these simple
fixes.
* Builds become slower and slower as the project grows. One day, while waiting
for a build to complete, you gaze mournfully at the idle desktop of your
coworker, who is on vacation, and wish there were a way to take advantage of
all that wasted computational power.
You’ve run into a classic problem of scale. For a single developer working on at
most a couple hundred lines of code for at most a week or two (which might have
been the entire experience thus far of a junior developer who just graduated
university), a compiler is all you need. Scripts can maybe take you a little bit
farther. But as soon as you need to coordinate across multiple developers and
their machines, even a perfect build script isn’t enough because it becomes very
difficult to account for the minor differences in those machines. At this point,
this simple approach breaks down and it’s time to invest in a real build system.
# Dependency Management
Source: https://bazel.build/basics/dependencies
In looking through the previous pages, one theme repeats over and over: managing
your own code is fairly straightforward, but managing its dependencies is much
more difficult. There are all sorts of dependencies: sometimes there’s a
dependency on a task (such as “push the documentation before I mark a release as
complete”), and sometimes there’s a dependency on an artifact (such as “I need
to have the latest version of the computer vision library to build my code”).
Sometimes, you have internal dependencies on another part of your codebase, and
sometimes you have external dependencies on code or data owned by another team
(either in your organization or a third party). But in any case, the idea of “I
need that before I can have this” is something that recurs repeatedly in the
design of build systems, and managing dependencies is perhaps the most
fundamental job of a build system.
## Dealing with Modules and Dependencies
Projects that use artifact-based build systems like Bazel are broken into a set
of modules, with modules expressing dependencies on one another via `BUILD`
files. Proper organization of these modules and dependencies can have a huge
effect on both the performance of the build system and how much work it takes to
maintain.
## Using Fine-Grained Modules and the 1:1:1 Rule
The first question that comes up when structuring an artifact-based build is
deciding how much functionality an individual module should encompass. In Bazel,
a *module* is represented by a target specifying a buildable unit like a
`java_library` or a `go_binary`. At one extreme, the entire project could be
contained in a single module by putting one `BUILD` file at the root and
recursively globbing together all of that project’s source files. At the other
extreme, nearly every source file could be made into its own module, effectively
requiring each file to list in a `BUILD` file every other file it depends on.
Most projects fall somewhere between these extremes, and the choice involves a
trade-off between performance and maintainability. Using a single module for the
entire project might mean that you never need to touch the `BUILD` file except
when adding an external dependency, but it means that the build system must
always build the entire project all at once. This means that it won’t be able to
parallelize or distribute parts of the build, nor will it be able to cache parts
that it’s already built. One-module-per-file is the opposite: the build system
has the maximum flexibility in caching and scheduling steps of the build, but
engineers need to expend more effort maintaining lists of dependencies whenever
they change which files reference which.
Though the exact granularity varies by language (and often even within
language), Google tends to favor significantly smaller modules than one might
typically write in a task-based build system. A typical production binary at
Google often depends on tens of thousands of targets, and even a moderate-sized
team can own several hundred targets within its codebase. For languages like
Java that have a strong built-in notion of packaging, each directory usually
contains a single package, target, and `BUILD` file (Pants, another build system
based on Bazel, calls this the 1:1:1 rule). Languages with weaker packaging
conventions frequently define multiple targets per `BUILD` file.
The benefits of smaller build targets really begin to show at scale because they
lead to faster distributed builds and a less frequent need to rebuild targets.
The advantages become even more compelling after testing enters the picture, as
finer-grained targets mean that the build system can be much smarter about
running only a limited subset of tests that could be affected by any given
change. Because Google believes in the systemic benefits of using smaller
targets, we’ve made some strides in mitigating the downside by investing in
tooling to automatically manage `BUILD` files to avoid burdening developers.
Some of these tools, such as `buildifier` and `buildozer`, are available with
Bazel in the [`buildtools` directory](https://github.com/bazelbuild/buildtools).
## Minimizing Module Visibility
Bazel and other build systems allow each target to specify a visibility — a
property that determines which other targets may depend on it. A private target
can only be referenced within its own `BUILD` file. A target may grant broader
visibility to the targets of an explicitly defined list of `BUILD` files, or, in
the case of public visibility, to every target in the workspace.
As with most programming languages, it is usually best to minimize visibility as
much as possible. Generally, teams at Google will make targets public only if
those targets represent widely used libraries available to any team at Google.
Teams that require others to coordinate with them before using their code will
maintain an allowlist of customer targets as their target’s visibility. Each
team’s internal implementation targets will be restricted to only directories
owned by the team, and most `BUILD` files will have only one target that isn’t
private.
## Managing Dependencies
Modules need to be able to refer to one another. The downside of breaking a
codebase into fine-grained modules is that you need to manage the dependencies
among those modules (though tools can help automate this). Expressing these
dependencies usually ends up being the bulk of the content in a `BUILD` file.
### Internal dependencies
In a large project broken into fine-grained modules, most dependencies are
likely to be internal; that is, on another target defined and built in the same
source repository. Internal dependencies differ from external dependencies in
that they are built from source rather than downloaded as a prebuilt artifact
while running the build. This also means that there’s no notion of “version” for
internal dependencies—a target and all of its internal dependencies are always
built at the same commit/revision in the repository. One issue that should be
handled carefully with regard to internal dependencies is how to treat
transitive dependencies (Figure 1). Suppose target A depends on target B, which
depends on a common library target C. Should target A be able to use classes
defined in target C?
[](/images/transitive-dependencies.png)
**Figure 1**. Transitive dependencies
As far as the underlying tools are concerned, there’s no problem with this; both
B and C will be linked into target A when it is built, so any symbols defined in
C are known to A. Bazel allowed this for many years, but as Google grew, we
began to see problems. Suppose that B was refactored such that it no longer
needed to depend on C. If B’s dependency on C was then removed, A and any other
target that used C via a dependency on B would break. Effectively, a target’s
dependencies became part of its public contract and could never be safely
changed. This meant that dependencies accumulated over time and builds at Google
started to slow down.
Google eventually solved this issue by introducing a “strict transitive
dependency mode” in Bazel. In this mode, Bazel detects whether a target tries to
reference a symbol without depending on it directly and, if so, fails with an
error and a shell command that can be used to automatically insert the
dependency. Rolling this change out across Google’s entire codebase and
refactoring every one of our millions of build targets to explicitly list their
dependencies was a multiyear effort, but it was well worth it. Our builds are
now much faster given that targets have fewer unnecessary dependencies, and
engineers are empowered to remove dependencies they don’t need without worrying
about breaking targets that depend on them.
As usual, enforcing strict transitive dependencies involved a trade-off. It made
build files more verbose, as frequently used libraries now need to be listed
explicitly in many places rather than pulled in incidentally, and engineers
needed to spend more effort adding dependencies to `BUILD` files. We’ve since
developed tools that reduce this toil by automatically detecting many missing
dependencies and adding them to a `BUILD` files without any developer
intervention. But even without such tools, we’ve found the trade-off to be well
worth it as the codebase scales: explicitly adding a dependency to `BUILD` file
is a one-time cost, but dealing with implicit transitive dependencies can cause
ongoing problems as long as the build target exists. Bazel [enforces strict transitive dependencies](https://blog.bazel.build/2017/06/28/sjd-unused_deps.html)
on Java code by default.
### External dependencies
If a dependency isn’t internal, it must be external. External dependencies are
those on artifacts that are built and stored outside of the build system. The
dependency is imported directly from an artifact repository (typically accessed
over the internet) and used as-is rather than being built from source. One of
the biggest differences between external and internal dependencies is that
external dependencies have versions, and those versions exist independently of
the project’s source code.
### Automatic versus manual dependency management
Build systems can allow the versions of external dependencies to be managed
either manually or automatically. When managed manually, the buildfile
explicitly lists the version it wants to download from the artifact repository,
often using a [semantic version string](https://semver.org/) such
as `1.1.4`. When managed automatically, the source file specifies a range of
acceptable versions, and the build system always downloads the latest one. For
example, Gradle allows a dependency version to be declared as “1.+” to specify
that any minor or patch version of a dependency is acceptable so long as the
major version is 1.
Automatically managed dependencies can be convenient for small projects, but
they’re usually a recipe for disaster on projects of nontrivial size or that are
being worked on by more than one engineer. The problem with automatically
managed dependencies is that you have no control over when the version is
updated. There’s no way to guarantee that external parties won’t make breaking
updates (even when they claim to use semantic versioning), so a build that
worked one day might be broken the next with no easy way to detect what changed
or to roll it back to a working state. Even if the build doesn’t break, there
can be subtle behavior or performance changes that are impossible to track down.
In contrast, because manually managed dependencies require a change in source
control, they can be easily discovered and rolled back, and it’s possible to
check out an older version of the repository to build with older dependencies.
Bazel requires that versions of all dependencies be specified manually. At even
moderate scales, the overhead of manual version management is well worth it for
the stability it provides.
### The One-Version Rule
Different versions of a library are usually represented by different artifacts,
so in theory there’s no reason that different versions of the same external
dependency couldn’t both be declared in the build system under different names.
That way, each target could choose which version of the dependency it wanted to
use. This causes a lot of problems in practice, so Google enforces a strict
[One-Version Rule](https://opensource.google/docs/thirdparty/oneversion/) for
all third-party dependencies in our codebase.
The biggest problem with allowing multiple versions is the diamond dependency
issue. Suppose that target A depends on target B and on v1 of an external
library. If target B is later refactored to add a dependency on v2 of the same
external library, target A will break because it now depends implicitly on two
different versions of the same library. Effectively, it’s never safe to add a
new dependency from a target to any third-party library with multiple versions,
because any of that target’s users could already be depending on a different
version. Following the One-Version Rule makes this conflict impossible—if a
target adds a dependency on a third-party library, any existing dependencies
will already be on that same version, so they can happily coexist.
### Transitive external dependencies
Dealing with the transitive dependencies of an external dependency can be
particularly difficult. Many artifact repositories such as Maven Central, allow
artifacts to specify dependencies on particular versions of other artifacts in
the repository. Build tools like Maven or Gradle often recursively download each
transitive dependency by default, meaning that adding a single dependency in
your project could potentially cause dozens of artifacts to be downloaded in
total.
This is very convenient: when adding a dependency on a new library, it would be
a big pain to have to track down each of that library’s transitive dependencies
and add them all manually. But there’s also a huge downside: because different
libraries can depend on different versions of the same third-party library, this
strategy necessarily violates the One-Version Rule and leads to the diamond
dependency problem. If your target depends on two external libraries that use
different versions of the same dependency, there’s no telling which one you’ll
get. This also means that updating an external dependency could cause seemingly
unrelated failures throughout the codebase if the new version begins pulling in
conflicting versions of some of its dependencies.
Bazel did not use to automatically download transitive dependencies. It used to
employ a `WORKSPACE` file that required all transitive dependencies to be
listed, which led to a lot of pain when managing external dependencies. Bazel
has since added support for automatic transitive external dependency management
in the form of the `MODULE.bazel` file. See [external dependency overview](/external/overview) for more details.
Yet again, the choice here is one between convenience and scalability. Small
projects might prefer not having to worry about managing transitive dependencies
themselves and might be able to get away with using automatic transitive
dependencies. This strategy becomes less and less appealing as the organization
and codebase grows, and conflicts and unexpected results become more and more
frequent. At larger scales, the cost of manually managing dependencies is much
less than the cost of dealing with issues caused by automatic dependency
management.
### Caching build results using external dependencies
External dependencies are most often provided by third parties that release
stable versions of libraries, perhaps without providing source code. Some
organizations might also choose to make some of their own code available as
artifacts, allowing other pieces of code to depend on them as third-party rather
than internal dependencies. This can theoretically speed up builds if artifacts
are slow to build but quick to download.
However, this also introduces a lot of overhead and complexity: someone needs to
be responsible for building each of those artifacts and uploading them to the
artifact repository, and clients need to ensure that they stay up to date with
the latest version. Debugging also becomes much more difficult because different
parts of the system will have been built from different points in the
repository, and there is no longer a consistent view of the source tree.
A better way to solve the problem of artifacts taking a long time to build is to
use a build system that supports remote caching, as described earlier. Such a
build system saves the resulting artifacts from every build to a location that
is shared across engineers, so if a developer depends on an artifact that was
recently built by someone else, the build system automatically downloads it
instead of building it. This provides all of the performance benefits of
depending directly on artifacts while still ensuring that builds are as
consistent as if they were always built from the same source. This is the
strategy used internally by Google, and Bazel can be configured to use a remote
cache.
### Security and reliability of external dependencies
Depending on artifacts from third-party sources is inherently risky. There’s an
availability risk if the third-party source (such as an artifact repository)
goes down, because your entire build might grind to a halt if it’s unable to
download an external dependency. There’s also a security risk: if the
third-party system is compromised by an attacker, the attacker could replace the
referenced artifact with one of their own design, allowing them to inject
arbitrary code into your build. Both problems can be mitigated by mirroring any
artifacts you depend on onto servers you control and blocking your build system
from accessing third-party artifact repositories like Maven Central. The
trade-off is that these mirrors take effort and resources to maintain, so the
choice of whether to use them often depends on the scale of the project. The
security issue can also be completely prevented with little overhead by
requiring the hash of each third-party artifact to be specified in the source
repository, causing the build to fail if the artifact is tampered with. Another
alternative that completely sidesteps the issue is to vendor your project’s
dependencies. When a project vendors its dependencies, it checks them into
source control alongside the project’s source code, either as source or as
binaries. This effectively means that all of the project’s external dependencies
are converted to internal dependencies. Google uses this approach internally,
checking every third-party library referenced throughout Google into a
`third_party` directory at the root of Google’s source tree. However, this works
at Google only because Google’s source control system is custom built to handle
an extremely large monorepo, so vendoring might not be an option for all
organizations.
# Distributed Builds
Source: https://bazel.build/basics/distributed-builds
When you have a large codebase, chains of dependencies can become very deep.
Even simple binaries can often depend on tens of thousands of build targets. At
this scale, it’s simply impossible to complete a build in a reasonable amount
of time on a single machine: no build system can get around the fundamental
laws of physics imposed on a machine’s hardware. The only way to make this work
is with a build system that supports distributed builds wherein the units of
work being done by the system are spread across an arbitrary and scalable
number of machines. Assuming we’ve broken the system’s work into small enough
units (more on this later), this would allow us to complete any build of any
size as quickly as we’re willing to pay for. This scalability is the holy grail
we’ve been working toward by defining an artifact-based build system.
## Remote caching
The simplest type of distributed build is one that only leverages *remote
caching*, which is shown in Figure 1.
[](/images/distributed-build-remote-cache.png)
**Figure 1**. A distributed build showing remote caching
Every system that performs builds, including both developer workstations and
continuous integration systems, shares a reference to a common remote cache
service. This service might be a fast and local short-term storage system like
Redis or a cloud service like Google Cloud Storage. Whenever a user needs to
build an artifact, whether directly or as a dependency, the system first checks
with the remote cache to see if that artifact already exists there. If so, it
can download the artifact instead of building it. If not, the system builds the
artifact itself and uploads the result back to the cache. This means that
low-level dependencies that don’t change very often can be built once and shared
across users rather than having to be rebuilt by each user. At Google, many
artifacts are served from a cache rather than built from scratch, vastly
reducing the cost of running our build system.
For a remote caching system to work, the build system must guarantee that builds
are completely reproducible. That is, for any build target, it must be possible
to determine the set of inputs to that target such that the same set of inputs
will produce exactly the same output on any machine. This is the only way to
ensure that the results of downloading an artifact are the same as the results
of building it oneself. Note that this requires that each artifact in the cache
be keyed on both its target and a hash of its inputs—that way, different
engineers could make different modifications to the same target at the same
time, and the remote cache would store all of the resulting artifacts and serve
them appropriately without conflict.
Of course, for there to be any benefit from a remote cache, downloading an
artifact needs to be faster than building it. This is not always the case,
especially if the cache server is far from the machine doing the build. Google’s
network and build system is carefully tuned to be able to quickly share build
results.
## Remote execution
Remote caching isn’t a true distributed build. If the cache is lost or if you
make a low-level change that requires everything to be rebuilt, you still need
to perform the entire build locally on your machine. The true goal is to support
remote execution, in which the actual work of doing the build can be spread
across any number of workers. Figure 2 depicts a remote execution system.
[](/images/remote-execution-system.png)
**Figure 2**. A remote execution system
The build tool running on each user’s machine (where users are either human
engineers or automated build systems) sends requests to a central build master.
The build master breaks the requests into their component actions and schedules
the execution of those actions over a scalable pool of workers. Each worker
performs the actions asked of it with the inputs specified by the user and
writes out the resulting artifacts. These artifacts are shared across the other
machines executing actions that require them until the final output can be
produced and sent to the user.
The trickiest part of implementing such a system is managing the communication
between the workers, the master, and the user’s local machine. Workers might
depend on intermediate artifacts produced by other workers, and the final output
needs to be sent back to the user’s local machine. To do this, we can build on
top of the distributed cache described previously by having each worker write
its results to and read its dependencies from the cache. The master blocks
workers from proceeding until everything they depend on has finished, in which
case they’ll be able to read their inputs from the cache. The final product is
also cached, allowing the local machine to download it. Note that we also need a
separate means of exporting the local changes in the user’s source tree so that
workers can apply those changes before building.
For this to work, all of the parts of the artifact-based build systems described
earlier need to come together. Build environments must be completely
self-describing so that we can spin up workers without human intervention. Build
processes themselves must be completely self-contained because each step might
be executed on a different machine. Outputs must be completely deterministic so
that each worker can trust the results it receives from other workers. Such
guarantees are extremely difficult for a task-based system to provide, which
makes it nigh-impossible to build a reliable remote execution system on top of
one.
## Distributed builds at Google
Since 2008, Google has been using a distributed build system that employs both
remote caching and remote execution, which is illustrated in Figure 3.
[](/images/high-level-build-system.png)
**Figure 3**. Google’s distributed build system
Google’s remote cache is called ObjFS. It consists of a backend that stores
build outputs in Bigtables distributed throughout our fleet of production
machines and a frontend FUSE daemon named objfsd that runs on each developer’s
machine. The FUSE daemon allows engineers to browse build outputs as if they
were normal files stored on the workstation, but with the file content
downloaded on-demand only for the few files that are directly requested by the
user. Serving file contents on-demand greatly reduces both network and disk
usage, and the system is able to build twice as fast compared to when we stored
all build output on the developer’s local disk.
Google’s remote execution system is called Forge. A Forge client in Blaze
(Bazel's internal equivalent) called
the Distributor sends requests for each action to a job running in our
datacenters called the Scheduler. The Scheduler maintains a cache of action
results, allowing it to return a response immediately if the action has already
been created by any other user of the system. If not, it places the action into
a queue. A large pool of Executor jobs continually read actions from this queue,
execute them, and store the results directly in the ObjFS Bigtables. These
results are available to the executors for future actions, or to be downloaded
by the end user via objfsd.
The end result is a system that scales to efficiently support all builds
performed at Google. And the scale of Google’s builds is truly massive: Google
runs millions of builds executing millions of test cases and producing petabytes
of build outputs from billions of lines of source code every day. Not only does
such a system let our engineers build complex codebases quickly, it also allows
us to implement a huge number of automated tools and systems that rely on our
build.
# Hermeticity
Source: https://bazel.build/basics/hermeticity
This page covers hermeticity, the benefits of using hermetic builds, and
strategies for identifying non-hermetic behavior in your builds.
## Overview
When given the same input source code and product configuration, a hermetic
build system always returns the same output by isolating the build from changes
to the host system.
In order to isolate the build, hermetic builds are insensitive to libraries and
other software installed on the local or remote host machine. They depend on
specific versions of build tools, such as compilers, and dependencies, such as
libraries. This makes the build process self-contained as it doesn't rely on
services external to the build environment.
The two important aspects of hermeticity are:
* **Isolation**: Hermetic build systems treat tools as source code. They
download copies of tools and manage their storage and use inside managed file
trees. This creates isolation between the host machine and local user,
including installed versions of languages.
* **Source identity**: Hermetic build systems try to ensure the sameness of
inputs. Code repositories, such as Git, identify sets of code mutations with a
unique hash code. Hermetic build systems use this hash to identify changes to
the build's input.
## Benefits
The major benefits of hermetic builds are:
* **Speed**: The output of an action can be cached, and the action need not be
run again unless inputs change.
* **Parallel execution**: For given input and output, the build system can
construct a graph of all actions to calculate efficient and parallel
execution. The build system loads the rules and calculates an action graph
and hash inputs to look up in the cache.
* **Multiple builds**: You can build multiple hermetic builds on the same
machine, each build using different tools and versions.
* **Reproducibility**: Hermetic builds are good for troubleshooting because you
know the exact conditions that produced the build.
## Identifying non-hermeticity
If you are preparing to switch to Bazel, migration is easier if you improve
your existing builds' hermeticity in advance. Some common sources of
non-hermeticity in builds are:
* Arbitrary processing in `.mk` files
* Actions or tooling that create files non-deterministically, usually involving
build IDs or timestamps
* System binaries that differ across hosts (such as `/usr/bin` binaries, absolute
paths, system C++ compilers for native C++ rules autoconfiguration)
* Writing to the source tree during the build. This prevents the same source
tree from being used for another target. The first build writes to the source
tree, fixing the source tree for target A. Then trying to build target B may
fail.
## Troubleshooting non-hermetic builds
Starting with local execution, issues that affect local cache hits reveal
non-hermetic actions.
* Ensure null sequential builds: If you run `make` and get a successful build,
running the build again should not rebuild any targets. If you run each build
step twice or on different systems, compare a hash of the file contents and
get results that differ, the build is not reproducible.
* Run steps to
[debug local cache hits](/remote/cache-remote#troubleshooting-cache-hits)
from a variety of potential client machines to ensure that you catch any
cases of client environment leaking into the actions.
* Execute a build within a docker container that contains nothing but the
checked-out source tree and explicit list of host tools. Build breakages and
error messages will catch implicit system dependencies.
* Discover and fix hermeticity problems using
[remote execution rules](/remote/rules#overview).
* Enable strict [sandboxing](/docs/sandboxing)
at the per-action level, since actions in a build can be stateful and affect
the build or the output.
* [Workspace rules](/remote/workspace)
allow developers to add dependencies to external workspaces, but they are
rich enough to allow arbitrary processing to happen in the process. You can
get a log of some potentially non-hermetic actions in Bazel workspace rules by
adding the flag
`--experimental_workspace_rules_log_file=PATH` to
your Bazel command.
Note: Make your build fully hermetic when mixing remote and local execution,
using Bazel’s “dynamic strategy” functionality. Running Bazel inside the remote
Docker container will enable the build to execute the same in both environments.
## Hermeticity with Bazel
For more information about how other projects have had success using hermetic
builds with Bazel, see these BazelCon talks:
* [Building Real-time Systems with Bazel](https://www.youtube.com/watch?v=t_3bckhV_YI) (SpaceX)
* [Bazel Remote Execution and Remote Caching](https://www.youtube.com/watch?v=_bPyEbAyC0s) (Uber and TwoSigma)
* [Faster Builds With Remote Execution and Caching](https://www.youtube.com/watch?v=MyuJRUwT5LI)
* [Fusing Bazel: Faster Incremental Builds](https://www.youtube.com/watch?v=rQd9Zd1ONOw)
* [Remote Execution vs Local Execution](https://www.youtube.com/watch?v=C8wHmIln--g)
* [Improving the Usability of Remote Caching](https://www.youtube.com/watch?v=u5m7V3ZRHLA) (IBM)
* [Building Self Driving Cars with Bazel](https://www.youtube.com/watch?v=Gh4SJuYUoQI\&list=PLxNYxgaZ8Rsf-7g43Z8LyXct9ax6egdSj\&index=4\&t=0s) (BMW)
* [Building Self Driving Cars with Bazel + Q\&A](https://www.youtube.com/watch?v=fjfFe98LTm8\&list=PLxNYxgaZ8Rsf-7g43Z8LyXct9ax6egdSj\&index=29) (GM Cruise)
# Build Basics
Source: https://bazel.build/basics/index
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](https://abseil.io/resources/swe-book/html/ch18.html).
Thank you to the original author, Erik Kuefler, for allowing its reuse and
modification here!
* **[Why a Build System?](/basics/build-systems)**
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.
* **[Task-Based Build Systems](/basics/task-based-builds)**
This page discusses task-based build systems (such as Make, Maven, and
Gradle) and some of their challenges.
* **[Artifact-Based Build Systems](/basics/artifact-based-builds)**
This page discusses artifact-based build systems in response to the pain
points of task-based build systems.
* **[Distributed Builds](/basics/distributed-builds)**
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!)
* **[Dependency Management](/basics/dependencies)**
This page covers some complications of dependencies at a large scale and
strategies to counteract those complications.
# Task-Based Build Systems
Source: https://bazel.build/basics/task-based-builds
This page covers task-based build systems, how they work and some of the
complications that can occur with task-based systems. After shell scripts,
task-based build systems are the next logical evolution of building.
## Understanding task-based build systems
In a task-based build system, the fundamental unit of work is the task. Each
task is a script that can execute any sort of logic, and tasks specify other
tasks as dependencies that must run before them. Most major build systems in use
today, such as Ant, Maven, Gradle, Grunt, and Rake, are task based. Instead of
shell scripts, most modern build systems require engineers to create build files
that describe how to perform the build.
Take this example from the
[Ant manual](https://ant.apache.org/manual/using.html):
```xml theme={null}
simple example build file
```
The buildfile is written in XML and defines some simple metadata about the build
along with a list of tasks (the `` tags in the XML). (Ant uses the word
*target* to represent a *task*, and it uses the word *task* to refer to
*commands*.) Each task executes a list of possible commands defined by Ant,
which here include creating and deleting directories, running `javac`, and
creating a JAR file. This set of commands can be extended by user-provided
plug-ins to cover any sort of logic. Each task can also define the tasks it
depends on via the depends attribute. These dependencies form an acyclic graph,
as seen in Figure 1.
[](/images/task-dependencies.png)
Figure 1. An acyclic graph showing dependencies
Users perform builds by providing tasks to Ant’s command-line tool. For example,
when a user types `ant dist`, Ant takes the following steps:
1. Loads a file named `build.xml` in the current directory and parses it to
create the graph structure shown in Figure 1.
2. Looks for the task named `dist` that was provided on the command line and
discovers that it has a dependency on the task named `compile`.
3. Looks for the task named `compile` and discovers that it has a dependency on
the task named `init`.
4. Looks for the task named `init` and discovers that it has no dependencies.
5. Executes the commands defined in the `init` task.
6. Executes the commands defined in the `compile` task given that all of that
task’s dependencies have been run.
7. Executes the commands defined in the `dist` task given that all of that
task’s dependencies have been run.
In the end, the code executed by Ant when running the `dist` task is equivalent
to the following shell script:
```posix-terminal theme={null}
./createTimestamp.sh
mkdir build/
javac src/* -d build/
mkdir -p dist/lib/
jar cf dist/lib/MyProject-$(date --iso-8601).jar build/*
```
When the syntax is stripped away, the buildfile and the build script actually
aren’t too different. But we’ve already gained a lot by doing this. We can
create new buildfiles in other directories and link them together. We can easily
add new tasks that depend on existing tasks in arbitrary and complex ways. We
need only pass the name of a single task to the `ant` command-line tool, and it
determines everything that needs to be run.
Ant is an old piece of software, originally released in 2000. Other tools like
Maven and Gradle have improved on Ant in the intervening years and essentially
replaced it by adding features like automatic management of external
dependencies and a cleaner syntax without any XML. But the nature of these newer
systems remains the same: they allow engineers to write build scripts in a
principled and modular way as tasks and provide tools for executing those tasks
and managing dependencies among them.
## The dark side of task-based build systems
Because these tools essentially let engineers define any script as a task, they
are extremely powerful, allowing you to do pretty much anything you can imagine
with them. But that power comes with drawbacks, and task-based build systems can
become difficult to work with as their build scripts grow more complex. The
problem with such systems is that they actually end up giving *too much power to
engineers and not enough power to the system*. Because the system has no idea
what the scripts are doing, performance suffers, as it must be very conservative
in how it schedules and executes build steps. And there’s no way for the system
to confirm that each script is doing what it should, so scripts tend to grow in
complexity and end up being another thing that needs debugging.
### Difficulty of parallelizing build steps
Modern development workstations are quite powerful, with multiple cores that are
capable of executing several build steps in parallel. But task-based systems are
often unable to parallelize task execution even when it seems like they should
be able to. Suppose that task A depends on tasks B and C. Because tasks B and C
have no dependency on each other, is it safe to run them at the same time so
that the system can more quickly get to task A? Maybe, if they don’t touch any
of the same resources. But maybe not—perhaps both use the same file to track
their statuses and running them at the same time causes a conflict. There’s no
way in general for the system to know, so either it has to risk these conflicts
(leading to rare but very difficult-to-debug build problems), or it has to
restrict the entire build to running on a single thread in a single process.
This can be a huge waste of a powerful developer machine, and it completely
rules out the possibility of distributing the build across multiple machines.
### Difficulty performing incremental builds
A good build system allows engineers to perform reliable incremental builds such
that a small change doesn’t require the entire codebase to be rebuilt from
scratch. This is especially important if the build system is slow and unable to
parallelize build steps for the aforementioned reasons. But unfortunately,
task-based build systems struggle here, too. Because tasks can do anything,
there’s no way in general to check whether they’ve already been done. Many tasks
simply take a set of source files and run a compiler to create a set of
binaries; thus, they don’t need to be rerun if the underlying source files
haven’t changed. But without additional information, the system can’t say this
for sure—maybe the task downloads a file that could have changed, or maybe it
writes a timestamp that could be different on each run. To guarantee
correctness, the system typically must rerun every task during each build. Some
build systems try to enable incremental builds by letting engineers specify the
conditions under which a task needs to be rerun. Sometimes this is feasible, but
often it’s a much trickier problem than it appears. For example, in languages
like C++ that allow files to be included directly by other files, it’s
impossible to determine the entire set of files that must be watched for changes
without parsing the input sources. Engineers often end up taking shortcuts, and
these shortcuts can lead to rare and frustrating problems where a task result is
reused even when it shouldn’t be. When this happens frequently, engineers get
into the habit of running clean before every build to get a fresh state,
completely defeating the purpose of having an incremental build in the first
place. Figuring out when a task needs to be rerun is surprisingly subtle, and is
a job better handled by machines than humans.
### Difficulty maintaining and debugging scripts
Finally, the build scripts imposed by task-based build systems are often just
difficult to work with. Though they often receive less scrutiny, build scripts
are code just like the system being built, and are easy places for bugs to hide.
Here are some examples of bugs that are very common when working with a
task-based build system:
* Task A depends on task B to produce a particular file as output. The owner
of task B doesn’t realize that other tasks rely on it, so they change it to
produce output in a different location. This can’t be detected until someone
tries to run task A and finds that it fails.
* Task A depends on task B, which depends on task C, which is producing a
particular file as output that’s needed by task A. The owner of task B
decides that it doesn’t need to depend on task C any more, which causes task
A to fail even though task B doesn’t care about task C at all!
* The developer of a new task accidentally makes an assumption about the
machine running the task, such as the location of a tool or the value of
particular environment variables. The task works on their machine, but fails
whenever another developer tries it.
* A task contains a nondeterministic component, such as downloading a file
from the internet or adding a timestamp to a build. Now, people get
potentially different results each time they run the build, meaning that
engineers won’t always be able to reproduce and fix one another’s failures
or failures that occur on an automated build system.
* Tasks with multiple dependencies can create race conditions. If task A
depends on both task B and task C, and task B and C both modify the same
file, task A gets a different result depending on which one of tasks B and C
finishes first.
There’s no general-purpose way to solve these performance, correctness, or
maintainability problems within the task-based framework laid out here. So long
as engineers can write arbitrary code that runs during the build, the system
can’t have enough information to always be able to run builds quickly and
correctly. To solve the problem, we need to take some power out of the hands of
engineers and put it back in the hands of the system and reconceptualize the
role of the system not as running tasks, but as producing artifacts.
This approach led to the creation of artifact-based build systems, like Blaze
and Bazel.
# Sharing Variables
Source: https://bazel.build/build/share-variables
`BUILD` files are intended to be simple and declarative. They will typically
consist of a series of target declarations. As your code base and your `BUILD`
files get larger, you will probably notice some duplication, such as:
```python theme={null}
cc_library(
name = "foo",
copts = ["-DVERSION=5"],
srcs = ["foo.cc"],
)
cc_library(
name = "bar",
copts = ["-DVERSION=5"],
srcs = ["bar.cc"],
deps = [":foo"],
)
```
Code duplication in `BUILD` files is usually fine. This can make the file more
readable: each declaration can be read and understood without any context. This
is important, not only for humans, but also for external tools. For example, a
tool might be able to read and update `BUILD` files to add missing dependencies.
Code refactoring and code reuse might prevent this kind of automated
modification.
If it is useful to share values (for example, if values must be kept in sync),
you can introduce a variable:
```python theme={null}
COPTS = ["-DVERSION=5"]
cc_library(
name = "foo",
copts = COPTS,
srcs = ["foo.cc"],
)
cc_library(
name = "bar",
copts = COPTS,
srcs = ["bar.cc"],
deps = [":foo"],
)
```
Multiple declarations now use the value `COPTS`. By convention, use uppercase
letters to name global constants.
## Sharing variables across multiple BUILD files
If you need to share a value across multiple `BUILD` files, you have to put it
in a `.bzl` file. `.bzl` files contain definitions (variables and functions)
that can be used in `BUILD` files.
In `path/to/variables.bzl`, write:
```python theme={null}
COPTS = ["-DVERSION=5"]
```
Then, you can update your `BUILD` files to access the variable:
```python theme={null}
load("//path/to:variables.bzl", "COPTS")
cc_library(
name = "foo",
copts = COPTS,
srcs = ["foo.cc"],
)
cc_library(
name = "bar",
copts = COPTS,
srcs = ["bar.cc"],
deps = [":foo"],
)
```
# BUILD Style Guide
Source: https://bazel.build/build/style-guide
## Prefer DAMP BUILD files over DRY
The DRY principle — "Don't Repeat Yourself" — encourages uniqueness by
introducing abstractions such as variables and functions to avoid redundancy in
code.
In contrast, the DAMP principle — "Descriptive and Meaningful Phrases" —
encourages readability over uniqueness to make files easier to understand and
maintain.
`BUILD` files aren't code, they are configurations. They aren't tested like
code, but do need to be maintained by people and tools. That makes DAMP better
for them than DRY.
## BUILD.bazel file formatting
`BUILD` file formatting follows the same approach as Go, where a standardized
tool takes care of most formatting issues.
[Buildifier](https://github.com/bazelbuild/buildifier) is a tool that parses and
emits the source code in a standard style. Every `BUILD` file is therefore
formatted in the same automated way, which makes formatting a non-issue during
code reviews. It also makes it easier for tools to understand, edit, and
generate `BUILD` files.
`BUILD` file formatting must match the output of `buildifier`.
### Formatting example
```python theme={null}
# Test code implementing the Foo controller.
package(default_testonly = True)
py_test(
name = "foo_test",
srcs = glob(["*.py"]),
data = [
"//data/production/foo:startfoo",
"//foo",
"//third_party/java/jdk:jdk-k8",
],
flaky = True,
deps = [
":check_bar_lib",
":foo_data_check",
":pick_foo_port",
"//pyglib",
"//testing/pybase",
],
)
```
## File structure
**Recommendation**: Use the following order (every element is optional):
* Package description (a comment)
* All `load()` statements
* The `package()` function.
* Calls to rules and macros
Buildifier makes a distinction between a standalone comment and a comment
attached to an element. If a comment is not attached to a specific element, use
an empty line after it. The distinction is important when doing automated
changes (for example, to keep or remove a comment when deleting a rule).
```python theme={null}
# Standalone comment (such as to make a section in a file)
# Comment for the cc_library below
cc_library(name = "cc")
```
## References to targets in the current package
Files should be referred to by their paths relative to the package directory
(without ever using up-references, such as `..`). Generated files should be
prefixed with "`:`" to indicate that they are not sources. Source files
should not be prefixed with `:`. Rules should be prefixed with `:`. For
example, assuming `x.cc` is a source file:
```python theme={null}
cc_library(
name = "lib",
srcs = ["x.cc"],
hdrs = [":gen_header"],
)
genrule(
name = "gen_header",
srcs = [],
outs = ["x.h"],
cmd = "echo 'int x();' > $@",
)
```
## Target naming
Target names should be descriptive. If a target contains one source file,
the target should generally have a name derived from that source (for example, a
`cc_library` for `chat.cc` could be named `chat`, or a `java_library` for
`DirectMessage.java` could be named `direct_message`).
The eponymous target for a package (the target with the same name as the
containing directory) should provide the functionality described by the
directory name. If there is no such target, do not create an eponymous
target.
Prefer using the short name when referring to an eponymous target (`//x`
instead of `//x:x`). If you are in the same package, prefer the local
reference (`:x` instead of `//x`).
Avoid using "reserved" target names which have special meaning. This includes
`all`, `__pkg__`, and `__subpackages__`, these names have special
semantics and can cause confusion and unexpected behaviors when they are used.
In the absence of a prevailing team convention these are some non-binding
recommendations that are broadly used at Google:
* In general, use ["snake\_case"](https://en.wikipedia.org/wiki/Snake_case)
* For a `java_library` with one `src` this means using a name that is not
the same as the filename without the extension
* For Java `*_binary` and `*_test` rules, use
["Upper CamelCase"](https://en.wikipedia.org/wiki/Camel_case).
This allows for the target name to match one of the `src`s. For
`java_test`, this makes it possible for the `test_class` attribute to be
inferred from the name of the target.
* If there are multiple variants of a particular target then add a suffix to
disambiguate (such as. `:foo_dev`, `:foo_prod` or `:bar_x86`, `:bar_x64`)
* Suffix `_test` targets with `_test`, `_unittest`, `Test`, or `Tests`
* Avoid meaningless suffixes like `_lib` or `_library` (unless necessary to
avoid conflicts between a `_library` target and its corresponding `_binary`)
* For proto related targets:
* `proto_library` targets should have names ending in `_proto`
* Languages specific `*_proto_library` rules should match the underlying
proto but replace `_proto` with a language specific suffix such as:
* **`cc_proto_library`**: `_cc_proto`
* **`java_proto_library`**: `_java_proto`
* **`java_lite_proto_library`**: `_java_proto_lite`
## Visibility
Visibility should be scoped as tightly as possible, while still allowing access
by tests and reverse dependencies. Use `__pkg__` and `__subpackages__` as
appropriate.
Avoid setting package `default_visibility` to `//visibility:public`.
`//visibility:public` should be individually set only for targets in the
project's public API. These could be libraries that are designed to be depended
on by external projects or binaries that could be used by an external project's
build process.
## Dependencies
Dependencies should be restricted to direct dependencies (dependencies
needed by the sources listed in the rule). Do not list transitive dependencies.
Package-local dependencies should be listed first and referred to in a way
compatible with the
[References to targets in the current package](#targets-current-package)
section above (not by their absolute package name).
Prefer to list dependencies directly, as a single list. Putting the "common"
dependencies of several targets into a variable reduces maintainability, makes
it impossible for tools to change the dependencies of a target, and can lead to
unused dependencies.
## Globs
Indicate "no targets" with `[]`. Do not use a glob that matches nothing: it
is more error-prone and less obvious than an empty list.
### Recursive
Do not use recursive globs to match source files (for example,
`glob(["**/*.java"])`).
Recursive globs make `BUILD` files difficult to reason about because they skip
subdirectories containing `BUILD` files.
Recursive globs are generally less efficient than having a `BUILD` file per
directory with a dependency graph defined between them as this enables better
remote caching and parallelism.
It is good practice to author a `BUILD` file in each directory and define a
dependency graph between them.
### Non-recursive
Non-recursive globs are generally acceptable.
## Avoid list comprehensions
Avoid using list comprehensions at the top level of a `BUILD.bazel` file.
Automate repetitive calls by creating each named target with a separate
top-level rule or macro call. Give each a short `name` parameter for clarity.
List comprehension reduces the following:
* Maintainability. It's difficult or impossible for human maintainers and
large scale automated changes to update list comprehensions correctly.
* Discoverability. Since the pattern doesn't have `name` parameters,
it's hard to find the rule by name.
A common application of the list comprehension pattern is to generate tests. For
example:
```build {.bad} theme={null}
[[java_test(
name = "test_%s_%s" % (backend, count),
srcs = [ ... ],
deps = [ ... ],
...
) for backend in [
"fake",
"mock",
]] for count in [
1,
10,
]]
```
We recommend using simpler alternatives. For example, define a macro that
generates one test and invoke it for each top-level `name`:
```build theme={null}
my_java_test(name = "test_fake_1",
...)
my_java_test(name = "test_fake_10",
...)
...
```
## Don't use deps variables
Don't use list variables to encapsulate common dependencies:
```build {.bad} theme={null}
COMMON_DEPS = [
"//d:e",
"//x/y:z",
]
cc_library(name = "a",
srcs = ["a.cc"],
deps = COMMON_DEPS + [ ... ],
)
cc_library(name = "b",
srcs = ["b.cc"],
deps = COMMON_DEPS + [ ... ],
)
```
Similarly, don't use a library target with
[`exports`](/reference/be/java#java_library.exports) to group dependencies.
Instead, list the dependencies separately for each target:
```build {.good} theme={null}
cc_library(name = "a",
srcs = ["a.cc"],
deps = [
"//a:b",
"//x/y:z",
...
],
)
cc_library(name = "b",
srcs = ["b.cc"],
deps = [
"//a:b",
"//x/y:z",
...
],
)
```
Let [Gazelle](https://github.com/bazel-contrib/bazel-gazelle) and other tools
maintain them. There will be repetition, but you won't have to think about how
to manage the dependencies.
## Prefer literal strings
Although Starlark provides string operators for concatenation (`+`) and
formatting (`%`), use them with caution. It is tempting to factor out common
string parts to make expressions more concise or break long lines. However,
* It is harder to read broken-up string values at a glance.
* Automated tools such as
[buildozer][buildozer] and Code Search have trouble finding values and
updating them correctly when the values broken up.
* In `BUILD` files, readability is more important than avoiding repetition
(see [DAMP versus DRY](#prefer-damp-build-files-over-dry)).
* This Style Guide
[warns against splitting label-valued strings](#other-conventions)
and
[explicitly permits long lines](#differences-python-style-guide).
* Buildifier automatically fuses concatenated strings when it detects that
they are labels.
Therefore, prefer explicit, literal strings over concatenated or formatted
strings, especially in label-type attributes such as `name` and `deps`. For
example, this `BUILD` fragment:
```build {.bad} theme={null}
NAME = "foo"
PACKAGE = "//a/b"
proto_library(
name = "%s_proto" % NAME,
deps = [PACKAGE + ":other_proto"],
alt_dep = "//surprisingly/long/chain/of/package/names:" +
"extravagantly_long_target_name",
)
```
would be better rewritten as
```build {.good} theme={null}
proto_library(
name = "foo_proto",
deps = ["//a/b:other_proto"],
alt_dep = "//surprisingly/long/chain/of/package/names:extravagantly_long_target_name",
)
```
[buildozer]: https://github.com/bazelbuild/buildtools/blob/main/buildozer/README.md
## Limit the symbols exported by each `.bzl` file
Minimize the number of symbols (rules, macros, constants, functions) exported by
each public `.bzl` (Starlark) file. We recommend that a file should export
multiple symbols only if they are certain to be used together. Otherwise, split
it into multiple `.bzl` files, each with its own [bzl\_library][bzl_library].
Excessive symbols can cause `.bzl` files to grow into broad "libraries" of
symbols, causing changes to single files to force Bazel to rebuild many targets.
[bzl_library]: https://github.com/bazelbuild/bazel-skylib/blob/main/README.md#bzl_library
## Other conventions
* Use uppercase and underscores to declare constants (such as `GLOBAL_CONSTANT`),
use lowercase and underscores to declare variables (such as `my_variable`).
* Labels should never be split, even if they are longer than 79 characters.
Labels should be string literals whenever possible. *Rationale*: It makes
find and replace easy. It also improves readability.
* The value of the name attribute should be a literal constant string (except
in macros). *Rationale*: External tools use the name attribute to refer a
rule. They need to find rules without having to interpret code.
* When setting boolean-type attributes, use boolean values, not integer values.
For legacy reasons, rules still convert integers to booleans as needed,
but this is discouraged. *Rationale*: `flaky = 1` could be misread as saying
"deflake this target by rerunning it once". `flaky = True` unambiguously says
"this test is flaky".
## Differences with Python style guide
Although compatibility with
[Python style guide](https://www.python.org/dev/peps/pep-0008/)
is a goal, there are a few differences:
* No strict line length limit. Long comments and long strings are often split
to 79 columns, but it is not required. It should not be enforced in code
reviews or presubmit scripts. *Rationale*: Labels can be long and exceed this
limit. It is common for `BUILD` files to be generated or edited by tools,
which does not go well with a line length limit.
* Implicit string concatenation is not supported. Use the `+` operator.
*Rationale*: `BUILD` files contain many string lists. It is easy to forget a
comma, which leads to a complete different result. This has created many bugs
in the past. [See also this discussion.](https://lwn.net/Articles/551438/)
* Use spaces around the `=` sign for keywords arguments in rules. *Rationale*:
Named arguments are much more frequent than in Python and are always on a
separate line. Spaces improve readability. This convention has been around
for a long time, and it is not worth modifying all existing `BUILD` files.
* By default, use double quotation marks for strings. *Rationale*: This is not
specified in the Python style guide, but it recommends consistency. So we
decided to use only double-quoted strings. Many languages use double-quotes
for string literals.
* Use a single blank line between two top-level definitions. *Rationale*: The
structure of a `BUILD` file is not like a typical Python file. It has only
top-level statements. Using a single-blank line makes `BUILD` files shorter.
# Recommended Rules
Source: https://bazel.build/community/recommended-rules
In the documentation, we provide a list of
[recommended rules](/rules).
This is a set of high quality rules, which will provide a good experience to our
users. We make a distinction between the supported rules, and the hundreds of
rules you can find on the Internet.
## Nomination
If a ruleset meets the requirements below, a rule maintainer can nominate it
to be part of the *recommended rules* by filing a
[GitHub issue](https://github.com/bazelbuild/bazel/).
After a review by the [Bazel core team](/contribute/policy), it
will be recommended on the Bazel website.
## Requirements for the rule maintainers
* The ruleset provides an important feature, useful to a large number of Bazel
users (for example, support for a widely popular language).
* The ruleset is well maintained. There must be at least two active maintainers.
* The ruleset is well documented, with examples, and easy to use.
* The ruleset follows the best practices and is performant (see
[the performance guide](/rules/performance)).
* The ruleset has sufficient test coverage.
* The ruleset is tested on
[BuildKite](https://github.com/bazelbuild/continuous-integration/blob/master/buildkite/README.md)
with the latest version of Bazel. Tests should always pass (when used as a
presubmit check).
* The ruleset is also tested with the upcoming incompatible changes. Breakages
should be fixed within two weeks. Migration issues should be reported to the
Bazel team quickly.
## Requirements for Bazel developers
* Recommended rules are frequently tested with Bazel at head (at least once a
day).
* No change in Bazel may break a recommended rule (with the default set of
flags). If it happens, the change should be fixed or rolled back.
## Demotion
If there is a concern that a particular ruleset is no longer meeting the
requirements, a [GitHub issue](https://github.com/bazelbuild/bazel/) should be
filed.
Rule maintainers will be contacted and need to respond in 2 weeks. Based on the
outcome, Bazel core team might make a decision to demote the rule set.
# BUILD files
Source: https://bazel.build/concepts/build-files
The previous sections described packages, targets and labels, and the
build dependency graph abstractly. This section describes the concrete syntax
used to define a package.
By definition, every package contains a `BUILD` file, which is a short
program.
Note: The `BUILD` file can be named either `BUILD` or `BUILD.bazel`. If both
files exist, `BUILD.bazel` takes precedence over `BUILD`.
For simplicity's sake, the documentation refers to these files simply as `BUILD`
files.
`BUILD` files are evaluated using an imperative language,
[Starlark](https://github.com/bazelbuild/starlark/).
They are interpreted as a sequential list of statements.
In general, order does matter: variables must be defined before they are
used, for example. However, most `BUILD` files consist only of declarations of
build rules, and the relative order of these statements is immaterial; all
that matters is *which* rules were declared, and with what values, by the
time package evaluation completes.
When a build rule function, such as `cc_library`, is executed, it creates a
new target in the graph. This target can later be referred using a label.
In simple `BUILD` files, rule declarations can be re-ordered freely without
changing the behavior.
To encourage a clean separation between code and data, `BUILD` files cannot
contain function definitions, `for` statements or `if` statements (but list
comprehensions and `if` expressions are allowed). Functions can be declared in
`.bzl` files instead. Additionally, `*args` and `**kwargs` arguments are not
allowed in `BUILD` files; instead list all the arguments explicitly.
Crucially, programs in Starlark can't perform arbitrary I/O. This invariant
makes the interpretation of `BUILD` files hermetic — dependent only on a known
set of inputs, which is essential for ensuring that builds are reproducible.
For more details, see [Hermeticity](/basics/hermeticity).
Because `BUILD` files need to be updated whenever the dependencies of the
underlying code change, they are typically maintained by multiple people on a
team. `BUILD` file authors should comment liberally to document the role
of each build target, whether or not it is intended for public use, and to
document the role of the package itself.
## Loading an extension
Bazel extensions are files ending in `.bzl`. Use the `load` statement to import
a symbol from an extension.
```
load("//foo/bar:file.bzl", "some_library")
```
This code loads the file `foo/bar/file.bzl` and adds the `some_library` symbol
to the environment. This can be used to load new rules, functions, or constants
(for example, a string or a list). Multiple symbols can be imported by using
additional arguments to the call to `load`. Arguments must be string literals
(no variable) and `load` statements must appear at top-level — they cannot be
in a function body.
The first argument of `load` is a [label](/concepts/labels) identifying a
`.bzl` file. If it's a relative label, it is resolved with respect to the
package (not directory) containing the current `bzl` file. Relative labels in
`load` statements should use a leading `:`.
`load` also supports aliases, therefore, you can assign different names to the
imported symbols.
```
load("//foo/bar:file.bzl", library_alias = "some_library")
```
You can define multiple aliases within one `load` statement. Moreover, the
argument list can contain both aliases and regular symbol names. The following
example is perfectly legal (please note when to use quotation marks).
```
load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")
```
In a `.bzl` file, symbols starting with `_` are not exported and cannot be
loaded from another file.
You can use [load visibility](/concepts/visibility#load-visibility) to restrict
who may load a `.bzl` file.
## Types of build rules
The majority of build rules come in families, grouped together by
language. For example, `cc_binary`, `cc_library`
and `cc_test` are the build rules for C++ binaries,
libraries, and tests, respectively. Other languages use the same
naming scheme, with a different prefix, such as `java_*` for
Java. Some of these functions are documented in the
[Build Encyclopedia](/reference/be/overview), but it is possible
for anyone to create new rules.
* `*_binary` rules build executable programs in a given language. After a
build, the executable will reside in the build tool's binary
output tree at the corresponding name for the rule's label,
so `//my:program` would appear at (for example) `$(BINDIR)/my/program`.
In some languages, such rules also create a runfiles directory
containing all the files mentioned in a `data`
attribute belonging to the rule, or any rule in its transitive
closure of dependencies; this set of files is gathered together in
one place for ease of deployment to production.
* `*_test` rules are a specialization of a `*_binary` rule, used for automated
testing. Tests are simply programs that return zero on success.
Like binaries, tests also have runfiles trees, and the files
beneath it are the only files that a test may legitimately open
at runtime. For example, a program `cc_test(name='x',
data=['//foo:bar'])` may open and read `$TEST_SRCDIR/workspace/foo/bar` during execution.
(Each programming language has its own utility function for
accessing the value of `$TEST_SRCDIR`, but they are all
equivalent to using the environment variable directly.)
Failure to observe the rule will cause the test to fail when it is
executed on a remote testing host.
* `*_library` rules specify separately-compiled modules in the given
programming language. Libraries can depend on other libraries,
and binaries and tests can depend on libraries, with the expected
separate-compilation behavior.
## File encoding
`BUILD` and `.bzl` files should be encoded in UTF-8, of which ASCII is a valid
subset. Arbitrary byte sequences are currently allowed, but may stop being
supported in the future.
# Repositories, workspaces, packages, and targets
Source: https://bazel.build/concepts/build-ref
Bazel builds software from source code organized in directory trees called
repositories. A defined set of repositories comprises the workspace. Source
files in repositories are organized in a nested hierarchy of packages, where
each package is a directory that contains a set of related source files and one
`BUILD` file. The `BUILD` file specifies what software outputs can be built from
the source.
### Repositories
Source files used in a Bazel build are organized in *repositories* (often
shortened to *repos*). A repo is a directory tree with a boundary marker file at
its root; such a boundary marker file could be `MODULE.bazel`, `REPO.bazel`, or
in legacy contexts, `WORKSPACE` or `WORKSPACE.bazel`.
The repo in which the current Bazel command is being run is called the *main
repo*. Other, (external) repos are defined by *repo rules*; see [external dependencies overview](/external/overview) for more information.
## Workspace
A *workspace* is the environment shared by all Bazel commands run from the same
main repo. 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".
## Packages
The primary unit of code organization in a repository is the *package*. A
package is a collection of related files and a specification of how they can be
used to produce output artifacts.
A package is defined as a directory containing a
[`BUILD` file](/concepts/build-files) named either `BUILD` or `BUILD.bazel`. A
package includes all files in its directory, plus all subdirectories beneath it,
except those which themselves contain a `BUILD` file. From this definition, no
file or directory may be a part of two different packages.
For example, in the following directory tree there are two packages, `my/app`,
and the subpackage `my/app/tests`. Note that `my/app/data` is not a package, but
a directory belonging to package `my/app`.
```
src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc
```
## Targets
A package is a container of *targets*, which are defined in the package's
`BUILD` file. Most targets are one of two principal kinds, *files* and *rules*.
Files are further divided into two kinds. *Source files* are usually written by
the efforts of people, and checked in to the repository. *Generated files*,
sometimes called derived files or output files, are not checked in, but are
generated from source files.
The second kind of target is declared with a *rule*. Each rule instance
specifies the relationship between a set of input and a set of output files. The
inputs to a rule may be source files, but they also may be the outputs of other
rules.
Whether the input to a rule is a source file or a generated file is in most
cases immaterial; what matters is only the contents of that file. This fact
makes it easy to replace a complex source file with a generated file produced by
a rule, such as happens when the burden of manually maintaining a highly
structured file becomes too tiresome, and someone writes a program to derive it.
No change is required to the consumers of that file. Conversely, a generated
file may easily be replaced by a source file with only local changes.
The inputs to a rule may also include *other rules*. The precise meaning of such
relationships is often quite complex and language- or rule-dependent, but
intuitively it is simple: a C++ library rule A might have another C++ library
rule B for an input. The effect of this dependency is that B's header files are
available to A during compilation, B's symbols are available to A during
linking, and B's runtime data is available to A during execution.
An invariant of all rules is that the files generated by a rule always belong to
the same package as the rule itself; it is not possible to generate files into
another package. It is not uncommon for a rule's inputs to come from another
package, though.
Package groups are sets of packages whose purpose is to limit accessibility of
certain rules. Package groups are defined by the `package_group` function. They
have three properties: the list of packages they contain, their name, and other
package groups they include. The only allowed ways to refer to them are from the
`visibility` attribute of rules or from the `default_visibility` attribute of
the `package` function; they do not generate or consume files. For more
information, refer to the [`package_group` documentation](/reference/be/functions#package_group).
# Dependencies
Source: https://bazel.build/concepts/dependencies
A target `A` *depends upon* a target `B` if `B` is needed by `A` at build or
execution time. The *depends upon* relation induces a
[Directed Acyclic Graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph)
(DAG) over targets, and it is called a *dependency graph*.
A target's *direct* dependencies are those other targets reachable by a path
of length 1 in the dependency graph. A target's *transitive* dependencies are
those targets upon which it depends via a path of any length through the graph.
In fact, in the context of builds, there are two dependency graphs, the graph
of *actual dependencies* and the graph of *declared dependencies*. Most of the
time, the two graphs are so similar that this distinction need not be made, but
it is useful for the discussion below.
## Actual and declared dependencies
A target `X` is *actually dependent* on target `Y` if `Y` must be present,
built, and up-to-date in order for `X` to be built correctly. *Built* could
mean generated, processed, compiled, linked, archived, compressed, executed, or
any of the other kinds of tasks that routinely occur during a build.
A target `X` has a *declared dependency* on target `Y` if there is a dependency
edge from `X` to `Y` in the package of `X`.
For correct builds, the graph of actual dependencies *A* must be a subgraph of
the graph of declared dependencies *D*. That is, every pair of
directly-connected nodes `x --> y` in *A* must also be directly connected in
*D*. It can be said that *D* is an *overapproximation* of *A*.
Important: *D* should not be too much of an overapproximation of *A* because
redundant declared dependencies can make builds slower and binaries larger.
`BUILD` file writers must explicitly declare all of the actual direct
dependencies for every rule to the build system, and no more.
Failure to observe this principle causes undefined behavior: the build may fail,
but worse, the build may depend on some prior operations, or upon transitive
declared dependencies the target happens to have. Bazel checks for missing
dependencies and report errors, but it's not possible for this checking to be
complete in all cases.
You need not (and should not) attempt to list everything indirectly imported,
even if it is *needed* by `A` at execution time.
During a build of target `X`, the build tool inspects the entire transitive
closure of dependencies of `X` to ensure that any changes in those targets are
reflected in the final result, rebuilding intermediates as needed.
The transitive nature of dependencies leads to a common mistake. Sometimes,
code in one file may use code provided by an *indirect* dependency — a
transitive but not direct edge in the declared dependency graph. Indirect
dependencies don't appear in the `BUILD` file. Because the rule doesn't
directly depend on the provider, there is no way to track changes, as shown in
the following example timeline:
### Declared dependencies match actual dependencies
At first, everything works. The code in package `a` uses code in package `b`.
The code in package `b` uses code in package `c`, and thus `a` transitively
depends on `c`.

**Declared** dependency graph

**Actual** dependency graph
The declared dependencies overapproximate the actual dependencies. All is well.
### Adding an undeclared dependency
A latent hazard is introduced when someone adds code to `a` that creates a
direct *actual* dependency on `c`, but forgets to declare it in the build file
`a/BUILD`.
`a / a.in`
```
import b;
import c;
b.foo();
c.garply();
```

**Declared** dependency graph

**Actual** dependency graph
The declared dependencies no longer overapproximate the actual dependencies.
This may build ok, because the transitive closures of the two graphs are equal,
but masks a problem: `a` has an actual but undeclared dependency on `c`.
### Divergence between declared and actual dependency graphs
The hazard is revealed when someone refactors `b` so that it no longer depends on
`c`, inadvertently breaking `a` through no
fault of their own.

**Declared** dependency graph

**Actual** dependency graph
The declared dependency graph is now an underapproximation of the actual
dependencies, even when transitively closed; the build is likely to fail.
The problem could have been averted by ensuring that the actual dependency from
`a` to `c` introduced in Step 2 was properly declared in the `BUILD` file.
## Types of dependencies
Most build rules have three attributes for specifying different kinds of
generic dependencies: `srcs`, `deps` and `data`. These are explained below. For
more details, see
[Attributes common to all rules](/reference/be/common-definitions).
Many rules also have additional attributes for rule-specific kinds of
dependencies, for example, `compiler` or `resources`. These are detailed in the
[Build Encyclopedia](/reference/be/).
### `srcs` dependencies
Files consumed directly by the rule or rules that output source files.
### `deps` dependencies
Rule pointing to separately-compiled modules providing header files,
symbols, libraries, data, etc.
### `data` dependencies
A build target might need some data files to run correctly. These data files
aren't source code: they don't affect how the target is built. For example, a
unit test might compare a function's output to the contents of a file. When you
build the unit test you don't need the file, but you do need it when you run
the test. The same applies to tools that are launched during execution.
The build system runs tests in an isolated directory where only files listed as
`data` are available. Thus, if a binary/library/test needs some files to run,
specify them (or a build rule containing them) in `data`. For example:
```
# I need a config file from a directory named env:
java_binary(
name = "setenv",
...
data = [":env/default_env.txt"],
)
# I need test data from another directory
sh_test(
name = "regtest",
srcs = ["regtest.sh"],
data = [
"//data:file1.txt",
"//data:file2.txt",
...
],
)
```
These files are available using the relative path `path/to/data/file`. In tests,
you can refer to these files by joining the paths of the test's source
directory and the workspace-relative path, for example,
`${TEST_SRCDIR}/workspace/path/to/data/file`.
## Using labels to reference directories
As you look over our `BUILD` files, you might notice that some `data` labels
refer to directories. These labels end with `/.` or `/` like these examples,
which you should not use:
Not recommended —
`data = ["//data/regression:unittest/."]`
Not recommended —
`data = ["testdata/."]`
Not recommended —
`data = ["testdata/"]`
This seems convenient, particularly for tests because it allows a test to
use all the data files in the directory.
But try not to do this. In order to ensure correct incremental rebuilds (and
re-execution of tests) after a change, the build system must be aware of the
complete set of files that are inputs to the build (or test). When you specify
a directory, the build system performs a rebuild only when the directory itself
changes (due to addition or deletion of files), but won't be able to detect
edits to individual files as those changes don't affect the enclosing directory.
Rather than specifying directories as inputs to the build system, you should
enumerate the set of files contained within them, either explicitly or using the
[`glob()`](/reference/be/functions#glob) function. (Use `**` to force the
`glob()` to be recursive.)
Recommended —
`data = glob(["testdata/**"])`
Unfortunately, there are some scenarios where directory labels must be used.
For example, if the `testdata` directory contains files whose names don't
conform to the [label syntax](/concepts/labels#labels-lexical-specification),
then explicit enumeration of files, or use of the
[`glob()`](/reference/be/functions#glob) function produces an invalid labels
error. You must use directory labels in this case, but beware of the
associated risk of incorrect rebuilds described above.
If you must use directory labels, keep in mind that you can't refer to the
parent package with a relative `../` path; instead, use an absolute path like
`//data/regression:unittest/.`.
Note: Directory labels are only valid for data dependencies. If you try to use
a directory as a label in an argument other than `data`, it will fail and you
will get a (probably cryptic) error message.
Any external rule, such as a test, that needs to use multiple files must
explicitly declare its dependence on all of them. You can use `filegroup()` to
group files together in the `BUILD` file:
```
filegroup(
name = 'my_data',
srcs = glob(['my_unittest_data/*'])
)
```
You can then reference the label `my_data` as the data dependency in your test.
# Labels
Source: https://bazel.build/concepts/labels
A **label** is an identifier for a target. A typical label in its full canonical
form looks like:
```none theme={null}
@@myrepo//my/app/main:app_binary
```
The first part of the label is the repository name, `@@myrepo`. The double-`@`
syntax signifies that this is a [*canonical* repo name](/external/overview#canonical-repo-name), which is unique within
the workspace. Labels with canonical repo names unambiguously identify a target
no matter which context they appear in.
Often the canonical repo name is an arcane string that looks like
`@@rules_java++toolchains+local_jdk`. What is much more commonly seen is
labels with an [*apparent* repo name](/external/overview#apparent-repo-name),
which looks like:
```
@myrepo//my/app/main:app_binary
```
The only difference is the repo name being prefixed with one `@` instead of two.
This refers to a repo with the apparent name `myrepo`, which could be different
based on the context this label appears in.
In the typical case that a label refers to the same repository from which
it is used, the repo name part may be omitted. So, inside `@@myrepo` the first
label is usually written as
```
//my/app/main:app_binary
```
The second part of the label is the un-qualified package name
`my/app/main`, the path to the package
relative to the repository root. Together, the repository name and the
un-qualified package name form the fully-qualified package name
`@@myrepo//my/app/main`. When the label refers to the same
package it is used in, the package name (and optionally, the colon)
may be omitted. So, inside `@@myrepo//my/app/main`,
this label may be written either of the following ways:
```
app_binary
:app_binary
```
It is a matter of convention that the colon is omitted for files,
but retained for rules, but it is not otherwise significant.
The part of the label after the colon, `app_binary` is the un-qualified target
name. When it matches the last component of the package path, it, and the
colon, may be omitted. So, these two labels are equivalent:
```
//my/app/lib
//my/app/lib:lib
```
The name of a file target in a subdirectory of the package is the file's path
relative to the package root (the directory containing the `BUILD` file). So,
this file is in the `my/app/main/testdata` subdirectory of the repository:
```
//my/app/main:testdata/input.txt
```
Strings like `//my/app` and `@@some_repo//my/app` have two meanings depending on
the context in which they are used: when Bazel expects a label, they mean
`//my/app:app` and `@@some_repo//my/app:app`, respectively. But, when Bazel
expects a package (e.g. in `package_group` specifications), they reference the
package that contains that label.
A common mistake in `BUILD` files is using `//my/app` to refer to a package, or
to *all* targets in a package--it does not. Remember, it is
equivalent to `//my/app:app`, so it names the `app` target in the `my/app`
package of the current repository.
However, the use of `//my/app` to refer to a package is encouraged in the
specification of a `package_group` or in `.bzl` files, because it clearly
communicates that the package name is absolute and rooted in the top-level
directory of the workspace.
Relative labels cannot be used to refer to targets in other packages; the
repository identifier and package name must always be specified in this case.
For example, if the source tree contains both the package `my/app` and the
package `my/app/testdata` (each of these two directories has its own
`BUILD` file), the latter package contains a file named `testdepot.zip`. Here
are two ways (one wrong, one correct) to refer to this file within
`//my/app:BUILD`:
Wrong — `testdata` is a different package, so you can't use a relative path
testdata/testdepot.zip
Correct — refer to `testdata` with its full path
//my/app/testdata:testdepot.zip
Labels starting with `@@//` are references to the main
repository, which will still work even from external repositories.
Therefore `@@//a/b/c` is different from
`//a/b/c` when referenced from an external repository.
The former refers back to the main repository, while the latter
looks for `//a/b/c` in the external repository itself.
This is especially relevant when writing rules in the main
repository that refer to targets in the main repository, and will be
used from external repositories.
For information about the different ways you can refer to targets, see
[target patterns](/run/build#specifying-build-targets).
### Lexical specification of a label
Label syntax discourages use of metacharacters that have special meaning to the
shell. This helps to avoid inadvertent quoting problems, and makes it easier to
construct tools and scripts that manipulate labels, such as the
[Bazel Query Language](/query/language).
The precise details of allowed target names are below.
### Target names — `package-name:target-name`
`target-name` is the name of the target within the package. The name of a rule
is the value of the `name` attribute in the rule's declaration in a `BUILD`
file; the name of a file is its pathname relative to the directory containing
the `BUILD` file.
Target names must be composed entirely of characters drawn from the set `a`–`z`,
`A`–`Z`, `0`–`9`, and the punctuation symbols `!%-@^_"#$&'()*-+,;<=>?[]{|}~/.`.
Filenames must be relative pathnames in normal form, which means they must
neither start nor end with a slash (for example, `/foo` and `foo/` are
forbidden) nor contain multiple consecutive slashes as path separators
(for example, `foo//bar`). Similarly, up-level references (`..`) and
current-directory references (`./`) are forbidden.
Wrong — Do not use `..` to refer to files in other packages
Correct — Use
`//package-name:filename`
While it is common to use `/` in the name of a file target, avoid the use of
`/` in the names of rules. Especially when the shorthand form of a label is
used, it may confuse the reader. The label `//foo/bar/wiz` is always a shorthand
for `//foo/bar/wiz:wiz`, even if there is no such package `foo/bar/wiz`; it
never refers to `//foo:bar/wiz`, even if that target exists.
However, there are some situations where use of a slash is convenient, or
sometimes even necessary. For example, the name of certain rules must match
their principal source file, which may reside in a subdirectory of the package.
### Package names — `//package-name:target-name`
The name of a package is the name of the directory containing its `BUILD` file,
relative to the top-level directory of the containing repository.
For example: `my/app`.
On a technical level, Bazel enforces the following:
* Allowed characters in package names are the lowercase letters `a` through `z`,
the uppercase letters `A` through `Z`, the digits `0` through `9`, the
characters ``! \"#$%&'()*+,-.;<=>?@[]^_`{|}`` (yes, there's a space character
in there!), and of course forward slash `/` (since it's the directory
separator).
* Package names may not start or end with a forward slash character `/`.
* Package names may not contain the substring `//`. This wouldn't make
sense---what would the corresponding directory path be?
* Package names may not contain the substring `/./` or `/../` or `/.../` etc.
This enforcement is done to avoid confusion when translating between a logical
package name and a physical directory name, given the semantic meaning of the
dot character in path strings.
On a practical level:
* For a language with a directory structure that is significant to its module
system (for example, Java), it's important to choose directory names that are
valid identifiers in the language. For example, don't start with a leading
digit and avoid special characters, especially underscores and hyphens.
* Although Bazel supports targets in the workspace's root package (for example,
`//:foo`), it's best to leave that package empty so all meaningful packages
have descriptive names.
## Rules
A rule specifies the relationship between inputs and outputs, and the
steps to build the outputs. Rules can be of one of many different
kinds (sometimes called the *rule class*), which produce compiled
executables and libraries, test executables and other supported
outputs as described in the [Build Encyclopedia](/reference/be/overview).
`BUILD` files declare *targets* by invoking *rules*.
In the example below, we see the declaration of the target `my_app`
using the `cc_binary` rule.
```python theme={null}
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
```
Every rule invocation has a `name` attribute (which must be a valid
[target name](#target-names)), that declares a target within the package
of the `BUILD` file.
Every rule has a set of *attributes*; the applicable attributes for a given
rule, and the significance and semantics of each attribute are a function of
the rule's kind; see the [Build Encyclopedia](/reference/be/overview) for a
list of rules and their corresponding attributes. Each attribute has a name and
a type. Some of the common types an attribute can have are integer, label, list
of labels, string, list of strings, output label, list of output labels. Not
all attributes need to be specified in every rule. Attributes thus form a
dictionary from keys (names) to optional, typed values.
The `srcs` attribute present in many rules has type "list of labels"; its
value, if present, is a list of labels, each being the name of a target that is
an input to this rule.
In some cases, the name of the rule kind is somewhat arbitrary, and more
interesting are the names of the files generated by the rule, and this is true
of genrules. For more information, see
[General Rules: genrule](/reference/be/general#genrule).
In other cases, the name is significant: for `*_binary` and `*_test` rules,
for example, the rule name determines the name of the executable produced by
the build.
This directed acyclic graph over targets is called the *target graph* or
*build dependency graph*, and is the domain over which the
[Bazel Query tool](/query/guide) operates.
# Platforms
Source: https://bazel.build/concepts/platforms
## Intro
Bazel can build and test code on a variety of hardware, operating systems, and
system configurations. This can involve different versions of build tools like
linkers and compilers. To help manage this complexity, Bazel has the concepts
of *constraints* and *platforms*.
A *constraint* is a distinguishing property of a build or production machine.
Common constraints are CPU architecture, presence or absence of a GPU, or
version of a locally installed compiler. But constraints can be *anything* that
meaningfully distinguishes machines when orchestrating build work.
A *platform* is a collection of constraints that specifies a complete machine.
Bazel uses this concept to let developers choose which machines they want to
build for, which machines should run compile and test actions, and which
[toolchains](/extending/toolchains) build actions should compile with.
Developers can also use constraints to [select](/docs/configurable-attributes)
custom properties or dependencies on their build rules. For example: "*use
`src_arm.cc` when the build targets an Arm machine*".
## Platform types
Bazel recognizes three roles a platform may play:
* **Host** - The platform on which Bazel itself runs.
* **Execution** - A platform which runs compile actions to produce build outputs.
* **Target** - A platform the code being built should run on.
Note: Builds only have one host platform, but often have multiple execution and
target platforms. For example, both remote Linux CI machines and developer Macs
may run build actions. And mobile apps have code for multiple phone types and
hardware extensions.
Builds generally have three kinds of relationships to platforms:
* **Single-platform builds** - Host, execution, and target platforms are the
same. For example, building on a developer machine without remote execution,
then running the built binary on the same machine.
* **Cross-compilation builds** - Host and execution platforms are the same,
but the target platform is different. For example, building an iOS app on a
Macbook Pro without remote execution.
* **Multi-platform builds** - Host, execution, and target platforms are all
different. For example, building an iOS app on a Macbook Pro and using remote
Linux machines to compile C++ actions that don't need Xcode.
## Specifying platforms
The most common way for developers to use platforms is to specify desired
target machines with the `--platforms` flag:
```shell theme={null}
$ bazel build //:my_linux_app --platforms=//myplatforms:linux_x86
```
Organizations generally maintain their own platform definitions because build
machine setups vary between organizations.
When `--platforms` isn't set, it defaults to `@platforms//host`. This is
specially defined to auto-detect the host machine's OS and CPU properties so
builds target the same machine Bazel runs on. Build rules can
[select](/docs/configurable-attributes) on these properties with the
[@platforms/os](https://github.com/bazelbuild/platforms/blob/main/os/BUILD) and
[@platforms/cpu](https://github.com/bazelbuild/platforms/blob/main/cpu/BUILD)
constraints.
## Generally useful constraints and platforms
To keep the ecosystem consistent, Bazel team maintains a repository with
constraint definitions for the most popular CPU architectures and operating
systems. These are all defined in
[https://github.com/bazelbuild/platforms](https://github.com/bazelbuild/platforms).
Bazel ships with the following special platform definition:
`@platforms//host` (aliased as `@bazel_tools//tools:host_platform`). This
auto-detects the OS and CPU properties of the machine Bazel runs on.
## Defining constraints
Constraints are modeled with the [`constraint_setting`][constraint_setting] and
[`constraint_value`][constraint_value] build rules.
[constraint_setting]: /reference/be/platforms-and-toolchains#constraint_setting
[constraint_value]: /reference/be/platforms-and-toolchains#constraint_value
`constraint_setting` declares a type of property. For example:
```python theme={null}
constraint_setting(name = "cpu")
```
`constraint_value` declares a possible value for that property:
```python theme={null}
constraint_value(
name = "x86",
constraint_setting = ":cpu"
)
```
These can be referenced as labels when defining platforms or customizing build rules
on them. If the above examples are defined in `cpus/BUILD`, you can reference
the `x86` constraint as `//cpus:x86`.
If visibility allows, you can extend an existing `constraint_setting` by
defining your own value for it.
## Defining platforms
The [`platform`](/reference/be/platforms-and-toolchains#platform) build rule
defines a platform as a collection of `constraint_value`s:
```python theme={null}
platform(
name = "linux_x86",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86",
],
)
```
This models a machine that must have both the `@platforms//os:linux` and `@platforms//cpu:x86`
constraints.
Platforms may only have one `constraint_value` for a given `constraint_setting`.
This means, for example, a platform can't have two CPUs unless you create another
`constraint_setting` type to model the second value.
## Skipping incompatible targets
When building for a specific target platform it is often desirable to skip
targets that will never work on that platform. For example, your Windows device
driver is likely going to generate lots of compiler errors when building on a
Linux machine with `//...`. Use the
[`target_compatible_with`](/reference/be/common-definitions#common.target_compatible_with)
attribute to tell Bazel what target platform constraints your code has.
The simplest use of this attribute restricts a target to a single platform.
The target won't be built for any platform that doesn't satisfy all of the
constraints. The following example restricts `win_driver_lib.cc` to 64-bit
Windows.
```python theme={null}
cc_library(
name = "win_driver_lib",
srcs = ["win_driver_lib.cc"],
target_compatible_with = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
],
)
```
`:win_driver_lib` is *only* compatible for building with 64-bit Windows and
incompatible with all else. Incompatibility is transitive. Any targets
that transitively depend on an incompatible target are themselves considered
incompatible.
### When are targets skipped?
Targets are skipped when they are considered incompatible and included in the
build as part of a target pattern expansion. For example, the following two
invocations skip any incompatible targets found in a target pattern expansion.
```console theme={null}
$ bazel build --platforms=//:myplatform //...
```
```console theme={null}
$ bazel build --platforms=//:myplatform //:all
```
Incompatible tests in a [`test_suite`](/reference/be/general#test_suite) are
similarly skipped if the `test_suite` is specified on the command line with
[`--expand_test_suites`](/reference/command-line-reference#flag--expand_test_suites).
In other words, `test_suite` targets on the command line behave like `:all` and
`...`. Using `--noexpand_test_suites` prevents expansion and causes
`test_suite` targets with incompatible tests to also be incompatible.
Explicitly specifying an incompatible target on the command line results in an
error message and a failed build.
```console theme={null}
$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully
```
Incompatible explicit targets are silently skipped if
`--skip_incompatible_explicit_targets` is enabled.
### More expressive constraints
For more flexibility in expressing constraints, use the
`@platforms//:incompatible`
[`constraint_value`](/reference/be/platforms-and-toolchains#constraint_value)
that no platform satisfies.
Use [`select()`](/reference/be/functions#select) in combination with
`@platforms//:incompatible` to express more complicated restrictions. For
example, use it to implement basic OR logic. The following marks a library
compatible with macOS and Linux, but no other platforms.
Note: An empty constraints list is equivalent to "compatible with everything".
```python theme={null}
cc_library(
name = "unixish_lib",
srcs = ["unixish_lib.cc"],
target_compatible_with = select({
"@platforms//os:osx": [],
"@platforms//os:linux": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
```
The above can be interpreted as follows:
1. When targeting macOS, the target has no constraints.
2. When targeting Linux, the target has no constraints.
3. Otherwise, the target has the `@platforms//:incompatible` constraint. Because
`@platforms//:incompatible` is not part of any platform, the target is
deemed incompatible.
To make your constraints more readable, use
[skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`selects.with_or()`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectswith_or).
You can express inverse compatibility in a similar way. The following example
describes a library that is compatible with everything *except* for ARM.
```python theme={null}
cc_library(
name = "non_arm_lib",
srcs = ["non_arm_lib.cc"],
target_compatible_with = select({
"@platforms//cpu:arm": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
)
```
### Detecting incompatible targets using `bazel cquery`
You can use the
[`IncompatiblePlatformProvider`](/rules/lib/providers/IncompatiblePlatformProvider)
in `bazel cquery`'s [Starlark output format](/query/cquery#output-format-definition) to distinguish
incompatible targets from compatible ones.
This can be used to filter out incompatible targets. The example below will
only print the labels for targets that are compatible. Incompatible targets are
not printed.
```console theme={null}
$ cat example.cquery
def format(target):
if "IncompatiblePlatformProvider" not in providers(target):
return target.label
return ""
$ bazel cquery //... --output=starlark --starlark:file=example.cquery
```
### Known Issues
Incompatible targets [ignore visibility restrictions](https://github.com/bazelbuild/bazel/issues/16044).
# Runfiles
Source: https://bazel.build/concepts/runfiles
[Runfiles are a set of files used by a target at runtime (as opposed to build time)](/extending/rules#runfiles).
Do not hardcode runfiles paths. Those contain the [canonical repository name](/external/overview#canonical-repo-name), but [the canonical repository name format is an implementation detail that may change at any time](/external/module#repository_names_and_strict_deps).
Use one of the language-specific runfiles libraries to access them:
* [rules\_cc](https://github.com/bazelbuild/rules_cc/blob/main/cc/runfiles/runfiles.h)
* [rules\_go](https://github.com/bazel-contrib/rules_go/blob/master/go/runfiles/runfiles.go)
* [rules\_python](https://github.com/bazel-contrib/rules_python/blob/main/python/runfiles/runfiles.py)
* [rules\_shell](https://github.com/bazelbuild/rules_shell/blob/main/shell/runfiles/runfiles.bash)
Runfiles are generally referenced by an `rlocationpath` in the form of `$REPO/package/file` where `$REPO` should be the [apparent repository name](/external/overview#apparent-repo-name).
Most runfiles libraries (see below) support functionality to determine the repository of the currently executed target which is useful to refer to other files in the same repository.
Many Bazel rules support [Make Variables](/reference/be/make-variables#predefined_label_variables) to translate from a target to an rlocationpath by using the `$(rlocationpath //package:target)` notation.
Examples:
**C++**
```python theme={null}
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
cc_binary(
name = "runfile",
srcs = ["runfile.cc"],
data = ["//examples:runfile.txt"],
deps = ["@rules_cc//cc/runfiles"],
)
```
```cpp theme={null}
#include
#include
#include
#include
#include "rules_cc/cc/runfiles/runfiles.h"
using rules_cc::cc::runfiles::Runfiles;
inline constexpr std::string_view someFile = "examples/runfile.txt";
int main(int argc, char **argv) {
std::string error;
const auto runfiles = Runfiles::Create(argv[0], BAZEL_CURRENT_REPOSITORY, &error);
if (runfiles == nullptr) {
std::cerr << "Failed to create Runfiles object" << error << "\n";
return 1;
}
std::string root = BAZEL_CURRENT_REPOSITORY;
if (root == "") {
root = "_main";
}
const std::string realPathToSomeFile = runfiles->Rlocation(std::filesystem::path(root) / someFile);
std::cout << "The content of the runfile is:\n";
std::ifstream fin(realPathToSomeFile);
std::string line;
while (std::getline(fin, line)) {
std::cout << line << "\n";
}
return 0;
}
```
**Golang**
```python theme={null}
load("@rules_go//go:def.bzl", "go_binary")
go_binary(
name = "runfile",
srcs = ["runfile.go"],
data = ["//examples:runfile.txt"],
deps = ["@rules_go//go/runfiles:go_default_library"],
)
```
```go theme={null}
package main
import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/bazelbuild/rules_go/go/runfiles"
)
const (
someFile = "examples/runfile.txt"
)
func main() {
r, err := runfiles.New()
if err != nil {
log.Fatalf("Failed to create Runfiles object: %v", err)
}
root := runfiles.CallerRepository()
if root == "" {
root = "_main"
}
path, err := r.Rlocation(filepath.Join(root, someFile))
if err != nil {
log.Fatalf("Failed to find rlocation: %v", err)
}
fmt.Println("The content of my runfile is:")
data, err := os.ReadFile(path)
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
fmt.Print(string(data))
}
```
**Python**
```python theme={null}
load("@rules_python//python:defs.bzl", "py_binary")
py_binary(
name = "runfile",
srcs = ["runfile.py"],
data = ["//examples:runfile.txt"],
deps = ["@rules_python//python/runfiles"],
)
```
```python theme={null}
import pathlib
from python.runfiles import runfiles
SOME_FILE = pathlib.Path('examples/runfile.txt')
r = runfiles.Create()
root = r.CurrentRepository()
if root == "":
root = "_main"
realPathToSomeFile = r.Rlocation(str(root / SOME_FILE))
print("The content of the runfile is:")
with open(realPathToSomeFile, 'r') as f:
print(f.read())
```
**Shell**
```python theme={null}
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
sh_binary(
name = "runfile",
srcs = ["runfile.sh"],
data = ["//examples:runfile.txt"],
use_bash_launcher = True,
)
```
```bash theme={null}
#!/bin/bash
SOME_FILE='examples/runfile.txt'
root="$(runfiles_current_repository)"
if [ -z "$root" ]; then
root="_main"
fi
real_path_to_some_file="$(rlocation "${root}/${SOME_FILE}")"
echo "The content of the runfile is:"
cat "${real_path_to_some_file}"
```
# Visibility
Source: https://bazel.build/concepts/visibility
This page covers Bazel's three visibility systems:
[target visibility](#target-visibility),[transitive visibility](#transitive-visibility)
and [load visibility](#load-visibility).
These types of visibility help other developers distinguish between your
library's public API and its implementation details, and help enforce structure
as your workspace grows. You can also use visibility when deprecating a public
API to allow current users while denying new ones.
## Target visibility
**Target visibility** controls who may depend on your target — that is, who may
use your target's label inside an attribute such as `deps`. A target will fail
to build during the [analysis](/reference/glossary#analysis-phase) phase if it
violates the visibility of one of its dependencies.
Generally, a target `A` is visible to a target `B` if they are in the same
location, or if `A` grants visibility to `B`'s location. In the absence of
[symbolic macros](/extending/macros), the term "location" can be simplified
to just "package"; see [below](#symbolic-macros) for more on symbolic macros.
Visibility is specified by listing allowed packages. Allowing a package does not
necessarily mean that its subpackages are also allowed. For more details on
packages and subpackages, see [Concepts and terminology](/concepts/build-ref).
For prototyping, you can disable target visibility enforcement by setting the
flag `--check_visibility=false`. This shouldn't be done for production usage in
submitted code.
The primary way to control visibility is with a rule's
[`visibility`](/reference/be/common-definitions#common.visibility) attribute.
The following subsections describe the attribute's format, how to apply it to
various kinds of targets, and the interaction between the visibility system and
symbolic macros.
### Visibility specifications
All rule targets have a `visibility` attribute that takes a list of labels. Each
label has one of the following forms. With the exception of the last form, these
are just syntactic placeholders that don't correspond to any actual target.
* `"//visibility:public"`: Grants access to all packages.
* `"//visibility:private"`: Does not grant any additional access; only targets
in this location's package can use this target.
* `"//foo/bar:__pkg__"`: Grants access to `//foo/bar` (but not its
subpackages).
* `"//foo/bar:__subpackages__"`: Grants access to `//foo/bar` and all of its
direct and indirect subpackages.
* `"//some_pkg:my_package_group"`: Grants access to all of the packages that
are part of the given [`package_group`](/reference/be/functions#package_group).
* Package groups use a
[different syntax](/reference/be/functions#package_group.packages) for
specifying packages. Within a package group, the forms
`"//foo/bar:__pkg__"` and `"//foo/bar:__subpackages__"` are respectively
replaced by `"//foo/bar"` and `"//foo/bar/..."`. Likewise,
`"//visibility:public"` and `"//visibility:private"` are just `"public"`
and `"private"`.
For example, if `//some/package:mytarget` has its `visibility` set to
`[":__subpackages__", "//tests:__pkg__"]`, then it could be used by any target
that is part of the `//some/package/...` source tree, as well as targets
declared in `//tests/BUILD`, but not by targets defined in
`//tests/integration/BUILD`.
**Best practice:** To make several targets visible to the same set
of packages, use a `package_group` instead of repeating the list in each
target's `visibility` attribute. This increases readability and prevents the
lists from getting out of sync.
**Best practice:** When granting visibility to another team's project, prefer
`__subpackages__` over `__pkg__` to avoid needless visibility churn as that
project evolves and adds new subpackages.
Note: The `visibility` attribute may not specify non-`package_group` targets.
Doing so triggers a "Label does not refer to a package group" or "Cycle in
dependency graph" error.
### Rule target visibility
A rule target's visibility is determined by taking its `visibility` attribute
\-- or a suitable default if not given -- and appending the location where the
target was declared. For targets not declared in a symbolic macro, if the
package specifies a [`default_visibility`](/reference/be/functions#package.default_visibility),
this default is used; for all other packages and for targets declared in a
symbolic macro, the default is just `["//visibility:private"]`.
```starlark theme={null}
# //mypkg/BUILD
package(default_visibility = ["//friend:__pkg__"])
cc_library(
name = "t1",
...
# No visibility explicitly specified.
# Effective visibility is ["//friend:__pkg__", "//mypkg:__pkg__"].
# If no default_visibility were given in package(...), the visibility would
# instead default to ["//visibility:private"], and the effective visibility
# would be ["//mypkg:__pkg__"].
)
cc_library(
name = "t2",
...
visibility = [":clients"],
# Effective visibility is ["//mypkg:clients, "//mypkg:__pkg__"], which will
# expand to ["//another_friend:__subpackages__", "//mypkg:__pkg__"].
)
cc_library(
name = "t3",
...
visibility = ["//visibility:private"],
# Effective visibility is ["//mypkg:__pkg__"]
)
package_group(
name = "clients",
packages = ["//another_friend/..."],
)
```
**Best practice:** Avoid setting `default_visibility` to public. It may be
convenient for prototyping or in small codebases, but the risk of inadvertently
creating public targets increases as the codebase grows. It's better to be
explicit about which targets are part of a package's public interface.
### Generated file target visibility
A generated file target has the same visibility as the rule target that
generates it.
```starlark theme={null}
# //mypkg/BUILD
java_binary(
name = "foo",
...
visibility = ["//friend:__pkg__"],
)
```
```starlark theme={null}
# //friend/BUILD
some_rule(
name = "bar",
deps = [
# Allowed directly by visibility of foo.
"//mypkg:foo",
# Also allowed. The java_binary's "_deploy.jar" implicit output file
# target the same visibility as the rule target itself.
"//mypkg:foo_deploy.jar",
]
...
)
```
### Source file target visibility
Source file targets can either be explicitly declared using
[`exports_files`](/reference/be/functions#exports_files), or implicitly created
by referring to their filename in a label attribute of a rule (outside of a
symbolic macro). As with rule targets, the location of the call to
`exports_files`, or the BUILD file that referred to the input file, is always
automatically appended to the file's visibility.
Files declared by `exports_files` can have their visibility set by the
`visibility` parameter to that function. If this parameter is not given, the visibility is public.
Note: `exports_files` may not be used to override the visibility of a generated
file.
For files that do not appear in a call to `exports_files`, the visibility
depends on the value of the flag
[`--incompatible_no_implicit_file_export`](https://github.com/bazelbuild/bazel/issues/10225):
* If the flag is true, the visibility is private.
* Else, the legacy behavior applies: The visibility is the same as the
`BUILD` file's `default_visibility`, or private if a default visibility is
not specified.
Avoid relying on the legacy behavior. Always write an `exports_files`
declaration whenever a source file target needs non-private visibility.
**Best practice:** When possible, prefer to expose a rule target rather than a
source file. For example, instead of calling `exports_files` on a `.java` file,
wrap the file in a non-private `java_library` target. Generally, rule targets
should only directly reference source files that live in the same package.
#### Example
File `//frobber/data/BUILD`:
```starlark theme={null}
exports_files(["readme.txt"])
```
File `//frobber/bin/BUILD`:
```starlark theme={null}
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
```
### Config setting visibility
Historically, Bazel has not enforced visibility for
[`config_setting`](/reference/be/general#config_setting) targets that are
referenced in the keys of a [`select()`](/reference/be/functions#select). There
are two flags to remove this legacy behavior:
* [`--incompatible_enforce_config_setting_visibility`](https://github.com/bazelbuild/bazel/issues/12932)
enables visibility checking for these targets. To assist with migration, it
also causes any `config_setting` that does not specify a `visibility` to be
considered public (regardless of package-level `default_visibility`).
* [`--incompatible_config_setting_private_default_visibility`](https://github.com/bazelbuild/bazel/issues/12933)
causes `config_setting`s that do not specify a `visibility` to respect the
package's `default_visibility` and to fallback on private visibility, just
like any other rule target. It is a no-op if
`--incompatible_enforce_config_setting_visibility` is not set.
Avoid relying on the legacy behavior. Any `config_setting` that is intended to
be used outside the current package should have an explicit `visibility`, if the
package does not already specify a suitable `default_visibility`.
### Package group target visibility
`package_group` targets do not have a `visibility` attribute. They are always
publicly visible.
### Visibility of implicit dependencies
Some rules have [implicit dependencies](/extending/rules#private_attributes_and_implicit_dependencies) —
dependencies that are not spelled out in a `BUILD` file but are inherent to
every instance of that rule. For example, a `cc_library` rule might create an
implicit dependency from each of its rule targets to an executable target
representing a C++ compiler.
The visibility of such an implicit dependency is checked with respect to the
package containing the `.bzl` file in which the rule (or aspect) is defined. In
our example, the C++ compiler could be private so long as it lives in the same
package as the definition of the `cc_library` rule. As a fallback, if the
implicit dependency is not visible from the definition, it is checked with
respect to the `cc_library` target.
If you want to restrict the usage of a rule to certain packages, use
[load visibility](#load-visibility) instead.
### Visibility and symbolic macros
This section describes how the visibility system interacts with
[symbolic macros](/extending/macros).
#### Locations within symbolic macros
A key detail of the visibility system is how we determine the location of a
declaration. For targets that are not declared in a symbolic macro, the location
is just the package where the target lives -- the package of the `BUILD` file.
But for targets created in a symbolic macro, the location is the package
containing the `.bzl` file where the macro's definition (the
`my_macro = macro(...)` statement) appears. When a target is created inside
multiple nested targets, it is always the innermost symbolic macro's definition
that is used.
The same system is used to determine what location to check against a given
dependency's visibility. If the consuming target was created inside a macro, we
look at the innermost macro's definition rather than the package the consuming
target lives in.
This means that all macros whose code is defined in the same package are
automatically "friends" with one another. Any target directly created by a macro
defined in `//lib:defs.bzl` can be seen from any other macro defined in `//lib`,
regardless of what packages the macros are actually instantiated in. Likewise,
they can see, and can be seen by, targets declared directly in `//lib/BUILD` and
its legacy macros. Conversely, targets that live in the same package cannot
necessarily see one another if at least one of them is created by a symbolic
macro.
Within a symbolic macro's implementation function, the `visibility` parameter
has the effective value of the macro's `visibility` attribute after appending
the location where the macro was called. The standard way for a macro to export
one of its targets to its caller is to forward this value along to the target's
declaration, as in `some_rule(..., visibility = visibility)`. Targets that omit
this attribute won't be visible to the caller of the macro unless the caller
happens to be in the same package as the macro definition. This behavior
composes, in the sense that a chain of nested calls to submacros may each pass
`visibility = visibility`, re-exporting the inner macro's exported targets to
the caller at each level, without exposing any of the macros' implementation
details.
#### Delegating privileges to a submacro
The visibility model has a special feature to allow a macro to delegate its
permissions to a submacro. This is important for factoring and composing macros.
Suppose you have a macro `my_macro` that creates a dependency edge using a rule
`some_library` from another package:
```starlark theme={null}
# //macro/defs.bzl
load("//lib:defs.bzl", "some_library")
def _impl(name, visibility, ...):
...
native.genrule(
name = name + "_dependency"
...
)
some_library(
name = name + "_consumer",
deps = [name + "_dependency"],
...
)
my_macro = macro(implementation = _impl, ...)
```
```starlark theme={null}
# //pkg/BUILD
load("//macro:defs.bzl", "my_macro")
my_macro(name = "foo", ...)
```
The `//pkg:foo_dependency` target has no `visibility` specified, so it is only
visible within `//macro`, which works fine for the consuming target. Now, what
happens if the author of `//lib` refactors `some_library` to instead be
implemented using a macro?
```starlark theme={null}
# //lib:defs.bzl
def _impl(name, visibility, deps, ...):
some_rule(
# Main target, exported.
name = name,
visibility = visibility,
deps = deps,
...)
some_library = macro(implementation = _impl, ...)
```
With this change, `//pkg:foo_consumer`'s location is now `//lib` rather than
`//macro`, so its usage of `//pkg:foo_dependency` violates the dependency's
visibility. The author of `my_macro` can't be expected to pass
`visibility = ["//lib"]` to the declaration of the dependency just to work
around this implementation detail.
For this reason, when a dependency of a target is also an attribute value of the
macro that declared the target, we check the dependency's visibility against the
location of the macro instead of the location of the consuming target.
In this example, to validate whether `//pkg:foo_consumer` can see
`//pkg:foo_dependency`, we see that `//pkg:foo_dependency` was also passed as an
input to the call to `some_library` inside of `my_macro`, and instead check the
dependency's visibility against the location of this call, `//macro`.
This process can repeat recursively, as long as a target or macro declaration is
inside of another symbolic macro taking the dependency's label in one of its
label-typed attributes.
Note: Visibility delegation does not work for labels that were not passed into
the macro, such as labels derived by string manipulation.
#### Finalizers
Targets declared in a rule finalizer (a symbolic macro with `finalizer = True`),
in addition to seeing targets following the usual symbolic macro visibility
rules, can *also* see all targets which are visible to the finalizer target's
package.
In other words, if you migrate a `native.existing_rules()`-based legacy macro to
a finalizer, the targets declared by the finalizer will still be able to see
their old dependencies.
It is possible to define targets that a finalizer can introspect using
`native.existing_rules()`, but which it cannot use as dependencies under the
visibility system. For example, if a macro-defined target is not visible to its
own package or to the finalizer macro's definition, and is not delegated to the
finalizer, the finalizer cannot see such a target. Note, however, that a
`native.existing_rules()`-based legacy macro will also be unable to see such a
target.
## Transitive visibility
**Transitive visibility** is a way of restricting who may depend on a target,
including when the dependency is only indirect. It applies separately from the
ordinary target visibility system, so it is possible for a transitive visibility
error to occur even when every link in the dependency chain is valid. This
allows the author of the target to share it with a trusted set of client targets
while guarding against inadvertently leaking it to the rest of the build.
Transitive visibility is declared at the package level, using the
`transitive_visibility` parameter of the \[`package`]\[package]
function. This declaration applies to all targets in the package. The parameter
takes a single label of a `package_group`, which specifies the packages whose
targets may transitively depend on this package's targets.
```starlark theme={null}
# //third_party/sensitive_dep/BUILD
package(
# This must be explicitly listed
transitive_visibility = [":sensitive_dep_users"]
)
package_group(
name = "sensitive_dep_users",
packages = [
"//third_party/sensitive_dep/...", # has to include itself
"//allowed",
],
)
sh_library(
name = "sensitive_dep"
)
```
```starlark theme={null}
# //not_allowed/BUILD
sh_binary(
name = "bad",
deps = ["//third_party/sensitive_dep:sensitive_dep"]
)
```
Building `//not_allowed:bad`, which depends on
`//third_party/sensitive_dep:sensitive_dep` but is not part of its
`transitive_visibility`, results in the following error:
```none theme={null}
Transitive visibility error: //third_party/sensitive_dep:sensitive_dep is not transitively visible from ///not_allowed:bad. //"//third_party/sensitive_dep:sensitive_dep inherits a transitive_visibility declaration from its package or one of its dependencies that does not allow //not_allowed:bad.
```
Package groups used in `transitive_visibility` may not `include` other package
groups.
Note that if a target has a transitive dependency with a transitive visibility
restriction, that target itself inherits the restriction and passes it along to
targets that depend on it. If a target has multiple transitive dependencies
with transitive visibility restrictions, it must meet all of the restrictions.
Transitive visibility also applies to targets that are declared in symbolic
macros. However, unlike ordinary target visibility, it only considers the
package these targets live in, not the package that defined the symbolic macro.
## Load visibility
**Load visibility** controls whether a `.bzl` file may be loaded from other
`BUILD` or `.bzl` files outside the current package.
In the same way that target visibility protects source code that is encapsulated
by targets, load visibility protects build logic that is encapsulated by `.bzl`
files. For instance, a `BUILD` file author might wish to factor some repetitive
target declarations into a macro in a `.bzl` file. Without the protection of
load visibility, they might find their macro reused by other collaborators in
the same workspace, so that modifying the macro breaks other teams' builds.
Note that a `.bzl` file may or may not have a corresponding source file target.
If it does, there is no guarantee that the load visibility and the target
visibility coincide. That is, the same `BUILD` file might be able to load the
`.bzl` file but not list it in the `srcs` of a [`filegroup`](/reference/be/general#filegroup),
or vice versa. This can sometimes cause problems for rules that wish to consume
`.bzl` files as source code, such as for documentation generation or testing.
For prototyping, you may disable load visibility enforcement by setting
`--check_bzl_visibility=false`. As with `--check_visibility=false`, this should
not be done for submitted code.
Load visibility is available as of Bazel 6.0.
### Declaring load visibility
To set the load visibility of a `.bzl` file, call the
[`visibility()`](/rules/lib/globals/bzl#visibility) function from within the file.
The argument to `visibility()` is a list of package specifications, just like
the [`packages`](/reference/be/functions#package_group.packages) attribute of
`package_group`. However, `visibility()` does not accept negative package
specifications.
The call to `visibility()` must only occur once per file, at the top level (not
inside a function), and ideally immediately following the `load()` statements.
Unlike target visibility, the default load visibility is always public. Files
that do not call `visibility()` are always loadable from anywhere in the
workspace. It is a good idea to add `visibility("private")` to the top of any
new `.bzl` file that is not specifically intended for use outside the package.
### Example
```starlark theme={null}
# //mylib/internal_defs.bzl
# Available to subpackages and to mylib's tests.
visibility(["//mylib/...", "//tests/mylib/..."])
def helper(...):
...
```
```starlark theme={null}
# //mylib/rules.bzl
load(":internal_defs.bzl", "helper")
# Set visibility explicitly, even though public is the default.
# Note the [] can be omitted when there's only one entry.
visibility("public")
myrule = rule(
...
)
```
```starlark theme={null}
# //someclient/BUILD
load("//mylib:rules.bzl", "myrule") # ok
load("//mylib:internal_defs.bzl", "helper") # error
...
```
### Load visibility practices
This section describes tips for managing load visibility declarations.
#### Factoring visibilities
When multiple `.bzl` files should have the same visibility, it can be helpful to
factor their package specifications into a common list. For example:
```starlark theme={null}
# //mylib/internal_defs.bzl
visibility("private")
clients = [
"//foo",
"//bar/baz/...",
...
]
```
```starlark theme={null}
# //mylib/feature_A.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
```
```starlark theme={null}
# //mylib/feature_B.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
```
This helps prevent accidental skew between the various `.bzl` files'
visibilities. It also is more readable when the `clients` list is large.
#### Composing visibilities
Sometimes a `.bzl` file might need to be visible to an allowlist that is
composed of multiple smaller allowlists. This is analogous to how a
`package_group` can incorporate other `package_group`s via its
[`includes`](/reference/be/functions#package_group.includes) attribute.
Suppose you are deprecating a widely used macro. You want it to be visible only
to existing users and to the packages owned by your own team. You might write:
```starlark theme={null}
# //mylib/macros.bzl
load(":internal_defs.bzl", "our_packages")
load("//some_big_client:defs.bzl", "their_remaining_uses")
# List concatenation. Duplicates are fine.
visibility(our_packages + their_remaining_uses)
```
#### Deduplicating with package groups
Unlike target visibility, you cannot define a load visibility in terms of a
`package_group`. If you want to reuse the same allowlist for both target
visibility and load visibility, it's best to move the list of package
specifications into a .bzl file, where both kinds of declarations may refer to
it. Building off the example in [Factoring visibilities](#factoring-visibilities)
above, you might write:
```starlark theme={null}
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
```
This only works if the list does not contain any negative package
specifications.
#### Protecting individual symbols
Any Starlark symbol whose name begins with an underscore cannot be loaded from
another file. This makes it easy to create private symbols, but does not allow
you to share these symbols with a limited set of trusted files. On the other
hand, load visibility gives you control over what other packages may see your
`.bzl file`, but does not allow you to prevent any non-underscored symbol from
being loaded.
Luckily, you can combine these two features to get fine-grained control.
```starlark theme={null}
# //mylib/internal_defs.bzl
# Can't be public, because internal_helper shouldn't be exposed to the world.
visibility("private")
# Can't be underscore-prefixed, because this is
# needed by other .bzl files in mylib.
def internal_helper(...):
...
def public_util(...):
...
```
```starlark theme={null}
# //mylib/defs.bzl
load(":internal_defs", "internal_helper", _public_util="public_util")
visibility("public")
# internal_helper, as a loaded symbol, is available for use in this file but
# can't be imported by clients who load this file.
...
# Re-export public_util from this file by assigning it to a global variable.
# We needed to import it under a different name ("_public_util") in order for
# this assignment to be legal.
public_util = _public_util
```
#### bzl-visibility Buildifier lint
There is a [Buildifier lint](https://github.com/bazelbuild/buildtools/blob/master/WARNINGS.md#bzl-visibility)
that provides a warning if users load a file from a directory named `internal`
or `private`, when the user's file is not itself underneath the parent of that
directory. This lint predates the load visibility feature and is unnecessary in
workspaces where `.bzl` files declare visibilities.
# Configurable Build Attributes
Source: https://bazel.build/configure/attributes
***Configurable attributes***, commonly known as [`select()`](/reference/be/functions#select), is a Bazel feature that lets users toggle the values
of build rule attributes at the command line.
This can be used, for example, for a multiplatform library that automatically
chooses the appropriate implementation for the architecture, or for a
feature-configurable binary that can be customized at build time.
## Example
```python theme={null}
# myapp/BUILD
cc_binary(
name = "mybinary",
srcs = ["main.cc"],
deps = select({
":arm_build": [":arm_lib"],
":x86_debug_build": [":x86_dev_lib"],
"//conditions:default": [":generic_lib"],
}),
)
config_setting(
name = "arm_build",
values = {"cpu": "arm"},
)
config_setting(
name = "x86_debug_build",
values = {
"cpu": "x86",
"compilation_mode": "dbg",
},
)
```
This declares a `cc_binary` that "chooses" its deps based on the flags at the
command line. Specifically, `deps` becomes:
Command
deps =
`bazel build //myapp:mybinary --cpu=arm`
`[":arm_lib"]`
`bazel build //myapp:mybinary -c dbg --cpu=x86`
`[":x86_dev_lib"]`
`bazel build //myapp:mybinary --cpu=ppc`
`[":generic_lib"]`
`bazel build //myapp:mybinary -c dbg --cpu=ppc`
`[":generic_lib"]`
`select()` serves as a placeholder for a value that will be chosen based on
*configuration conditions*, which are labels referencing [`config_setting`](/reference/be/general#config_setting)
targets. By using `select()` in a configurable attribute, the attribute
effectively adopts different values when different conditions hold.
Matches must be unambiguous: if multiple conditions match then either
* They all resolve to the same value. For example, when running on linux x86, this is unambiguous
`{"@platforms//os:linux": "Hello", "@platforms//cpu:x86_64": "Hello"}` because both branches resolve to "hello".
* One's `values` is a strict superset of all others'. For example, `values = {"cpu": "x86", "compilation_mode": "dbg"}`
is an unambiguous specialization of `values = {"cpu": "x86"}`.
The built-in condition [`//conditions:default`](#default-condition) automatically matches when
nothing else does.
While this example uses `deps`, `select()` works just as well on `srcs`,
`resources`, `cmd`, and most other attributes. Only a small number of attributes
are *non-configurable*, and these are clearly annotated. For example,
`config_setting`'s own
[`values`](/reference/be/general#config_setting.values) attribute is non-configurable.
## `select()` and dependencies
Certain attributes change the build parameters for all transitive dependencies
under a target. For example, `genrule`'s `tools` changes `--cpu` to the CPU of
the machine running Bazel (which, thanks to cross-compilation, may be different
than the CPU the target is built for). This is known as a
[configuration transition](/reference/glossary#transition).
Given
```python theme={null}
#myapp/BUILD
config_setting(
name = "arm_cpu",
values = {"cpu": "arm"},
)
config_setting(
name = "x86_cpu",
values = {"cpu": "x86"},
)
genrule(
name = "my_genrule",
srcs = select({
":arm_cpu": ["g_arm.src"],
":x86_cpu": ["g_x86.src"],
}),
tools = select({
":arm_cpu": [":tool1"],
":x86_cpu": [":tool2"],
}),
)
cc_binary(
name = "tool1",
srcs = select({
":arm_cpu": ["armtool.cc"],
":x86_cpu": ["x86tool.cc"],
}),
)
```
running
```sh theme={null}
$ bazel build //myapp:my_genrule --cpu=arm
```
on an `x86` developer machine binds the build to `g_arm.src`, `tool1`, and
`x86tool.cc`. Both of the `select`s attached to `my_genrule` use `my_genrule`'s
build parameters, which include `--cpu=arm`. The `tools` attribute changes
`--cpu` to `x86` for `tool1` and its transitive dependencies. The `select` on
`tool1` uses `tool1`'s build parameters, which include `--cpu=x86`.
## Configuration conditions
Each key in a configurable attribute is a label reference to a
[`config_setting`](/reference/be/general#config_setting) or
[`constraint_value`](/reference/be/platforms-and-toolchains#constraint_value).
`config_setting` is just a collection of
expected command line flag settings. By encapsulating these in a target, it's
easy to maintain "standard" conditions users can reference from multiple places.
`constraint_value` provides support for [multi-platform behavior](#platforms).
### Built-in flags
Flags like `--cpu` are built into Bazel: the build tool natively understands
them for all builds in all projects. These are specified with
[`config_setting`](/reference/be/general#config_setting)'s
[`values`](/reference/be/general#config_setting.values) attribute:
```python theme={null}
config_setting(
name = "meaningful_condition_name",
values = {
"flag1": "value1",
"flag2": "value2",
...
},
)
```
`flagN` is a flag name (without `--`, so `"cpu"` instead of `"--cpu"`). `valueN`
is the expected value for that flag. `:meaningful_condition_name` matches if
*every* entry in `values` matches. Order is irrelevant.
`valueN` is parsed as if it was set on the command line. This means:
* `values = { "compilation_mode": "opt" }` matches `bazel build -c opt`
* `values = { "force_pic": "true" }` matches `bazel build --force_pic=1`
* `values = { "force_pic": "0" }` matches `bazel build --noforce_pic`
`config_setting` only supports flags that affect target behavior. For example,
[`--show_progress`](/docs/user-manual#show-progress) isn't allowed because
it only affects how Bazel reports progress to the user. Targets can't use that
flag to construct their results. The exact set of supported flags isn't
documented. In practice, most flags that "make sense" work.
### Custom flags
You can model your own project-specific flags with
[Starlark build settings][BuildSettings]. Unlike built-in flags, these are
defined as build targets, so Bazel references them with target labels.
These are triggered with [`config_setting`](/reference/be/general#config_setting)'s
[`flag_values`](/reference/be/general#config_setting.flag_values)
attribute:
```python theme={null}
config_setting(
name = "meaningful_condition_name",
flag_values = {
"//myflags:flag1": "value1",
"//myflags:flag2": "value2",
...
},
)
```
Behavior is the same as for [built-in flags](#built-in-flags). See [here](https://github.com/bazelbuild/examples/tree/HEAD/configurations/select_on_build_setting)
for a working example.
[`--define`](/reference/command-line-reference#flag--define)
is an alternative legacy syntax for custom flags (for example
`--define foo=bar`). This can be expressed either in the
[values](/reference/be/general#config_setting.values) attribute
(`values = {"define": "foo=bar"}`) or the
[define\_values](/reference/be/general#config_setting.define_values) attribute
(`define_values = {"foo": "bar"}`). `--define` is only supported for backwards
compatibility. Prefer Starlark build settings whenever possible.
`values`, `flag_values`, and `define_values` evaluate independently. The
`config_setting` matches if all values across all of them match.
## The default condition
The built-in condition `//conditions:default` matches when no other condition
matches.
Because of the "exactly one match" rule, a configurable attribute with no match
and no default condition emits a `"no matching conditions"` error. This can
protect against silent failures from unexpected settings:
```python theme={null}
# myapp/BUILD
config_setting(
name = "x86_cpu",
values = {"cpu": "x86"},
)
cc_library(
name = "x86_only_lib",
srcs = select({
":x86_cpu": ["lib.cc"],
}),
)
```
```sh theme={null}
$ bazel build //myapp:x86_only_lib --cpu=arm
ERROR: Configurable attribute "srcs" doesn't match this configuration (would
a default condition help?).
Conditions checked:
//myapp:x86_cpu
```
For even clearer errors, you can set custom messages with `select()`'s
[`no_match_error`](#custom-error-messages) attribute.
## Platforms
While the ability to specify multiple flags on the command line provides
flexibility, it can also be burdensome to individually set each one every time
you want to build a target.
[Platforms](/extending/platforms)
let you consolidate these into simple bundles.
```python theme={null}
# myapp/BUILD
sh_binary(
name = "my_rocks",
srcs = select({
":basalt": ["pyroxene.sh"],
":marble": ["calcite.sh"],
"//conditions:default": ["feldspar.sh"],
}),
)
config_setting(
name = "basalt",
constraint_values = [
":black",
":igneous",
],
)
config_setting(
name = "marble",
constraint_values = [
":white",
":metamorphic",
],
)
# constraint_setting acts as an enum type, and constraint_value as an enum value.
constraint_setting(name = "color")
constraint_value(name = "black", constraint_setting = "color")
constraint_value(name = "white", constraint_setting = "color")
constraint_setting(name = "texture")
constraint_value(name = "smooth", constraint_setting = "texture")
constraint_setting(name = "type")
constraint_value(name = "igneous", constraint_setting = "type")
constraint_value(name = "metamorphic", constraint_setting = "type")
platform(
name = "basalt_platform",
constraint_values = [
":black",
":igneous",
],
)
platform(
name = "marble_platform",
constraint_values = [
":white",
":smooth",
":metamorphic",
],
)
```
The platform can be specified on the command line. It activates the
`config_setting`s that contain a subset of the platform's `constraint_values`,
allowing those `config_setting`s to match in `select()` expressions.
For example, in order to set the `srcs` attribute of `my_rocks` to `calcite.sh`,
you can simply run
```sh theme={null}
bazel build //my_app:my_rocks --platforms=//myapp:marble_platform
```
Without platforms, this might look something like
```sh theme={null}
bazel build //my_app:my_rocks --define color=white --define texture=smooth --define type=metamorphic
```
`select()` can also directly read `constraint_value`s:
```python theme={null}
constraint_setting(name = "type")
constraint_value(name = "igneous", constraint_setting = "type")
constraint_value(name = "metamorphic", constraint_setting = "type")
sh_binary(
name = "my_rocks",
srcs = select({
":igneous": ["igneous.sh"],
":metamorphic" ["metamorphic.sh"],
}),
)
```
This saves the need for boilerplate `config_setting`s when you only need to
check against single values.
Platforms are still under development. See the
[documentation](/concepts/platforms) for details.
## Combining `select()`s
`select` can appear multiple times in the same attribute:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"] +
select({
":armeabi_mode": ["armeabi_src.sh"],
":x86_mode": ["x86_src.sh"],
}) +
select({
":opt_mode": ["opt_extras.sh"],
":dbg_mode": ["dbg_extras.sh"],
}),
)
```
Note: Some restrictions apply on what can be combined in the `select`s values:
* Duplicate labels can appear in different paths of the same `select`.
* Duplicate labels can *not* appear within the same path of a `select`.
* Duplicate labels can *not* appear across multiple combined `select`s (no matter what path)
`select` cannot appear inside another `select`. If you need to nest `selects`
and your attribute takes other targets as values, use an intermediate target:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":armeabi_mode": [":armeabi_lib"],
...
}),
)
sh_library(
name = "armeabi_lib",
srcs = select({
":opt_mode": ["armeabi_with_opt.sh"],
...
}),
)
```
If you need a `select` to match when multiple conditions match, consider [AND chaining](#and-chaining).
## OR chaining
Consider the following:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1": [":standard_lib"],
":config2": [":standard_lib"],
":config3": [":standard_lib"],
":config4": [":special_lib"],
}),
)
```
Most conditions evaluate to the same dep. But this syntax is hard to read and
maintain. It would be nice to not have to repeat `[":standard_lib"]` multiple
times.
One option is to predefine the value as a BUILD variable:
```python theme={null}
STANDARD_DEP = [":standard_lib"]
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1": STANDARD_DEP,
":config2": STANDARD_DEP,
":config3": STANDARD_DEP,
":config4": [":special_lib"],
}),
)
```
This makes it easier to manage the dependency. But it still causes unnecessary
duplication.
For more direct support, use one of the following:
### `selects.with_or`
The
[with\_or](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectswith_or)
macro in [Skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`selects`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md)
module supports `OR`ing conditions directly inside a `select`:
```python theme={null}
load("@bazel_skylib//lib:selects.bzl", "selects")
```
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = selects.with_or({
(":config1", ":config2", ":config3"): [":standard_lib"],
":config4": [":special_lib"],
}),
)
```
### `selects.config_setting_group`
The
[config\_setting\_group](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectsconfig_setting_group)
macro in [Skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`selects`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md)
module supports `OR`ing multiple `config_setting`s:
```python theme={null}
load("@bazel_skylib//lib:selects.bzl", "selects")
```
```python theme={null}
config_setting(
name = "config1",
values = {"cpu": "arm"},
)
config_setting(
name = "config2",
values = {"compilation_mode": "dbg"},
)
selects.config_setting_group(
name = "config1_or_2",
match_any = [":config1", ":config2"],
)
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1_or_2": [":standard_lib"],
"//conditions:default": [":other_lib"],
}),
)
```
Unlike `selects.with_or`, different targets can share `:config1_or_2` across
different attributes.
It's an error for multiple conditions to match unless one is an unambiguous
"specialization" of the others or they all resolve to the same value. See [here](#configurable-build-example) for details.
## AND chaining
If you need a `select` branch to match when multiple conditions match, use the
[Skylib](https://github.com/bazelbuild/bazel-skylib) macro
[config\_setting\_group](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectsconfig_setting_group):
```python theme={null}
config_setting(
name = "config1",
values = {"cpu": "arm"},
)
config_setting(
name = "config2",
values = {"compilation_mode": "dbg"},
)
selects.config_setting_group(
name = "config1_and_2",
match_all = [":config1", ":config2"],
)
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1_and_2": [":standard_lib"],
"//conditions:default": [":other_lib"],
}),
)
```
Unlike OR chaining, existing `config_setting`s can't be directly `AND`ed
inside a `select`. You have to explicitly wrap them in a `config_setting_group`.
## Custom error messages
By default, when no condition matches, the target the `select()` is attached to
fails with the error:
```sh theme={null}
ERROR: Configurable attribute "deps" doesn't match this configuration (would
a default condition help?).
Conditions checked:
//tools/cc_target_os:darwin
//tools/cc_target_os:android
```
This can be customized with the [`no_match_error`](/reference/be/functions#select)
attribute:
```python theme={null}
cc_library(
name = "my_lib",
deps = select(
{
"//tools/cc_target_os:android": [":android_deps"],
"//tools/cc_target_os:windows": [":windows_deps"],
},
no_match_error = "Please build with an Android or Windows toolchain",
),
)
```
```sh theme={null}
$ bazel build //myapp:my_lib
ERROR: Configurable attribute "deps" doesn't match this configuration: Please
build with an Android or Windows toolchain
```
## Rules compatibility
Rule implementations receive the *resolved values* of configurable
attributes. For example, given:
```python theme={null}
# myapp/BUILD
some_rule(
name = "my_target",
some_attr = select({
":foo_mode": [":foo"],
":bar_mode": [":bar"],
}),
)
```
```sh theme={null}
$ bazel build //myapp/my_target --define mode=foo
```
Rule implementation code sees `ctx.attr.some_attr` as `[":foo"]`.
Macros can accept `select()` clauses and pass them through to native
rules. But *they cannot directly manipulate them*. For example, there's no way
for a macro to convert
```python theme={null}
select({"foo": "val"}, ...)
```
to
```python theme={null}
select({"foo": "val_with_suffix"}, ...)
```
This is for two reasons.
First, macros that need to know which path a `select` will choose *cannot work*
because macros are evaluated in Bazel's [loading phase](/run/build#loading),
which occurs before flag values are known.
This is a core Bazel design restriction that's unlikely to change any time soon.
Second, macros that just need to iterate over *all* `select` paths, while
technically feasible, lack a coherent UI. Further design is necessary to change
this.
## Bazel query and cquery
Bazel [`query`](/query/guide) operates over Bazel's
[loading phase](/reference/glossary#loading-phase).
This means it doesn't know what command line flags a target uses since those
flags aren't evaluated until later in the build (in the
[analysis phase](/reference/glossary#analysis-phase)).
So it can't determine which `select()` branches are chosen.
Bazel [`cquery`](/query/cquery) operates after Bazel's analysis phase, so it has
all this information and can accurately resolve `select()`s.
Consider:
```python theme={null}
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
```
```python theme={null}
# myapp/BUILD
string_flag(
name = "dog_type",
build_setting_default = "cat"
)
cc_library(
name = "my_lib",
deps = select({
":long": [":foo_dep"],
":short": [":bar_dep"],
}),
)
config_setting(
name = "long",
flag_values = {":dog_type": "dachshund"},
)
config_setting(
name = "short",
flag_values = {":dog_type": "pug"},
)
```
`query` overapproximates `:my_lib`'s dependencies:
```sh theme={null}
$ bazel query 'deps(//myapp:my_lib)'
//myapp:my_lib
//myapp:foo_dep
//myapp:bar_dep
```
while `cquery` shows its exact dependencies:
```sh theme={null}
$ bazel cquery 'deps(//myapp:my_lib)' --//myapp:dog_type=pug
//myapp:my_lib
//myapp:bar_dep
```
## FAQ
### Why doesn't select() work in macros?
select() *does* work in rules! See [Rules compatibility](#rules-compatibility) for
details.
The key issue this question usually means is that select() doesn't work in
*macros*. These are different than *rules*. See the
documentation on [rules](/extending/rules) and [macros](/extending/macros)
to understand the difference.
Here's an end-to-end example:
Define a rule and macro:
```python theme={null}
# myapp/defs.bzl
# Rule implementation: when an attribute is read, all select()s have already
# been resolved. So it looks like a plain old attribute just like any other.
def _impl(ctx):
name = ctx.attr.name
allcaps = ctx.attr.my_config_string.upper() # This works fine on all values.
print("My name is " + name + " with custom message: " + allcaps)
# Rule declaration:
my_custom_bazel_rule = rule(
implementation = _impl,
attrs = {"my_config_string": attr.string()},
)
# Macro declaration:
def my_custom_bazel_macro(name, my_config_string):
allcaps = my_config_string.upper() # This line won't work with select(s).
print("My name is " + name + " with custom message: " + allcaps)
```
Instantiate the rule and macro:
```python theme={null}
# myapp/BUILD
load("//myapp:defs.bzl", "my_custom_bazel_rule")
load("//myapp:defs.bzl", "my_custom_bazel_macro")
my_custom_bazel_rule(
name = "happy_rule",
my_config_string = select({
"//third_party/bazel_platforms/cpu:x86_32": "first string",
"//third_party/bazel_platforms/cpu:ppc": "second string",
}),
)
my_custom_bazel_macro(
name = "happy_macro",
my_config_string = "fixed string",
)
my_custom_bazel_macro(
name = "sad_macro",
my_config_string = select({
"//third_party/bazel_platforms/cpu:x86_32": "first string",
"//third_party/bazel_platforms/cpu:ppc": "other string",
}),
)
```
Building fails because `sad_macro` can't process the `select()`:
```sh theme={null}
$ bazel build //myapp:all
ERROR: /myworkspace/myapp/BUILD:17:1: Traceback
(most recent call last):
File "/myworkspace/myapp/BUILD", line 17
my_custom_bazel_macro(name = "sad_macro", my_config_stri..."}))
File "/myworkspace/myapp/defs.bzl", line 4, in
my_custom_bazel_macro
my_config_string.upper()
type 'select' has no method upper().
ERROR: error loading package 'myapp': Package 'myapp' contains errors.
```
Building succeeds when you comment out `sad_macro`:
```sh theme={null}
# Comment out sad_macro so it doesn't mess up the build.
$ bazel build //myapp:all
DEBUG: /myworkspace/myapp/defs.bzl:5:3: My name is happy_macro with custom message: FIXED STRING.
DEBUG: /myworkspace/myapp/hi.bzl:15:3: My name is happy_rule with custom message: FIRST STRING.
```
This is impossible to change because *by definition* macros are evaluated before
Bazel reads the build's command line flags. That means there isn't enough
information to evaluate select()s.
Macros can, however, pass `select()`s as opaque blobs to rules:
```python theme={null}
# myapp/defs.bzl
def my_custom_bazel_macro(name, my_config_string):
print("Invoking macro " + name)
my_custom_bazel_rule(
name = name + "_as_target",
my_config_string = my_config_string,
)
```
```sh theme={null}
$ bazel build //myapp:sad_macro_less_sad
DEBUG: /myworkspace/myapp/defs.bzl:23:3: Invoking macro sad_macro_less_sad.
DEBUG: /myworkspace/myapp/defs.bzl:15:3: My name is sad_macro_less_sad with custom message: FIRST STRING.
```
### Why does select() always return true?
Because *macros* (but not rules) by definition
[can't evaluate `select()`s](#faq-select-macro), any attempt to do so
usually produces an error:
```sh theme={null}
ERROR: /myworkspace/myapp/BUILD:17:1: Traceback
(most recent call last):
File "/myworkspace/myapp/BUILD", line 17
my_custom_bazel_macro(name = "sad_macro", my_config_stri..."}))
File "/myworkspace/myapp/defs.bzl", line 4, in
my_custom_bazel_macro
my_config_string.upper()
type 'select' has no method upper().
```
Booleans are a special case that fail silently, so you should be particularly
vigilant with them:
```sh theme={null}
$ cat myapp/defs.bzl
def my_boolean_macro(boolval):
print("TRUE" if boolval else "FALSE")
$ cat myapp/BUILD
load("//myapp:defs.bzl", "my_boolean_macro")
my_boolean_macro(
boolval = select({
"//third_party/bazel_platforms/cpu:x86_32": True,
"//third_party/bazel_platforms/cpu:ppc": False,
}),
)
$ bazel build //myapp:all --cpu=x86
DEBUG: /myworkspace/myapp/defs.bzl:4:3: TRUE.
$ bazel build //mypro:all --cpu=ppc
DEBUG: /myworkspace/myapp/defs.bzl:4:3: TRUE.
```
This happens because macros don't understand the contents of `select()`.
So what they're really evaluting is the `select()` object itself. According to
[Pythonic](https://docs.python.org/release/2.5.2/lib/truth.html) design
standards, all objects aside from a very small number of exceptions
automatically return true.
### Can I read select() like a dict?
Macros [can't](#faq-select-macro) evaluate select(s) because macros evaluate before
Bazel knows what the build's command line parameters are. Can they at least read
the `select()`'s dictionary to, for example, add a suffix to each value?
Conceptually this is possible, but it isn't yet a Bazel feature.
What you *can* do today is prepare a straight dictionary, then feed it into a
`select()`:
```sh theme={null}
$ cat myapp/defs.bzl
def selecty_genrule(name, select_cmd):
for key in select_cmd.keys():
select_cmd[key] += " WITH SUFFIX"
native.genrule(
name = name,
outs = [name + ".out"],
srcs = [],
cmd = "echo " + select(select_cmd + {"//conditions:default": "default"})
+ " > $@"
)
$ cat myapp/BUILD
selecty_genrule(
name = "selecty",
select_cmd = {
"//third_party/bazel_platforms/cpu:x86_32": "x86 mode",
},
)
$ bazel build //testapp:selecty --cpu=x86 && cat bazel-genfiles/testapp/selecty.out
x86 mode WITH SUFFIX
```
If you'd like to support both `select()` and native types, you can do this:
```sh theme={null}
$ cat myapp/defs.bzl
def selecty_genrule(name, select_cmd):
cmd_suffix = ""
if type(select_cmd) == "string":
cmd_suffix = select_cmd + " WITH SUFFIX"
elif type(select_cmd) == "dict":
for key in select_cmd.keys():
select_cmd[key] += " WITH SUFFIX"
cmd_suffix = select(select_cmd + {"//conditions:default": "default"})
native.genrule(
name = name,
outs = [name + ".out"],
srcs = [],
cmd = "echo " + cmd_suffix + "> $@",
)
```
### Why doesn't select() work with bind()?
First of all, do not use `bind()`. It is deprecated in favor of `alias()`.
The technical answer is that [`bind()`](/reference/be/workspace#bind) is a repo
rule, not a BUILD rule.
Repo rules do not have a specific configuration, and aren't evaluated in
the same way as BUILD rules. Therefore, a `select()` in a `bind()` can't
actually evaluate to any specific branch.
Instead, you should use [`alias()`](/reference/be/general#alias), with a `select()` in
the `actual` attribute, to perform this type of run-time determination. This
works correctly, since `alias()` is a BUILD rule, and is evaluated with a
specific configuration.
```sh theme={null}
$ cat WORKSPACE
workspace(name = "myapp")
bind(name = "openssl", actual = "//:ssl")
http_archive(name = "alternative", ...)
http_archive(name = "boringssl", ...)
$ cat BUILD
config_setting(
name = "alt_ssl",
define_values = {
"ssl_library": "alternative",
},
)
alias(
name = "ssl",
actual = select({
"//:alt_ssl": "@alternative//:ssl",
"//conditions:default": "@boringssl//:ssl",
}),
)
```
With this setup, you can pass `--define ssl_library=alternative`, and any target
that depends on either `//:ssl` or `//external:ssl` will see the alternative
located at `@alternative//:ssl`.
But really, stop using `bind()`.
### Why doesn't my select() choose what I expect?
If `//myapp:foo` has a `select()` that doesn't choose the condition you expect,
use [cquery](/query/cquery) and `bazel config` to debug:
If `//myapp:foo` is the top-level target you're building, run:
```sh theme={null}
$ bazel cquery //myapp:foo
//myapp:foo (12e23b9a2b534a)
```
If you're building some other target `//bar` that depends on
//myapp:foo somewhere in its subgraph, run:
```sh theme={null}
$ bazel cquery 'somepath(//bar, //myapp:foo)'
//bar:bar (3ag3193fee94a2)
//bar:intermediate_dep (12e23b9a2b534a)
//myapp:foo (12e23b9a2b534a)
```
The `(12e23b9a2b534a)` next to `//myapp:foo` is a *hash* of the
configuration that resolves `//myapp:foo`'s `select()`. You can inspect its
values with `bazel config`:
```sh theme={null}
$ bazel config 12e23b9a2b534a
BuildConfigurationValue 12e23b9a2b534a
Fragment com.google.devtools.build.lib.analysis.config.CoreOptions {
cpu: darwin
compilation_mode: fastbuild
...
}
Fragment com.google.devtools.build.lib.rules.cpp.CppOptions {
linkopt: [-Dfoo=bar]
...
}
...
```
Then compare this output against the settings expected by each `config_setting`.
`//myapp:foo` may exist in different configurations in the same build. See the
[cquery docs](/query/cquery) for guidance on using `somepath` to get the right
one.
Caution: To prevent restarting the Bazel server, invoke `bazel config` with the
same command line flags as the `bazel cquery`. The `config` command relies on
the configuration nodes from the still-running server of the previous command.
### Why doesn't `select()` work with platforms?
Bazel doesn't support configurable attributes checking whether a given platform
is the target platform because the semantics are unclear.
For example:
```py theme={null}
platform(
name = "x86_linux_platform",
constraint_values = [
"@platforms//cpu:x86",
"@platforms//os:linux",
],
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":x86_linux_platform": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
In this `BUILD` file, which `select()` should be used if the target platform has both the
`@platforms//cpu:x86` and `@platforms//os:linux` constraints, but is **not** the
`:x86_linux_platform` defined here? The author of the `BUILD` file and the user
who defined the separate platform may have different ideas.
#### What should I do instead?
Instead, define a `config_setting` that matches **any** platform with
these constraints:
```py theme={null}
config_setting(
name = "is_x86_linux",
constraint_values = [
"@platforms//cpu:x86",
"@platforms//os:linux",
],
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":is_x86_linux": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
This process defines specific semantics, making it clearer to users what
platforms meet the desired conditions.
#### What if I really, really want to `select` on the platform?
If your build requirements specifically require checking the platform, you
can flip the value of the `--platforms` flag in a `config_setting`:
```py theme={null}
config_setting(
name = "is_specific_x86_linux_platform",
values = {
"platforms": ["//package:x86_linux_platform"],
},
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":is_specific_x86_linux_platform": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
The Bazel team doesn't endorse doing this; it overly constrains your build and
confuses users when the expected condition does not match.
[BuildSettings]: /extending/config#user-defined-build-settings
# Best Practices
Source: https://bazel.build/configure/best-practices
This page assumes you are familiar with Bazel and provides guidelines and
advice on structuring your projects to take full advantage of Bazel's features.
The overall goals are:
* To use fine-grained dependencies to allow parallelism and incrementality.
* To keep dependencies well-encapsulated.
* To make code well-structured and testable.
* To create a build configuration that is easy to understand and maintain.
These guidelines are not requirements: few projects will be able to adhere to
all of them. As the man page for lint says, "A special reward will be presented
to the first person to produce a real program that produces no errors with
strict checking." However, incorporating as many of these principles as possible
should make a project more readable, less error-prone, and faster to build.
This page uses the requirement levels described in
[this RFC](https://www.ietf.org/rfc/rfc2119.txt).
## Running builds and tests
A project should always be able to run `bazel build //...` and
`bazel test //...` successfully on its stable branch. Targets that are necessary
but do not build under certain circumstances (such as,require specific build
flags, don't build on a certain platform, require license agreements) should be
tagged as specifically as possible (for example, "`requires-osx`"). This
tagging allows targets to be filtered at a more fine-grained level than the
"manual" tag and allows someone inspecting the `BUILD` file to understand what
a target's restrictions are.
## Third-party dependencies
You may declare third-party dependencies:
* Either declare them as remote repositories in the `MODULE.bazel` file.
* Or put them in a directory called `third_party/` under your workspace directory.
## Depending on binaries
Everything should be built from source whenever possible. Generally this means
that, instead of depending on a library `some-library.so`, you'd create a
`BUILD` file and build `some-library.so` from its sources, then depend on that
target.
Always building from source ensures that a build is not using a library that
was built with incompatible flags or a different architecture. There are also
some features like coverage, static analysis, or dynamic analysis that only
work on the source.
## Versioning
Prefer building all code from head whenever possible. When versions must be
used, avoid including the version in the target name (for example, `//guava`,
not `//guava-20.0`). This naming makes the library easier to update (only one
target needs to be updated). It's also more resilient to diamond dependency
issues: if one library depends on `guava-19.0` and one depends on `guava-20.0`,
you could end up with a library that tries to depend on two different versions.
If you created a misleading alias to point both targets to one `guava` library,
then the `BUILD` files are misleading.
## Using the `.bazelrc` file
For project-specific options, use the configuration file your
`workspace/.bazelrc` (see [bazelrc format](/run/bazelrc)).
If you want to support per-user options for your project that you **do not**
want to check into source control, include the line:
```
try-import %workspace%/user.bazelrc
```
(or any other file name) in your `workspace/.bazelrc`
and add `user.bazelrc` to your `.gitignore`.
The open-source
[bazelrc-preset.bzl](https://github.com/bazel-contrib/bazelrc-preset.bzl)
generates a custom bazelrc file that matches your Bazel version and provides a
preset of recommended flags.
## Packages
Every directory that contains buildable files should be a package. If a `BUILD`
file refers to files in subdirectories (such as, `srcs = ["a/b/C.java"]`) it's
a sign that a `BUILD` file should be added to that subdirectory. The longer
this structure exists, the more likely circular dependencies will be
inadvertently created, a target's scope will creep, and an increasing number
of reverse dependencies will have to be updated.
# Code coverage with Bazel
Source: https://bazel.build/configure/coverage
Bazel features a `coverage` sub-command to produce code coverage
reports on repositories that can be tested with `bazel coverage`. Due
to the idiosyncrasies of the various language ecosystems, it is not
always trivial to make this work for a given project.
This page documents the general process for creating and viewing
coverage reports, and also features some language-specific notes for
languages whose configuration is well-known. It is best read by first
reading [the general section](#creating-a-coverage-report), and then
reading about the requirements for a specific language.
While a lot of customization is possible, this document focuses on
producing and consuming [`lcov`][lcov] reports, which is currently the
most well-supported route.
## Creating a coverage report
### Preparation
The basic workflow for creating coverage reports requires the
following:
* A basic repository with test targets
* A toolchain with the language-specific code coverage tools installed
* A correct "instrumentation" configuration
The former two are language-specific and mostly straightforward,
however the latter can be more difficult for complex projects.
"Instrumentation" in this case refers to the coverage tools that are
used for a specific target. Bazel allows turning this on for a
specific subset of files using the
[`--instrumentation_filter`](/reference/command-line-reference#flag--instrumentation_filter)
flag, which specifies a filter for targets that are tested with the
instrumentation enabled. To enable instrumentation for tests, the
[`--instrument_test_targets`](/reference/command-line-reference#flag--instrument_test_targets)
flag is required.
By default, bazel tries to match the target package(s), and prints the
relevant filter as an `INFO` message.
### Running coverage
To produce a coverage report, use [`bazel coverage --combined_report=lcov [target]`](/reference/command-line-reference#coverage). This runs the
tests for the target, generating coverage reports in the lcov format
for each file.
Once finished, bazel runs an action that collects all the produced
coverage files, and merges them into one, which is then finally
created under `$(bazel info
output_path)/_coverage/_coverage_report.dat`.
Coverage reports are also produced if tests fail, though note that
this does not extend to the failed tests - only passing tests are
reported.
### Viewing coverage
The coverage report is only output in the non-human-readable `lcov`
format. From this, we can use the `genhtml` utility (part of [the lcov
project][lcov]) to produce a report that can be viewed in a web
browser:
```console theme={null}
genhtml --branch-coverage --output genhtml "$(bazel info output_path)/_coverage/_coverage_report.dat"
```
Note that `genhtml` reads the source code as well, to annotate missing
coverage in these files. For this to work, it is expected that
`genhtml` is executed in the root of the bazel project.
To view the result, simply open the `index.html` file produced in the
`genhtml` directory in any web browser.
For further help and information around the `genhtml` tool, or the
`lcov` coverage format, see [the lcov project][lcov].
## Language-specific configuration
### C++
#### Linux
C++ coverage should work out-of-the-box with the default configuration.
#### MacOS
The default value of `GCOV_PREFIX_STRIP` is almost certainly incorrect and needs
adjusting manually because the correct value depends on your setup.
When the value is incorrect, no coverage data will be found.
Example to set `GCOV_PREFIX_STRIP=10`
```
bazel coverage //foo:foo_test --test_env=GCOV_PREFIX_STRIP=10`
```
### Java
Java should work out-of-the-box with the default configuration. The
[bazel toolchains][bazel_toolchains] contain everything necessary for
remote execution, as well, including JUnit.
### Python
See the [`rules_python` coverage docs](https://rules-python.readthedocs.io/en/latest/coverage.html)
for additional steps needed to enable coverage support in Python.
[lcov]: https://github.com/linux-test-project/lcov
[bazel_toolchains]: https://github.com/bazelbuild/bazel-toolchains
# Integrating with C++ Rules
Source: https://bazel.build/configure/integrate-cpp
This page describes how to integrate with C++ rules on various levels.
## Accessing the C++ toolchain
You should use the helper functions available at
[`@rules_cc//cc:find_cc_toolchain.bzl`](https://github.com/bazelbuild/rules_cc/blob/main/cc/find_cc_toolchain.bzl)
to depend on a CC toolchain from a Starlark rule.
To depend on a C++ toolchain in your rule, set the `toolchains` parameter to
`use_cc_toolchain()`. Then, in the rule implementation, use
`find_cpp_toolchain(ctx)` to get the
[`CcToolchainInfo`](/rules/lib/providers/CcToolchainInfo). A complete working
example can be found [in the rules\_cc examples](https://github.com/bazelbuild/rules_cc/blob/main/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl).
## Generating command lines and environment variables using the C++ toolchain
Typically, you would integrate with the C++ toolchain to have the same
command line flags as C++ rules do, but without using C++ actions directly.
This is because when writing our own actions, they must behave
consistently with the C++ toolchain - for example, passing C++ command line
flags to a tool that invokes the C++ compiler behind the scenes.
C++ rules use a special way of constructing command lines based on [feature configuration](/docs/cc-toolchain-config-reference). To construct a command line,
you need the following:
* `features` and `action_configs` - these come from the `CcToolchainConfigInfo`
and encapsulated in `CcToolchainInfo`
* `FeatureConfiguration` - returned by [cc\_common.configure\_features](/rules/lib/toplevel/cc_common#configure_features)
* cc toolchain config variables - returned by
[cc\_common.create\_compile\_variables](/rules/lib/toplevel/cc_common#create_compile_variables)
or
[cc\_common.create\_link\_variables](/rules/lib/toplevel/cc_common#create_link_variables).
There still are tool-specific getters, such as
[compiler\_executable](/rules/lib/providers/CcToolchainInfo#compiler_executable).
Prefer `get_tool_for_action` over these, as tool-specific getters will
eventually be removed.
A complete working example can be found
[in the rules\_cc examples](https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_compile/my_c_compile.bzl).
## Implementing Starlark rules that depend on C++ rules and/or that C++ rules can depend on
Most C++ rules provide
[`CcInfo`](/rules/lib/providers/CcInfo),
a provider containing [`CompilationContext`](/rules/lib/builtins/CompilationContext)
and
[`LinkingContext`](/rules/lib/builtins/LinkingContext).
Through these it is possible to access information such as all transitive headers
or libraries to link. From `CcInfo` and from the `CcToolchainInfo` custom
Starlark rules should be able to get all the information they need.
If a custom Starlark rule provides `CcInfo`, it's a signal to the C++ rules that
they can also depend on it. Be careful, however - if you only need to propagate
`CcInfo` through the graph to the binary rule that then makes use of it, wrap
`CcInfo` in a different provider. For example, if `java_library` rule wanted
to propagate native dependencies up to the `java_binary`, it shouldn't provide
`CcInfo` directly (`cc_binary` depending on `java_library` doesn't make sense),
it should wrap it in, for example, `JavaCcInfo`.
A complete working example can be found
[in the rules\_cc examples](https://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_archive/my_c_archive.bzl).
## Reusing logic and actions of C++ rules
*Not stable yet; This section will be updated once the API stabilizes. Follow
[#4570](https://github.com/bazelbuild/bazel/issues/4570) for up-to-date
information.*
# Using Bazel on Windows
Source: https://bazel.build/configure/windows
This page covers Best Practices for using Bazel on Windows. For installation
instructions, see [Install Bazel on Windows](/install/windows).
## Known issues
Windows-related Bazel issues are marked with the "area-Windows" label on GitHub.
[GitHub-Windows].
[GitHub-Windows]: https://github.com/bazelbuild/bazel/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-Windows
## Best practices
### Avoid long path issues
Some tools have the [Maximum Path Length Limitation](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation) on Windows, including the MSVC compiler.
To avoid hitting this issue, you can specify a short output directory for Bazel by the [--output\_user\_root](/reference/command-line-reference#flag--output_user_root) flag.
For example, add the following line to your bazelrc file:
```none theme={null}
startup --output_user_root=C:/tmp
```
### Enable symlink support
Some features require Bazel to be able to create file symlinks on Windows,
either by enabling
[Developer Mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development)
(on Windows 10 version 1703 or newer), or by running Bazel as an administrator.
This enables the following features:
* [--windows\_enable\_symlinks](/reference/command-line-reference#flag--windows_enable_symlinks)
* [--enable\_runfiles](/reference/command-line-reference#flag--enable_runfiles)
To make it easier, add the following lines to your bazelrc file:
```none theme={null}
startup --windows_enable_symlinks
build --enable_runfiles
```
**Note**: Creating symlinks on Windows is an expensive operation. The `--enable_runfiles` flag can potentially create a large amount of file symlinks. Only enable this feature when you need it.
### Running Bazel: MSYS2 shell vs. command prompt vs. PowerShell
**Recommendation:** Run Bazel from the command prompt (`cmd.exe`) or from
PowerShell.
As of 2020-01-15, **do not** run Bazel from `bash` -- either
from MSYS2 shell, or Git Bash, or Cygwin, or any other Bash variant. While Bazel
may work for most use cases, some things are broken, like
[interrupting the build with Ctrl+C from MSYS2](https://github.com/bazelbuild/bazel/issues/10573)).
Also, if you choose to run under MSYS2, you need to disable MSYS2's
automatic path conversion, otherwise MSYS will convert command line arguments
that *look like* Unix paths (such as `//foo:bar`) into Windows paths. See
[this StackOverflow answer](https://stackoverflow.com/a/49004265/7778502)
for details.
### Using Bazel without Bash (MSYS2)
#### Using bazel build without Bash
Bazel versions before 1.0 used to require Bash to build some rules.
Starting with Bazel 1.0, you can build any rule without Bash unless it is a:
* `genrule`, because genrules execute Bash commands
* `sh_binary` or `sh_test` rule, because these inherently need Bash
* Starlark rule that uses `ctx.actions.run_shell()` or `ctx.resolve_command()`
However, `genrule` is often used for simple tasks like
[copying a file](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/copy_file.bzl)
or [writing a text file](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/write_file.bzl).
Instead of using `genrule` (and depending on Bash) you may find a suitable rule
in the
[bazel-skylib repository](https://github.com/bazelbuild/bazel-skylib/tree/main/rules).
When built on Windows, **these rules do not require Bash**.
#### Using bazel test without Bash
Bazel versions before 1.0 used to require Bash to `bazel test` anything.
Starting with Bazel 1.0, you can test any rule without Bash, except when:
* you use `--run_under`
* the test rule itself requires Bash (because its executable is a shell script)
#### Using bazel run without Bash
Bazel versions before 1.0 used to require Bash to `bazel run` anything.
Starting with Bazel 1.0, you can run any rule without Bash, except when:
* you use `--run_under` or `--script_path`
* the test rule itself requires Bash (because its executable is a shell script)
#### Using sh\_binary and sh\_\* rules, and ctx.actions.run\_shell() without Bash
You need Bash to build and test `sh_*` rules, and to build and test Starlark
rules that use `ctx.actions.run_shell()` and `ctx.resolve_command()`. This
applies not only to rules in your project, but to rules in any of the external
repositories your project depends on (even transitively).
In the future, there may be an option to use Windows Subsystem for
Linux (WSL) to build these rules, but currently it is not a priority for
the Bazel-on-Windows subteam.
### Setting environment variables
Environment variables you set in the Windows Command Prompt (`cmd.exe`) are only
set in that command prompt session. If you start a new `cmd.exe`, you need to
set the variables again. To always set the variables when `cmd.exe` starts, you
can add them to the User variables or System variables in the `Control Panel >
System Properties > Advanced > Environment Variables...` dialog box.
## Build on Windows
### Build C++ with MSVC
To build C++ targets with MSVC, you need:
* [The Visual C++ compiler](/install/windows#install-vc).
* (Optional) The `BAZEL_VC` and `BAZEL_VC_FULL_VERSION` environment variable.
Bazel automatically detects the Visual C++ compiler on your system.
To tell Bazel to use a specific VC installation, you can set the
following environment variables:
For Visual Studio 2017 and 2019, set one of `BAZEL_VC`. Additionally you may also set `BAZEL_VC_FULL_VERSION`.
* `BAZEL_VC` the Visual C++ Build Tools installation directory
```
set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
```
* `BAZEL_VC_FULL_VERSION` (Optional) Only for Visual Studio 2017 and 2019, the full version
number of your Visual C++ Build Tools. You can choose the exact Visual C++ Build Tools
version via `BAZEL_VC_FULL_VERSION` if more than one version are installed, otherwise Bazel
will choose the latest version.
```
set BAZEL_VC_FULL_VERSION=14.16.27023
```
For Visual Studio 2015 or older, set `BAZEL_VC`. (`BAZEL_VC_FULL_VERSION` is not supported.)
* `BAZEL_VC` the Visual C++ Build Tools installation directory
```
set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
```
* The [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk).
The Windows SDK contains header files and libraries you need when building
Windows applications, including Bazel itself. By default, the latest Windows SDK installed will
be used. You also can specify Windows SDK version by setting `BAZEL_WINSDK_FULL_VERSION`. You
can use a full Windows 10 SDK number such as 10.0.10240.0, or specify 8.1 to use the Windows 8.1
SDK (only one version of Windows 8.1 SDK is available). Please make sure you have the specified
Windows SDK installed.
**Requirement**: This is supported with VC 2017 and 2019. The standalone VC 2015 Build Tools doesn't
support selecting Windows SDK, you'll need the full Visual Studio 2015 installation, otherwise
`BAZEL_WINSDK_FULL_VERSION` will be ignored.
```
set BAZEL_WINSDK_FULL_VERSION=10.0.10240.0
```
If everything is set up, you can build a C++ target now!
Try building a target from one of our [sample projects](https://github.com/bazelbuild/bazel/tree/master/examples):
```
bazel build //examples/cpp:hello-worldbazel-bin\examples\cpp\hello-world.exe
```
By default, the built binaries target x64 architecture. To build for ARM64
architecture, use
```none theme={null}
--platforms=//:windows_arm64 --extra_toolchains=@local_config_cc//:cc-toolchain-arm64_windows
```
You can introduce `@local_config_cc` in `MODULE.bazel` with
```python theme={null}
bazel_dep(name = "rules_cc", version = "0.1.1")
cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension")
use_repo(cc_configure, "local_config_cc")
```
To build and use Dynamically Linked Libraries (DLL files), see [this example](https://github.com/bazelbuild/bazel/tree/master/examples/windows/dll).
**Command Line Length Limit**: To prevent the
[Windows command line length limit issue](https://github.com/bazelbuild/bazel/issues/5163),
enable the compiler parameter file feature via `--features=compiler_param_file`.
### Build C++ with Clang
From 0.29.0, Bazel supports building with LLVM's MSVC-compatible compiler driver (`clang-cl.exe`).
**Requirement**: To build with Clang, you have to install **both**
[LLVM](http://releases.llvm.org/download.html) and Visual C++ Build tools,
because although you use `clang-cl.exe` as compiler, you still need to link to
Visual C++ libraries.
Bazel can automatically detect LLVM installation on your system, or you can explicitly tell
Bazel where LLVM is installed by `BAZEL_LLVM`.
* `BAZEL_LLVM` the LLVM installation directory
```posix-terminal theme={null}
set BAZEL_LLVM=C:\Program Files\LLVM
```
To enable the Clang toolchain, the configuration depends on your Bazel version
and whether you are using Bzlmod or WORKSPACE.
***
**Bazel 8 and newer:**
* **Using Bzlmod (Recommended):**
1. Ensure you have `rules_cc` loaded in your `MODULE.bazel` and configure
the CC toolchains:
```python theme={null}
bazel_dep(name = "rules_cc", version = "0.0.17") # Or newer
cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension")
use_repo(cc_configure, "local_config_cc")
```
2. Define a `platform` target in a BUILD file (e.g., the root BUILD file):
```python theme={null}
platform(
name = "x64_windows-clang-cl",
constraint_values = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
"@bazel_tools//tools/cpp:clang-cl", # Alias to the @rules_cc constraint in Bazel 8+
],
)
```
3. Enable the toolchain using these flags:
```bash theme={null}
--extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
```
* **Using WORKSPACE:**
1. Load the `rules_cc` dependencies and toolchains in your `WORKSPACE` file
:
```python theme={null}
load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies", "rules_cc_toolchains")
rules_cc_dependencies()
rules_cc_toolchains()
```
2. Define a `platform` target in a BUILD file (e.g., the root BUILD file):
```python theme={null}
platform(
name = "x64_windows-clang-cl",
constraint_values = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
"@bazel_tools//tools/cpp:clang-cl", # Alias to the @rules_cc constraint in Bazel 8+
],
)
```
3. Enable the toolchain using these flags:
```bash theme={null}
--extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
```
***
**Bazel 7:**
**Note:** In Bazel 7, `@bazel_tools//tools/cpp:clang-cl` is *not* an alias for
the `@rules_cc` constraint. To correctly use `clang-cl` with `rules_cc` in Bazel
7, you must reference a constraint within the `@rules_cc` repository. The label
`@rules_cc//cc/private/toolchain:clang-cl` is technically private but is
necessary for consistent behavior between WORKSPACE and Bzlmod setups in Bazel
7\.
* **Using Bzlmod:**
1. Setup `MODULE.bazel` as in the Bazel 8 example.
2. Define the `platform` target using the `@rules_cc` private constraint:
```python theme={null}
platform(
name = "x64_windows-clang-cl",
constraint_values = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
"@rules_cc//cc/private/toolchain:clang-cl", # Necessary for Bazel 7
],
)
```
3. Enable the toolchain using these flags:
```bash theme={null}
--extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
```
* **Using WORKSPACE:**
1. Load the `rules_cc` dependencies and toolchains in your `WORKSPACE` file
:
```python theme={null}
load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies", "rules_cc_toolchains")
rules_cc_dependencies()
rules_cc_toolchains()
```
2. Define the `platform` target using the `@rules_cc` private constraint:
```python theme={null}
platform(
name = "x64_windows-clang-cl",
constraint_values = [
"@platforms//cpu:x86_64",
"@platforms//os:windows",
"@rules_cc//cc/private/toolchain:clang-cl", # Necessary for Bazel 7
],
)
```
3. Enable the toolchain using these flags:
```bash theme={null}
--extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
```
***
**Bazel 0.29 to 6.x:**
* Enable the Clang toolchain by
a build flag `--compiler=clang-cl`.
* If your build sets the flag
[--incompatible\_enable\_cc\_toolchain\_resolution](https://github.com/bazelbuild/bazel/issues/7260)
to `true`, then use the approach for Bazel 7.0.0.
**Bazel 0.28 and older:**
* Clang is not supported.
### Build Java
To build Java targets, you need:
* [The Java SE Development Kit](/install/windows#install-jdk)
On Windows, Bazel builds two output files for `java_binary` rules:
* a `.jar` file
* a `.exe` file that can set up the environment for the JVM and run the binary
Try building a target from one of our [sample projects](https://github.com/bazelbuild/bazel/tree/master/examples):
```
bazel build //examples/java-native/src/main/java/com/example/myproject:hello-worldbazel-bin\examples\java-native\src\main\java\com\example\myproject\hello-world.exe
```
### Build Python
To build Python targets, you need:
* The [Python interpreter](/install/windows#install-python)
On Windows, Bazel builds two output files for `py_binary` rules:
* a self-extracting zip file
* an executable file that can launch the Python interpreter with the
self-extracting zip file as the argument
You can either run the executable file (it has a `.exe` extension) or you can run
Python with the self-extracting zip file as the argument.
Try building a target from one of our [sample projects](https://github.com/bazelbuild/bazel/tree/master/examples):
```
bazel build //examples/py_native:binbazel-bin\examples\py_native\bin.exepython bazel-bin\examples\py_native\bin.zip
```
If you are interested in details about how Bazel builds Python targets on
Windows, check out this [design doc](https://github.com/bazelbuild/bazel-website/blob/master/designs/_posts/2016-09-05-build-python-on-windows.md).
# Android Build Performance
Source: https://bazel.build/docs/android-build-performance
This page contains information on optimizing build performance for Android
apps specifically. For general build performance optimization with Bazel, see
[Optimizing Performance](/rules/performance).
## Recommended flags
The flags are in the
[`bazelrc` configuration syntax](/run/bazelrc#bazelrc-syntax-semantics), so
they can be pasted directly into a `bazelrc` file and invoked with
`--config=` on the command line.
**Profiling performance**
Bazel writes a JSON trace profile by default to a file called
`command.profile.gz` in Bazel's output base.
See the [JSON Profile documentation](/rules/performance#performance-profiling) for
how to read and interact with the profile.
**Persistent workers for Android build actions**.
A subset of Android build actions has support for
[persistent workers](https://blog.bazel.build/2015/12/10/java-workers.html).
These actions' mnemonics are:
* DexBuilder
* Javac
* Desugar
* AaptPackage
* AndroidResourceParser
* AndroidResourceValidator
* AndroidResourceCompiler
* RClassGenerator
* AndroidResourceLink
* AndroidAapt2
* AndroidAssetMerger
* AndroidResourceMerger
* AndroidCompiledResourceMerger
Enabling workers can result in better build performance by saving on JVM
startup costs from invoking each of these tools, but at the cost of increased
memory usage on the system by persisting them.
To enable workers for these actions, apply these flags with
`--config=android_workers` on the command line:
```
build:android_workers --strategy=DexBuilder=worker
build:android_workers --strategy=Javac=worker
build:android_workers --strategy=Desugar=worker
# A wrapper flag for these resource processing actions:
# - AndroidResourceParser
# - AndroidResourceValidator
# - AndroidResourceCompiler
# - RClassGenerator
# - AndroidResourceLink
# - AndroidAapt2
# - AndroidAssetMerger
# - AndroidResourceMerger
# - AndroidCompiledResourceMerger
build:android_workers --persistent_android_resource_processor
```
The default number of persistent workers created per action is `4`. We have
[measured improved build performance](https://github.com/bazelbuild/bazel/issues/8586#issuecomment-500070549)
by capping the number of instances for each action to `1` or `2`, although this
may vary depending on the system Bazel is running on, and the project being
built.
To cap the number of instances for an action, apply these flags:
```
build:android_workers --worker_max_instances=DexBuilder=2
build:android_workers --worker_max_instances=Javac=2
build:android_workers --worker_max_instances=Desugar=2
build:android_workers --worker_max_instances=AaptPackage=2
# .. and so on for each action you're interested in.
```
**Using AAPT2**
[`aapt2`](https://developer.android.com/studio/command-line/aapt2) has improved
performance over `aapt` and also creates smaller APKs. To use `aapt2`, use the
`--android_aapt=aapt2` flag or set `aapt2` on the `aapt_version` on
`android_binary` and `android_local_test`.
**SSD optimizations**
The `--experimental_multi_threaded_digest` flag is useful for optimizing digest
computation on SSDs.
# Android Instrumentation Tests
Source: https://bazel.build/docs/android-instrumentation-test
*If you're new to Bazel, start with the [Building Android with Bazel](/start/android-app) tutorial.*

**Figure 1.** Running parallel Android instrumentation tests.
[`android_instrumentation_test`](/reference/be/android#android_instrumentation_test)
allows developers to test their apps on Android emulators and devices.
It utilizes real Android framework APIs and the Android Test Library.
For hermeticity and reproducibility, Bazel creates and launches Android
emulators in a sandbox, ensuring that tests always run from a clean state. Each
test gets an isolated emulator instance, allowing tests to run in parallel
without passing states between them.
For more information on Android instrumentation tests, check out the [Android developer documentation](https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html).
Please file issues in the [GitHub issue tracker](https://github.com/bazelbuild/bazel/issues).
## How it works
When you run `bazel test` on an `android_instrumentation_test` target for the
first time, Bazel performs the following steps:
1. Builds the test APK, APK under test, and their transitive dependencies
2. Creates, boots, and caches clean emulator states
3. Starts the emulator
4. Installs the APKs
5. Runs tests utilizing the [Android Test Orchestrator](https://developer.android.com/training/testing/junit-runner.html#using-android-test-orchestrator)
6. Shuts down the emulator
7. Reports the results
In subsequent test runs, Bazel boots the emulator from the clean, cached state
created in step 2, so there are no leftover states from previous runs. Caching
emulator state also speeds up test runs.
## Prerequisites
Ensure your environment satisfies the following prerequisites:
* **Linux**. Tested on Ubuntu 16.04, and 18.04.
* **Bazel 0.12.0** or later. Verify the version by running `bazel info release`.
```posix-terminal theme={null}
bazel info release
```
This results in output similar to the following:
```none theme={null}
release 4.1.0
```
* **KVM**. Bazel requires emulators to have [hardware acceleration](https://developer.android.com/studio/run/emulator-acceleration.html#accel-check)
with KVM on Linux. You can follow these
[installation instructions](https://help.ubuntu.com/community/KVM/Installation)
for Ubuntu.
To verify that KVM has the correct configuration, run:
```posix-terminal theme={null}
apt-get install cpu-checker && kvm-ok
```
If it prints the following message, you have the correct configuration:
```none theme={null}
INFO: /dev/kvm exists
KVM acceleration can be used
```
* **Xvfb**. To run headless tests (for example, on CI servers), Bazel requires
the [X virtual framebuffer](https://www.x.org/archive/X11R7.6/doc/man/man1/Xvfb.1.xhtml).
To install it, run:
```posix-terminal theme={null}
apt-get install xvfb
```
Verify that `Xvfb` is installed correctly and is installed at `/usr/bin/Xvfb`
by running:
```posix-terminal theme={null}
which Xvfb
```
The output is the following:
```
/usr/bin/Xvfb
```
* **32-bit Libraries**. Some of the binaries used by the test infrastructure are
32-bit, so on 64-bit machines, ensure that 32-bit binaries can be run. For
Ubuntu, install these 32-bit libraries:
```posix-terminal theme={null}
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386
```
## Getting started
Here is a typical target dependency graph of an `android_instrumentation_test`:

**Figure 2.** Target dependency graph of an `android_instrumentation_test`.
### BUILD file
The graph translates into a `BUILD` file like this:
```python theme={null}
android_instrumentation_test(
name = "my_test",
test_app = ":my_test_app",
target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86",
)
# Test app and library
android_binary(
name = "my_test_app",
instruments = ":my_app",
manifest = "AndroidTestManifest.xml",
deps = [":my_test_lib"],
# ...
)
android_library(
name = "my_test_lib",
srcs = glob(["javatest/**/*.java"]),
deps = [
":my_app_lib",
"@maven//:androidx_test_core",
"@maven//:androidx_test_runner",
"@maven//:androidx_test_espresso_espresso_core",
],
# ...
)
# Target app and library under test
android_binary(
name = "my_app",
manifest = "AndroidManifest.xml",
deps = [":my_app_lib"],
# ...
)
android_library(
name = "my_app_lib",
srcs = glob(["java/**/*.java"]),
deps = [
"@maven//:androidx_appcompat_appcompat",
"@maven//:androidx_annotation_annotation",
]
# ...
)
```
The main attributes of the rule `android_instrumentation_test` are:
* `test_app`: An `android_binary` target. This target contains test code and
dependencies like Espresso and UIAutomator. The selected `android_binary`
target is required to specify an `instruments` attribute pointing to another
`android_binary`, which is the app under test.
* `target_device`: An `android_device` target. This target describes the
specifications of the Android emulator which Bazel uses to create, launch and
run the tests. See the [section on choosing an Android device](#android-device-target) for more information.
The test app's `AndroidManifest.xml` must include [an `` tag](https://developer.android.com/studio/test/#configure_instrumentation_manifest_settings).
This tag must specify the attributes for the **package of the target app** and
the **fully qualified class name of the instrumentation test runner**,
`androidx.test.runner.AndroidJUnitRunner`.
Here is an example `AndroidTestManifest.xml` for the test app:
```xml theme={null}
```
### WORKSPACE dependencies
In order to use this rule, your project needs to depend on these external
repositories:
* `@androidsdk`: The Android SDK. Download this through Android Studio.
* `@android_test_support`: Hosts the test runner, emulator launcher, and
`android_device` targets. You can find the [latest release here](https://github.com/android/android-test/releases).
Enable these dependencies by adding the following lines to your `WORKSPACE`
file:
```python theme={null}
# Android SDK
android_sdk_repository(
name = "androidsdk",
path = "/path/to/sdk", # or set ANDROID_HOME
)
# Android Test Support
ATS_COMMIT = "$COMMIT_HASH"
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "android_test_support",
strip_prefix = "android-test-%s" % ATS_COMMIT,
urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_COMMIT],
)
load("@android_test_support//:repo.bzl", "android_test_repositories")
android_test_repositories()
```
## Maven dependencies
For managing dependencies on Maven artifacts from repositories, such as [Google Maven](https://maven.google.com) or [Maven Central](https://central.maven.org),
you should use a Maven resolver, such as
[`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external).
The rest of this page shows how to use `rules_jvm_external` to
resolve and fetch dependencies from Maven repositories.
## Choosing an android\_device target
`android_instrumentation_test.target_device` specifies which Android device to
run the tests on. These `android_device` targets are defined in
[`@android_test_support`](https://github.com/google/android-testing-support-library/tree/master/tools/android/emulated_devices).
For example, you can query for the sources for a particular target by running:
```posix-terminal theme={null}
bazel query --output=build @android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86
```
Which results in output that looks similar to:
```python theme={null}
# .../external/android_test_support/tools/android/emulated_devices/generic_phone/BUILD:43:1
android_device(
name = "android_23_x86",
visibility = ["//visibility:public"],
tags = ["requires-kvm"],
generator_name = "generic_phone",
generator_function = "make_device",
generator_location = "tools/android/emulated_devices/generic_phone/BUILD:43",
vertical_resolution = 800,
horizontal_resolution = 480,
ram = 2048,
screen_density = 240,
cache = 32,
vm_heap = 256,
system_image = "@android_test_support//tools/android/emulated_devices/generic_phone:android_23_x86_images",
default_properties = "@android_test_support//tools/android/emulated_devices/generic_phone:_android_23_x86_props",
)
```
The device target names use this template:
```
@android_test_support//tools/android/emulated_devices/device_type:system_api_level_x86_qemu2
```
In order to launch an `android_device`, the `system_image` for the selected API
level is required. To download the system image, use Android SDK's
`tools/bin/sdkmanager`. For example, to download the system image for
`generic_phone:android_23_x86`, run `$sdk/tools/bin/sdkmanager
"system-images;android-23;default;x86"`.
To see the full list of supported `android_device` targets in
`@android_test_support`, run the following command:
```posix-terminal theme={null}
bazel query 'filter("x86_qemu2$", kind(android_device, @android_test_support//tools/android/emulated_devices/...:*))'
```
Bazel currently supports x86-based emulators only. For better performance, use
`QEMU2` `android_device` targets instead of `QEMU` ones.
## Running tests
To run tests, add these lines to your project's
`project root:/.bazelrc` file.
```
# Configurations for testing with Bazel
# Select a configuration by running
# `bazel test //my:target --config={headless, gui, local_device}`
# Headless instrumentation tests (No GUI)
test:headless --test_arg=--enable_display=false
# Graphical instrumentation tests. Ensure that $DISPLAY is set.
test:gui --test_env=DISPLAY
test:gui --test_arg=--enable_display=true
# Testing with a local emulator or device. Ensure that `adb devices` lists the
# device.
# Run tests serially.
test:local_device --test_strategy=exclusive
# Use the local device broker type, as opposed to WRAPPED_EMULATOR.
test:local_device --test_arg=--device_broker_type=LOCAL_ADB_SERVER
# Uncomment and set $device_id if there is more than one connected device.
# test:local_device --test_arg=--device_serial_number=$device_id
```
Then, use one of the configurations to run tests:
* `bazel test //my/test:target --config=gui`
* `bazel test //my/test:target --config=headless`
* `bazel test //my/test:target --config=local_device`
Use **only one configuration** or tests will fail.
### Headless testing
With `Xvfb`, it is possible to test with emulators without the graphical
interface, also known as headless testing. To disable the graphical interface
when running tests, pass the test argument `--enable_display=false` to Bazel:
```posix-terminal theme={null}
bazel test //my/test:target --test_arg=--enable_display=false
```
### GUI testing
If the `$DISPLAY` environment variable is set, it's possible to enable the
graphical interface of the emulator while the test is running. To do this, pass
these test arguments to Bazel:
```posix-terminal theme={null}
bazel test //my/test:target --test_arg=--enable_display=true --test_env=DISPLAY
```
### Testing with a local emulator or device
Bazel also supports testing directly on a locally launched emulator or connected
device. Pass the flags
`--test_strategy=exclusive` and
`--test_arg=--device_broker_type=LOCAL_ADB_SERVER` to enable local testing mode.
If there is more than one connected device, pass the flag
`--test_arg=--device_serial_number=$device_id` where `$device_id` is the id of
the device/emulator listed in `adb devices`.
## Sample projects
If you are looking for canonical project samples, see the [Android testing samples](https://github.com/googlesamples/android-testing#experimental-bazel-support)
for projects using Espresso and UIAutomator.
## Espresso setup
If you write UI tests with [Espresso](https://developer.android.com/training/testing/espresso/)
(`androidx.test.espresso`), you can use the following snippets to set up your
Bazel workspace with the list of commonly used Espresso artifacts and their
dependencies:
```
androidx.test.espresso:espresso-core
androidx.test:rules
androidx.test:runner
javax.inject:javax.inject
org.hamcrest:java-hamcrest
junit:junit
```
One way to organize these dependencies is to create a `//:test_deps` shared
library in your `project root/BUILD.bazel` file:
```python theme={null}
java_library(
name = "test_deps",
visibility = ["//visibility:public"],
exports = [
"@maven//:androidx_test_espresso_espresso_core",
"@maven//:androidx_test_rules",
"@maven//:androidx_test_runner",
"@maven//:javax_inject_javax_inject"
"@maven//:org_hamcrest_java_hamcrest",
"@maven//:junit_junit",
],
)
```
Then, add the required dependencies in `project root/WORKSPACE`:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "2.8"
RULES_JVM_EXTERNAL_SHA = "79c9850690d7614ecdb72d68394f994fef7534b292c4867ce5e7dec0aa7bdfad"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"junit:junit:4.12",
"javax.inject:javax.inject:1",
"org.hamcrest:java-hamcrest:2.0.0.0"
"androidx.test.espresso:espresso-core:3.1.1",
"androidx.test:rules:aar:1.1.1",
"androidx.test:runner:aar:1.1.1",
],
repositories = [
"https://maven.google.com",
"https://repo1.maven.org/maven2",
],
)
```
Finally, in your test `android_binary` target, add the `//:test_deps`
dependency:
```python theme={null}
android_binary(
name = "my_test_app",
instruments = "//path/to:app",
deps = [
"//:test_deps",
# ...
],
# ...
)
```
## Tips
### Reading test logs
Use `--test_output=errors` to print logs for failing tests, or
`--test_output=all` to print all test output. If you're looking for an
individual test log, go to
`$PROJECT_ROOT/bazel-testlogs/path/to/InstrumentationTestTargetName`.
For example, the test logs for `BasicSample` canonical project are in
`bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest`, run:
```posix-terminal theme={null}
tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest
```
This results in the following output:
```none theme={null}
$ tree bazel-testlogs/ui/espresso/BasicSample/BasicSampleInstrumentationTest
.
├── adb.409923.log
├── broker_logs
│ ├── aapt_binary.10.ok.txt
│ ├── aapt_binary.11.ok.txt
│ ├── adb.12.ok.txt
│ ├── adb.13.ok.txt
│ ├── adb.14.ok.txt
│ ├── adb.15.fail.txt
│ ├── adb.16.ok.txt
│ ├── adb.17.fail.txt
│ ├── adb.18.ok.txt
│ ├── adb.19.fail.txt
│ ├── adb.20.ok.txt
│ ├── adb.21.ok.txt
│ ├── adb.22.ok.txt
│ ├── adb.23.ok.txt
│ ├── adb.24.fail.txt
│ ├── adb.25.ok.txt
│ ├── adb.26.fail.txt
│ ├── adb.27.ok.txt
│ ├── adb.28.fail.txt
│ ├── adb.29.ok.txt
│ ├── adb.2.ok.txt
│ ├── adb.30.ok.txt
│ ├── adb.3.ok.txt
│ ├── adb.4.ok.txt
│ ├── adb.5.ok.txt
│ ├── adb.6.ok.txt
│ ├── adb.7.ok.txt
│ ├── adb.8.ok.txt
│ ├── adb.9.ok.txt
│ ├── android_23_x86.1.ok.txt
│ └── exec-1
│ ├── adb-2.txt
│ ├── emulator-2.txt
│ └── mksdcard-1.txt
├── device_logcat
│ └── logcat1635880625641751077.txt
├── emulator_itCqtc.log
├── outputs.zip
├── pipe.log.txt
├── telnet_pipe.log.txt
└── tmpuRh4cy
├── watchdog.err
└── watchdog.out
4 directories, 41 files
```
### Reading emulator logs
The emulator logs for `android_device` targets are stored in the `/tmp/`
directory with the name `emulator_xxxxx.log`, where `xxxxx` is a
randomly-generated sequence of characters.
Use this command to find the latest emulator log:
```posix-terminal theme={null}
ls -1t /tmp/emulator_*.log | head -n 1
```
### Testing against multiple API levels
If you would like to test against multiple API levels, you can use a list
comprehension to create test targets for each API level. For example:
```python theme={null}
API_LEVELS = [
"19",
"20",
"21",
"22",
]
[android_instrumentation_test(
name = "my_test_%s" % API_LEVEL,
test_app = ":my_test_app",
target_device = "@android_test_support//tools/android/emulated_devices/generic_phone:android_%s_x86_qemu2" % API_LEVEL,
) for API_LEVEL in API_LEVELS]
```
## Known issues
* [Forked adb server processes are not terminated after tests](https://github.com/bazelbuild/bazel/issues/4853)
* While APK building works on all platforms (Linux, macOS, Windows), testing
only works on Linux.
* Even with `--config=local_adb`, users still need to specify
`android_instrumentation_test.target_device`.
* If using a local device or emulator, Bazel does not uninstall the APKs after
the test. Clean the packages by running this command:
```posix-terminal theme={null}
adb shell pm list
packages com.example.android.testing | cut -d ':' -f 2 | tr -d '\r' | xargs
-L1 -t adb uninstall
```
# Using the Android Native Development Kit with Bazel
Source: https://bazel.build/docs/android-ndk
*If you're new to Bazel, please start with the [Building Android with Bazel](/start/android-app) tutorial.*
## Overview
Bazel can run in many different build configurations, including several that use
the Android Native Development Kit (NDK) toolchain. This means that normal
`cc_library` and `cc_binary` rules can be compiled for Android directly within
Bazel. Bazel accomplishes this by using the `android_ndk_repository` repository
rule and its related bzlmod extension.
For general Android
compilation, use [`rules_android`](https://github.com/bazelbuild/rules_android).
This tutorial demonstrates how to integrate C++ library dependencies into
Android apps and uses
[`rules_android_ndk`](https://github.com/bazelbuild/rules_android_ndk) for NDK
toolchain discovery and registration.
## Prerequisites
Please ensure that you have installed the Android SDK and NDK.
### NDK and SDK setup
External repository setup varies depending on whether you are using WORKSPACE
or bzlmod (MODULE.bazel). *Bzlmod is the preferred solution for Bazel 7+.*
Note that the MODULE.bazel and WORKSPACE setup stanzas are independent of
each other.
If you are using one dependency management solution, you don't need to add
the boilerplate for the other.
#### Bzlmod MODULE.bazel setup
Add the following snippet to your MODULE.bazel:
```python theme={null}
# NDK
bazel_dep(name = "rules_android_ndk", version = "0.1.3")
android_ndk_repository_extension = use_extension("@rules_android_ndk//:extension.bzl", "android_ndk_repository_extension")
use_repo(android_ndk_repository_extension, "androidndk")
register_toolchains("@androidndk//:all")
# SDK
bazel_dep(name = "rules_android", version = "0.6.6")
register_toolchains(
"@rules_android//toolchains/android:android_default_toolchain",
"@rules_android//toolchains/android_sdk:android_sdk_tools",
)
android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension")
use_repo(android_sdk_repository_extension, "androidsdk")
register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all")
```
#### Legacy WORKSPACE setup
Add the following snippet to your `WORKSPACE`:
```python theme={null}
load("@rules_android//rules:rules.bzl", "android_sdk_repository")
android_sdk_repository(
name = "androidsdk", # Required. Name *must* be "androidsdk".
path = "/path/to/sdk", # Optional. Can be omitted if `ANDROID_HOME` environment variable is set.
)
load("@rules_android_ndk//:rules.bzl", "android_ndk_repository")
android_ndk_repository(
name = "androidndk", # Required. Name *must* be "androidndk".
path = "/path/to/ndk", # Optional. Can be omitted if `ANDROID_NDK_HOME` environment variable is set.
)
```
Compatibility notes for WORKSPACE:
* Both `rules_android` and `rules_android_ndk` rules require extra
boilerplate not depicted in the WORKSPACE snippet above. For an up-to-date
and fully-formed instantiation stanza, see the [WORKSPACE](https://github.com/bazelbuild/rules_android_ndk/blob/main/examples/basic/WORKSPACE)
file of `rules_android_ndk`'s basic example app.
For more information about the `android_ndk_repository` rule, see its
[docstring](https://github.com/bazelbuild/rules_android_ndk/blob/7b4300f6d731139ca097f3332a5aebae5b0d91d0/rules.bzl#L18-L25).
## Quick start
To build C++ for Android, simply add `cc_library` dependencies to your
`android_binary` or `android_library` rules.
For example, given the following `BUILD` file for an Android app:
```python theme={null}
# In /app/src/main/BUILD.bazel
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_android//rules:rules.bzl", "android_binary", "android_library")
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
)
android_library(
name = "lib",
srcs = ["java/com/example/android/bazel/MainActivity.java"],
resource_files = glob(["res/**/*"]),
custom_package = "com.example.android.bazel",
manifest = "LibraryManifest.xml",
deps = [":jni_lib"],
)
android_binary(
name = "app",
deps = [":lib"],
manifest = "AndroidManifest.xml",
)
```
This `BUILD` file results in the following target graph:

**Figure 1.** Build graph of Android project with cc\_library dependencies.
To build the app, simply run:
```posix-terminal theme={null}
bazel build //app/src/main:app --android_platforms=
```
Note that if you don't specify `--android_platforms`, your build will fail with
errors about missing JNI headers.
The `bazel build` command compiles the Java files, Android resource files, and
`cc_library` rules, and packages everything into an APK:
```posix-terminal theme={null}
$ zipinfo -1 bazel-bin/app/src/main/app.apk
nativedeps
lib/armeabi-v7a/libapp.so
classes.dex
AndroidManifest.xml
...
res/...
...
META-INF/CERT.SF
META-INF/CERT.RSA
META-INF/MANIFEST.MF
```
Bazel compiles all of the cc\_libraries into a single shared object (`.so`) file,
targeted the architectures specified by `--android_platforms`.
See the section on [configuring the target ABI](#configuring-target-abi) for
more details.
## Example setup
This example is available in the [Bazel examples repository](https://github.com/bazelbuild/examples/tree/master/android/ndk).
In the `BUILD.bazel` file, three targets are defined with the `android_binary`,
`android_library`, and `cc_library` rules.
The `android_binary` top-level target builds the APK.
The `cc_library` target contains a single C++ source file with a JNI function
implementation:
```c++ theme={null}
#include
#include
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_android_bazel_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
```
The `android_library` target specifies the Java sources, resource files, and the
dependency on a `cc_library` target. For this example, `MainActivity.java` loads
the shared object file `libapp.so`, and defines the method signature for the JNI
function:
```java theme={null}
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("app");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
public native String stringFromJNI();
}
```
Note: The name of the native library is derived from the name of the top
level `android_binary` target. In this example, it is `app`.
## Configuring the target ABI
To configure the target ABI, use the `--android_platforms` flag as follows:
```posix-terminal theme={null}
bazel build //:app --android_platforms=comma-separated list of platforms
```
Just like the `--platforms` flag, the values passed to `--android_platforms` are
the labels of [`platform`](https://bazel.build/reference/be/platforms-and-toolchains#platform)
targets, using standard constraint values to describe your device.
For example, for an Android device with a 64-bit ARM processor, you'd define
your platform like this:
```py theme={null}
platform(
name = "android_arm64",
constraint_values = [
"@platforms//os:android",
"@platforms//cpu:arm64",
],
)
```
Every Android `platform` should use the [`@platforms//os:android`](https://github.com/bazelbuild/platforms/blob/33a3b209f94856193266871b1545054afb90bb28/os/BUILD#L36)
OS constraint. To migrate the CPU constraint, check this chart:
| CPU Value | Platform |
| - | - |
| `armeabi-v7a` | `@platforms//cpu:armv7` |
| `arm64-v8a` | `@platforms//cpu:arm64` |
| `x86` | `@platforms//cpu:x86_32` |
| `x86_64` | `@platforms//cpu:x86_64` |
And, of course, for a multi-architecture APK, you pass multiple labels, for
example: `--android_platforms=//:arm64,//:x86_64` (assuming you defined those in
your top-level `BUILD.bazel` file).
Bazel is unable to select a default Android platform, so one must be defined and
specified with `--android_platforms`.
Depending on the NDK revision and Android API level, the following ABIs are
available:
| NDK revision | ABIs |
| - | - |
| 16 and lower | armeabi, armeabi-v7a, arm64-v8a, mips, mips64, x86, x86\_64 |
| 17 and above | armeabi-v7a, arm64-v8a, x86, x86\_64 |
See [the NDK docs](https://developer.android.com/ndk/guides/abis.html)
for more information on these ABIs.
Multi-ABI Fat APKs are not recommended for release builds since they increase
the size of the APK, but can be useful for development and QA builds.
## Selecting a C++ standard
Use the following flags to build according to a C++ standard:
| C++ Standard | Flag |
| - | - |
| C++98 | Default, no flag needed |
| C++11 | `--cxxopt=-std=c++11` |
| C++14 | `--cxxopt=-std=c++14` |
| C++17 | `--cxxopt=-std=c++17` |
For example:
```posix-terminal theme={null}
bazel build //:app --cxxopt=-std=c++11
```
Read more about passing compiler and linker flags with `--cxxopt`, `--copt`, and
`--linkopt` in the [User Manual](/docs/user-manual#cxxopt).
Compiler and linker flags can also be specified as attributes in `cc_library`
using `copts` and `linkopts`. For example:
```python theme={null}
cc_library(
name = "jni_lib",
srcs = ["cpp/native-lib.cpp"],
copts = ["-std=c++11"],
linkopts = ["-ldl"], # link against libdl
)
```
## Building a `cc_library` for Android without using `android_binary`
To build a standalone `cc_binary` or `cc_library` for Android without using an
`android_binary`, use the `--platforms` flag.
For example, assuming you have defined Android platforms in
`my/platforms/BUILD`:
```posix-terminal theme={null}
bazel build //my/cc/jni:target \
--platforms=//my/platforms:x86_64
```
This approach affects the entire build tree.
Note: All of the targets on the command line must be compatible with
building for Android when specifying these flags, which may make it difficult to
use [Bazel wild-cards](/run/build#specifying-build-targets) like
`/...` and `:all`.
These flags can be put into a `bazelrc` config (one for each ABI), in
`project/.bazelrc`:
```
common:android_x86 --platforms=//my/platforms:x86
common:android_armeabi-v7a --platforms=//my/platforms:armeabi-v7a
# In general
common:android_ --platforms=//my/platforms:
```
Then, to build a `cc_library` for `x86` for example, run:
```posix-terminal theme={null}
bazel build //my/cc/jni:target --config=android_x86
```
In general, use this method for low-level targets (like `cc_library`) or when
you know exactly what you're building; rely on the automatic configuration
transitions from `android_binary` for high-level targets where you're expecting
to build a lot of targets you don't control.
# Android and Bazel
Source: https://bazel.build/docs/bazel-and-android
This page contains resources that help you use Bazel with Android projects. It
links to a tutorial, build rules, and other information specific to building
Android projects with Bazel.
## Getting started
The following resources will help you work with Bazel on Android projects:
* [Tutorial: Building an Android app](/start/android-app). This
tutorial is a good place to start learning about Bazel commands and concepts,
and how to build Android apps with Bazel.
* [Codelab: Building Android Apps with Bazel](https://developer.android.com/codelabs/bazel-android-intro#0).
This codelab explains how to build Android apps with Bazel.
## Features
Bazel has Android rules for building and testing Android apps, integrating with
the SDK/NDK, and creating emulator images. There are also Bazel plugins for
Android Studio and IntelliJ.
* [Android rules](/reference/be/android). The Build Encyclopedia describes the rules
for building and testing Android apps with Bazel.
* [Integration with Android Studio](/install/ide). Bazel is compatible with
Android Studio using the [Android Studio with Bazel](https://ij.bazel.build/)
plugin.
* [`mobile-install` for Android](/docs/mobile-install). Bazel's `mobile-install`
feature provides automated build-and-deploy functionality for building and
testing Android apps directly on Android devices and emulators.
* [Android instrumentation testing](/docs/android-instrumentation-test) on
emulators and devices.
* [Android NDK integration](/docs/android-ndk). Bazel supports compiling to
native code through direct NDK integration and the C++ rules.
* [Android build performance](/docs/android-build-performance). This page
provides information on optimizing build performance for Android apps.
## Further reading
* Integrating with dependencies from Google Maven and Maven Central with [rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external).
* Learn [How Android Builds Work in Bazel](https://blog.bazel.build/2018/02/14/how-android-builds-work-in-bazel.html).
* Shrink and optimize your app with [R8](https://github.com/bazelbuild/rules_android/tree/main/docs/r8-optimization.md).
# Apple Apps and Bazel
Source: https://bazel.build/docs/bazel-and-apple
This page contains resources that help you use Bazel to build macOS and iOS
projects. It links to a tutorial, build rules, and other information specific to
using Bazel to build and test for those platforms.
## Working with Bazel
The following resources will help you work with Bazel on macOS and iOS projects:
* [Tutorial: Building an iOS app](/start/ios-app)
* [Objective-C build rules](/reference/be/objective-c)
* [General Apple rules](https://github.com/bazelbuild/rules_apple)
* [Integration with Xcode](/install/ide)
## Migrating to Bazel
If you currently build your macOS and iOS projects with Xcode, follow the steps
in the migration guide to start building them with Bazel:
* [Migrating from Xcode to Bazel](/migrate/xcode)
## Apple apps and new rules
**Note**: Creating new rules is for advanced build and test scenarios.
You do not need it when getting started with Bazel.
The following modules, configuration fragments, and providers will help you
[extend Bazel's capabilities](/extending/concepts)
when building your macOS and iOS projects:
* Modules:
* [`apple_bitcode_mode`](/rules/lib/builtins/apple_bitcode_mode)
* [`apple_common`](/rules/lib/toplevel/apple_common)
* [`apple_platform`](/rules/lib/builtins/apple_platform)
* [`apple_platform_type`](/rules/lib/builtins/apple_platform_type)
* [`apple_toolchain`](/rules/lib/builtins/apple_toolchain)
* Configuration fragments:
* [`apple`](/rules/lib/fragments/apple)
* Providers:
* [`ObjcProvider`](/rules/lib/providers/ObjcProvider)
* [`XcodeVersionConfig`](/rules/lib/providers/XcodeVersionConfig)
## Xcode selection
If your build requires Xcode, Bazel will select an appropriate version based on
the `--xcode_config` and `--xcode_version` flags. The `--xcode_config` consumes
the set of available Xcode versions and sets a default version if
`--xcode_version` is not passed. This default is overridden by the
`--xcode_version` flag, as long as it is set to an Xcode version that is
represented in the `--xcode_config` target.
If you do not pass `--xcode_config`, Bazel will use the autogenerated
[`XcodeVersionConfig`](/rules/lib/providers/XcodeVersionConfig) that represents the
Xcode versions available on your host machine. The default version is
the newest available Xcode version. This is appropriate for local execution.
If you are performing remote builds, you should set `--xcode_config` to an
[`xcode_config`](/reference/be/objective-c#xcode_config)
target whose `versions` attribute is a list of remotely available
[`xcode_version`](/reference/be/objective-c#xcode_version)
targets, and whose `default` attribute is one of these
[`xcode_versions`](/reference/be/objective-c#xcode_version).
If you are using dynamic execution, you should set `--xcode_config` to an
[`xcode_config`](/reference/be/objective-c#xcode_config)
target whose `remote_versions` attribute is an
[`available_xcodes`](/reference/be/workspace#available_xcodes)
target containing the remotely available Xcode versions, and whose
`local_versions` attribute is an
[`available_xcodes`](/reference/be/workspace#available_xcodes)
target containing the locally available Xcode versions. For `local_versions`,
you probably want to use the autogenerated
`@local_config_xcode//:host_available_xcodes`. The default Xcode version is the
newest mutually available version, if there is one, otherwise the default of the
`local_versions` target. If you prefer to use the `local_versions` default
as the default, you can pass `--experimental_prefer_mutual_default=false`.
# C++ and Bazel
Source: https://bazel.build/docs/bazel-and-cpp
This page contains resources that help you use Bazel with C++ projects. It links
to a tutorial, build rules, and other information specific to building C++
projects with Bazel.
## Working with Bazel
The following resources will help you work with Bazel on C++ projects:
* [Tutorial: Building a C++ project](/start/cpp)
* [C++ common use cases](/tutorials/cpp-use-cases)
* [C/C++ rules](/reference/be/c-cpp)
* Essential Libraries
* [Abseil](https://abseil.io/docs/cpp/quickstart)
* [Boost](https://github.com/nelhage/rules_boost)
* [HTTPS Requests: CPR and libcurl](https://github.com/hedronvision/bazel-make-cc-https-easy)
* [C++ toolchain configuration](/docs/cc-toolchain-config-reference)
* [Tutorial: Configuring C++ toolchains](/tutorials/ccp-toolchain-config)
* [Integrating with C++ rules](/configure/integrate-cpp)
## Best practices
In addition to [general Bazel best practices](/configure/best-practices), below are
best practices specific to C++ projects.
### BUILD files
Follow the guidelines below when creating your BUILD files:
* Each `BUILD` file should contain one [`cc_library`](/reference/be/c-cpp#cc_library)
rule target per compilation unit in the directory.
* You should granularize your C++ libraries as much as
possible to maximize incrementality and parallelize the build.
* If there is a single source file in `srcs`, name the library the same as
that C++ file's name. This library should contain C++ file(s), any matching
header file(s), and the library's direct dependencies. For example:
```python theme={null}
cc_library(
name = "mylib",
srcs = ["mylib.cc"],
hdrs = ["mylib.h"],
deps = [":lower-level-lib"]
)
```
* Use one `cc_test` rule target per `cc_library` target in the file. Name the
target `[library-name]_test` and the source file `[library-name]_test.cc`.
For example, a test target for the `mylib` library target shown above would
look like this:
```python theme={null}
cc_test(
name = "mylib_test",
srcs = ["mylib_test.cc"],
deps = [":mylib"]
)
```
### Include paths
Follow these guidelines for include paths:
* Make all include paths relative to the workspace directory.
* Use quoted includes (`#include "foo/bar/baz.h"`) for non-system headers, not
angle-brackets (`#include <foo/bar/baz.h>`).
* Avoid using UNIX directory shortcuts, such as `.` (current directory) or `..`
(parent directory).
* For legacy or `third_party` code that requires includes pointing outside the
project repository, such as external repository includes requiring a prefix,
use the [`include_prefix`](/reference/be/c-cpp#cc_library.include_prefix) and
[`strip_include_prefix`](/reference/be/c-cpp#cc_library.strip_include_prefix)
arguments on the `cc_library` rule target.
### Toolchain features
The following optional [features](/docs/cc-toolchain-config-reference#features)
can improve the hygiene of a C++ project. They can be enabled using the
`--features` command-line flag or the `features` attribute of
[`repo`](/external/overview#repo.bazel),
[`package`](/reference/be/functions#package) or `cc_*` rules:
* The `parse_headers` feature makes it so that the C++ compiler is used to parse
(but not compile) all header files in the built targets and their dependencies
when using the
[`--process_headers_in_dependencies`](/reference/command-line-reference#flag--process_headers_in_dependencies)
flag. This can help catch issues in header-only libraries and ensure that
headers are self-contained and independent of the order in which they are
included.
* The `layering_check` feature enforces that targets only include headers
provided by their direct dependencies. The default toolchain supports this
feature on Linux with `clang` as the compiler.
# Java and Bazel
Source: https://bazel.build/docs/bazel-and-java
This page contains resources that help you use Bazel with Java projects. It
links to a tutorial, build rules, and other information specific to building
Java projects with Bazel.
## Working with Bazel
The following resources will help you work with Bazel on Java projects:
* [Tutorial: Building a Java Project](/start/java)
* [Java rules](/reference/be/java)
## Migrating to Bazel
If you currently build your Java projects with Maven, follow the steps in the
migration guide to start building your Maven projects with Bazel:
* [Migrating from Maven to Bazel](/migrate/maven)
## Java versions
There are two relevant versions of Java that are set with configuration flags:
* the version of the source files in the repository
* the version of the Java runtime that is used to execute the code and to test
it
### Configuring the version of the source code in your repository
Without an additional configuration, Bazel assumes all Java source files in the
repository are written in a single Java version. To specify the version of the
sources in the repository add `build --java_language_version={ver}` to
`.bazelrc` file, where `{ver}` is for example `11`. Bazel repository owners
should set this flag so that Bazel and its users can reference the source code's
Java version number. For more details, see
[Java language version flag](/docs/user-manual#java-language-version).
### Configuring the JVM used to execute and test the code
Bazel uses one JDK for compilation and another JVM to execute and test the code.
By default Bazel compiles the code using a JDK it downloads and it executes and
tests the code with the JVM installed on the local machine. Bazel searches for
the JVM using `JAVA_HOME` or path.
The resulting binaries are compatible with locally installed JVM in system
libraries, which means the resulting binaries depend on what is installed on the
machine.
To configure the JVM used for execution and testing use `--java_runtime_version`
flag. The default value is `local_jdk`.
### Hermetic testing and compilation
To create a hermetic compile, you can use command line flag
`--java_runtime_version=remotejdk_11`. The code is compiled for, executed, and
tested on the JVM downloaded from a remote repository. For more details, see
[Java runtime version flag](/docs/user-manual#java_runtime_version).
### Configuring compilation and execution of build tools in Java
There is a second pair of JDK and JVM used to build and execute tools, which are
used in the build process, but are not in the build results. That JDK and JVM
are controlled using `--tool_java_language_version` and
`--tool_java_runtime_version`. Default values are `11` and `remotejdk_11`,
respectively.
#### Compiling using locally installed JDK
Bazel by default compiles using remote JDK, because it is overriding JDK's
internals. The compilation toolchains using locally installed JDK are configured,
however not used.
To compile using locally installed JDK, that is use the compilation toolchains
for local JDK, use additional flag `--extra_toolchains=@local_jdk//:all`,
however, mind that this may not work on JDK of arbitrary vendors.
For more details, see
[configuring Java toolchains](#config-java-toolchains).
## Best practices
In addition to [general Bazel best practices](/configure/best-practices), below are
best practices specific to Java projects.
### Directory structure
Prefer Maven's standard directory layout (sources under `src/main/java`, tests
under `src/test/java`).
### BUILD files
Follow these guidelines when creating your `BUILD` files:
* Use one `BUILD` file per directory containing Java sources, because this
improves build performance.
* Every `BUILD` file should contain one `java_library` rule that looks like
this:
```python theme={null}
java_library(
name = "directory-name",
srcs = glob(["*.java"]),
deps = [...],
)
```
* The name of the library should be the name of the directory containing the
`BUILD` file. This makes the label of the library shorter, that is use
`"//package"` instead of `"//package:package"`.
* The sources should be a non-recursive [`glob`](/reference/be/functions#glob) of
all Java files in the directory.
* Tests should be in a matching directory under `src/test` and depend on this
library.
## Creating new rules for advanced Java builds
**Note**: Creating new rules is for advanced build and test scenarios. You do
not need it when getting started with Bazel.
The following modules, configuration fragments, and providers will help you
[extend Bazel's capabilities](/extending/concepts) when building your Java
projects:
* Main Java module: [`java_common`](/rules/lib/toplevel/java_common)
* Main Java provider: [`JavaInfo`](/rules/lib/providers/JavaInfo)
* Configuration fragment: [`java`](/rules/lib/fragments/java)
* Other modules:
* [`java_annotation_processing`](/rules/lib/builtins/java_annotation_processing)
* [`java_compilation_info`](/rules/lib/providers/java_compilation_info)
* [`java_output_jars`](/rules/lib/providers/java_output_jars)
* [`JavaRuntimeInfo`](/rules/lib/providers/JavaRuntimeInfo)
* [`JavaToolchainInfo`](/rules/lib/providers/JavaToolchainInfo)
## Configuring the Java toolchains
Bazel uses two types of Java toolchains:
* execution, used to execute and test Java binaries, controlled with the
`--java_runtime_version` flag
* compilation, used to compile Java sources, controlled with the
`--java_language_version` flag
### Configuring additional execution toolchains
Execution toolchain is the JVM, either local or from a repository, with some
additional information about its version, operating system, and CPU
architecture.
Java execution toolchains may added using the `local_java_repository` or
`remote_java_repository` repo rules in a module extension. Adding the rule makes
the JVM available using a flag. When multiple definitions for the same operating
system and CPU architecture are given, the first one is used.
Example configuration of local JVM in MODULE.bazel:
```python theme={null}
custom_jdk = use_extension("@rules_java//java:extensions.bzl", "java_repository")
custom_jdk.local(
name = "additionaljdk", # Can be used with --java_runtime_version=additionaljdk, --java_runtime_version=11 or --java_runtime_version=additionaljdk_11
version = "11", # Optional, if not set it is autodetected
java_home = "/usr/lib/jdk-15/", # Path to directory containing bin/java
)
use_repo(custom_jdk, "additionaljdk")
register_toolchains("@additionaljdk//:all")
```
Example configuration of remote JVM:
```python theme={null}
custom_jdk = use_extension("@rules_java//java:extensions.bzl", "java_repository")
custom_jdk.remote(
name = "openjdk_canary_linux_arm",
prefix = "openjdk_canary", # Can be used with --java_runtime_version=openjdk_canary_11
version = "11", # or --java_runtime_version=11
target_compatible_with = [ # Specifies constraints this JVM is compatible with
"@platforms//cpu:arm",
"@platforms//os:linux",
],
urls = ..., # Other parameters are from http_repository rule.
sha256 = ...,
strip_prefix = ...
)
use_repo(custom_jdk, "openjdk_canary_linux_arm", "openjdk_canary_linux_arm_toolchain_config_repo")
register_toolchains("@openjdk_canary_linux_arm_toolchain_config_repo//:all")
```
### Configuring additional compilation toolchains
Compilation toolchain is composed of JDK and multiple tools that Bazel uses
during the compilation and that provides additional features, such as: Error
Prone, strict Java dependencies, header compilation, Android desugaring,
coverage instrumentation, and genclass handling for IDEs.
JavaBuilder is a Bazel-bundled tool that executes compilation, and provides the
aforementioned features. Actual compilation is executed using the internal
compiler by the JDK. The JDK used for compilation is specified by `java_runtime`
attribute of the toolchain.
Bazel overrides some JDK internals. In case of JDK version > 9,
`java.compiler` and `jdk.compiler` modules are patched using JDK's flag
`--patch_module`. In case of JDK version 8, the Java compiler is patched using
`-Xbootclasspath` flag.
VanillaJavaBuilder is a second implementation of JavaBuilder,
which does not modify JDK's internal compiler and does not have any of the
additional features. VanillaJavaBuilder is not used by any of the built-in
toolchains.
In addition to JavaBuilder, Bazel uses several other tools during compilation.
The `ijar` tool processes `jar` files to remove everything except call
signatures. Resulting jars are called header jars. They are used to improve the
compilation incrementality by only recompiling downstream dependents when the
body of a function changes.
The `singlejar` tool packs together multiple `jar` files into a single one.
The `genclass` tool post-processes the output of a Java compilation, and produces
a `jar` containing only the class files for sources that were generated by
annotation processors.
The `JacocoRunner` tool runs Jacoco over instrumented files and outputs results in
LCOV format.
The `TestRunner` tool executes JUnit 4 tests in a controlled environment.
You can reconfigure the compilation by adding `default_java_toolchain` macro to
a `BUILD` file and registering it either by adding `register_toolchains` rule to
the `MODULE.bazel` file or by using
[`--extra_toolchains`](/docs/user-manual#extra-toolchains) flag.
The toolchain is only used when the `source_version` attribute matches the
value specified by `--java_language_version` flag.
Example toolchain configuration:
```python theme={null}
load(
"@rules_java//toolchains:default_java_toolchain.bzl",
"default_java_toolchain", "DEFAULT_TOOLCHAIN_CONFIGURATION", "BASE_JDK9_JVM_OPTS", "DEFAULT_JAVACOPTS"
)
default_java_toolchain(
name = "repository_default_toolchain",
configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, # One of predefined configurations
# Other parameters are from java_toolchain rule:
java_runtime = "@rules_java//toolchains:remote_jdk11", # JDK to use for compilation and toolchain's tools execution
jvm_opts = BASE_JDK9_JVM_OPTS + ["--enable_preview"], # Additional JDK options
javacopts = DEFAULT_JAVACOPTS + ["--enable_preview"], # Additional javac options
source_version = "9",
)
```
which can be used using `--extra_toolchains=//:repository_default_toolchain_definition`
or by adding `register_toolchains("//:repository_default_toolchain_definition")`
to the workpace.
Predefined configurations:
* `DEFAULT_TOOLCHAIN_CONFIGURATION`: all features, supports JDK versions >= 9
* `VANILLA_TOOLCHAIN_CONFIGURATION`: no additional features, supports JDKs of
arbitrary vendors.
* `PREBUILT_TOOLCHAIN_CONFIGURATION`: same as default, but only use prebuilt
tools (`ijar`, `singlejar`)
* `NONPREBUILT_TOOLCHAIN_CONFIGURATION`: same as default, but all tools are
built from sources (this may be useful on operating system with different
libc)
#### Configuring JVM and Java compiler flags
You may configure JVM and javac flags either with flags or with
`default_java_toolchain` attributes.
The relevant flags are `--jvmopt`, `--host_jvmopt`, `--javacopt`, and
`--host_javacopt`.
The relevant `default_java_toolchain` attributes are `javacopts`, `jvm_opts`,
`javabuilder_jvm_opts`, and `turbine_jvm_opts`.
#### Package specific Java compiler flags configuration
You can configure different Java compiler flags for specific source
files using `package_configuration` attribute of `default_java_toolchain`.
Please refer to the example below.
```python theme={null}
load("@rules_java//toolchains:default_java_toolchain.bzl", "default_java_toolchain")
# This is a convenience macro that inherits values from Bazel's default java_toolchain
default_java_toolchain(
name = "toolchain",
package_configuration = [
":error_prone",
],
visibility = ["//visibility:public"],
)
# This associates a set of javac flags with a set of packages
java_package_configuration(
name = "error_prone",
javacopts = [
"-Xep:MissingOverride:ERROR",
],
packages = ["error_prone_packages"],
)
# This is a regular package_group, which is used to specify a set of packages to apply flags to
package_group(
name = "error_prone_packages",
packages = [
"//foo/...",
"-//foo/bar/...", # this is an exclusion
],
)
```
#### Multiple versions of Java source code in a single repository
Bazel only supports compiling a single version of Java sources in a build.
build. This means that when building a Java test or an application, all
dependencies are built against the same Java version.
However, separate builds may be executed using different flags.
To make the task of using different flags easier, sets of flags for a specific
version may be grouped with `.bazelrc` configs":
```python theme={null}
build:java8 --java_language_version=8
build:java8 --java_runtime_version=local_jdk_8
build:java11 --java_language_version=11
build:java11 --java_runtime_version=remotejdk_11
```
These configs can be used with the `--config` flag, for example
`bazel test --config=java11 //:java11_test`.
# JavaScript and Bazel
Source: https://bazel.build/docs/bazel-and-javascript
This page contains resources that help you use Bazel with JavaScript projects.
It links to build rules and other information specific to building JavaScript
with Bazel.
The following resources will help you work with Bazel on JavaScript projects:
* [NodeJS toolchain](https://github.com/bazelbuild/rules_nodejs)
* [rules\_js](https://github.com/aspect-build/rules_js) - Bazel rules for building JavaScript programs
* [rules\_esbuild](https://github.com/aspect-build/rules_esbuild) - Bazel rules for [esbuild](https://esbuild.github.io) JS bundler
* [rules\_terser](https://github.com/aspect-build/rules_terser) - Bazel rules for [Terser](https://terser.org) - a JavaScript minifier
* [rules\_swc](https://github.com/aspect-build/rules_swc) - Bazel rules for [swc](https://swc.rs)
* [rules\_ts](https://github.com/aspect-build/rules_ts) - Bazel rules for [TypeScript](http://typescriptlang.org)
* [rules\_webpack](https://github.com/aspect-build/rules_webpack) - Bazel rules for [Webpack](https://webpack.js.org)
* [rules\_rollup](https://github.com/aspect-build/rules_rollup) - Bazel rules for [Rollup](https://rollupjs.org) - a JavaScript bundler
* [rules\_jest](https://github.com/aspect-build/rules_jest) - Bazel rules to run tests using [Jest](https://jestjs.io)
* [rules\_jasmine](https://github.com/aspect-build/rules_jasmine) - Bazel rules to run tests using [Jasmine](https://jasmine.github.io/)
* [rules\_cypress](https://github.com/aspect-build/rules_cypress) - Bazel rules to run tests using [Cypress](https://cypress.io)
* [rules\_deno](https://github.com/aspect-build/rules_deno) - Bazel rules for [Deno](http://deno.land)
# C++ Toolchain Configuration
Source: https://bazel.build/docs/cc-toolchain-config-reference
## Overview
To invoke the compiler with the right options, Bazel needs some knowledge about
the compiler internals, such as include directories and important flags.
In other words, Bazel needs a simplified model of the compiler to understand its
workings.
Bazel needs to know the following:
* Whether the compiler supports thinLTO, modules, dynamic linking, or PIC
(position independent code).
* Paths to the required tools such as gcc, ld, ar, objcopy, and so on.
* The built-in system include directories. Bazel needs these to validate that
all headers that were included in the source file were properly declared in
the `BUILD` file.
* The default sysroot.
* Which flags to use for compilation, linking, archiving.
* Which flags to use for the supported compilation modes (opt, dbg, fastbuild).
* Make variables specifically required by the compiler.
If the compiler has support for multiple architectures, Bazel needs to configure
them separately.
[`CcToolchainConfigInfo`](/rules/lib/providers/CcToolchainConfigInfo) is a provider that provides the necessary level of
granularity for configuring the behavior of Bazel's C++ rules. By default,
Bazel automatically configures `CcToolchainConfigInfo` for your build, but you
have the option to configure it manually. For that, you need a Starlark rule
that provides the `CcToolchainConfigInfo` and you need to point the
[`toolchain_config`](/reference/be/c-cpp#cc_toolchain.toolchain_config) attribute of the
[`cc_toolchain`](/reference/be/c-cpp#cc_toolchain) to your rule.
You can create the `CcToolchainConfigInfo` by calling
[`cc_common.create_cc_toolchain_config_info()`](/rules/lib/toplevel/cc_common#create_cc_toolchain_config_info).
You can find Starlark constructors for all structs you'll need in the process in
[`@rules_cc//cc:cc_toolchain_config_lib.bzl`](https://github.com/bazelbuild/rules_cc/blob/master/cc/cc_toolchain_config_lib.bzl).
When a C++ target enters the analysis phase, Bazel selects the appropriate
`cc_toolchain` target based on the `BUILD` file, and obtains the
`CcToolchainConfigInfo` provider from the target specified in the
`cc_toolchain.toolchain_config` attribute. The `cc_toolchain` target
passes this information to the C++ target through a `CcToolchainProvider`.
For example, a compile or link action, instantiated by a rule such as
`cc_binary` or `cc_library`, needs the following information:
* The compiler or linker to use
* Command-line flags for the compiler/linker
* Configuration flags passed through the `--copt/--linkopt` options
* Environment variables
* Artifacts needed in the sandbox in which the action executes
All of the above information except the artifacts required in the sandbox is
specified in the Starlark target that the `cc_toolchain` points to.
The artifacts to be shipped to the sandbox are declared in the `cc_toolchain`
target. For example, with the `cc_toolchain.linker_files` attribute you can
specify the linker binary and toolchain libraries to ship into the sandbox.
## Toolchain selection
The toolchain selection logic operates as follows:
1. User specifies a `cc_toolchain_suite` target in the `BUILD` file and points
Bazel to the target using the
[`--crosstool_top` option](/docs/user-manual#flag--crosstool_top).
2. The `cc_toolchain_suite` target references multiple toolchains. The
values of the `--cpu` and `--compiler` flags determine which of those
toolchains is selected, either based only on the `--cpu` flag value, or
based on a joint `--cpu | --compiler` value. The selection process is as
follows:
* If the `--compiler` option is specified, Bazel selects the
corresponding entry from the `cc_toolchain_suite.toolchains`
attribute with `--cpu | --compiler`. If Bazel does not find
a corresponding entry, it throws an error.
* If the `--compiler` option is not specified, Bazel selects
the corresponding entry from the `cc_toolchain_suite.toolchains`
attribute with just `--cpu`.
* If no flags are specified, Bazel inspects the host system and selects a
`--cpu` value based on its findings. See the
[inspection mechanism code](https://source.bazel.build/bazel/+/1b73bc37e184e71651eb631223dcce321ba16211:src/main/java/com/google/devtools/build/lib/analysis/config/AutoCpuConverter.java).
Once a toolchain has been selected, corresponding `feature` and `action_config`
objects in the Starlark rule govern the configuration of the build (that is,
items described later). These messages allow the implementation of
fully fledged C++ features in Bazel without modifying the
Bazel binary. C++ rules support multiple unique actions documented in detail
[in the Bazel source code](https://source.bazel.build/bazel/+/4f547a7ea86df80e4c76145ffdbb0c8b75ba3afa:tools/build_defs/cc/action_names.bzl).
## Features
A feature is an entity that requires command-line flags, actions,
constraints on the execution environment, or dependency alterations. A feature
can be something as simple as allowing `BUILD` files to select configurations of
flags, such as `treat_warnings_as_errors`, or interact with the C++ rules and
include new compile actions and inputs to the compilation, such as
`header_modules` or `thin_lto`.
Ideally, `CcToolchainConfigInfo` contains a list of features, where each
feature consists of one or more flag groups, each defining a list of flags
that apply to specific Bazel actions.
A feature is specified by name, which allows full decoupling of the Starlark
rule configuration from Bazel releases. In other words, a Bazel release does not
affect the behavior of `CcToolchainConfigInfo` configurations as long as those
configurations do not require the use of new features.
A feature is enabled in one of the following ways:
* The feature's `enabled` field is set to `true`.
* Bazel or the rule owner explicitly enable it.
* The user enables it through the `--feature` Bazel option or `features` rule
attribute.
Features can have interdependencies, depend on command line flags, `BUILD` file
settings, and other variables.
### Feature relationships
Dependencies are typically managed directly with Bazel, which simply enforces
the requirements and manages conflicts intrinsic to the nature of the features
defined in the build. The toolchain specification allows for more granular
constraints for use directly within the Starlark rule that govern feature
support and expansion. These are:
Feature-level. The feature is supported only if the specified required
features are enabled. For example, when a feature is only supported in
certain build modes (`opt`, `dbg`, or
`fastbuild`). If `requires` contains multiple `feature_set`s
the feature is supported if any of the `feature_set`s is satisfied
(when all specified features are enabled).
implies = \['feature']
Feature-level. This feature implies the specified feature(s).
Enabling a feature also implicitly enables all features implied by it
(that is, it functions recursively).
Also provides the ability to factor common subsets of functionality out of
a set of features, such as the common parts of sanitizers. Implied
features cannot be disabled.
provides = \['feature']
Feature-level. Indicates that this feature is one of several mutually
exclusive alternate features. For example, all of the sanitizers could
specify `provides = ["sanitizer"]`.
This improves error handling by listing the alternatives if the user asks
for two or more mutually exclusive features at once.
Flag set-level. A feature can specify multiple flag sets with multiple.
When `with_features` is specified, the flag set will only expand
to the build command if there is at least one `with_feature_set`
for which all of the features in the specified `features` set
are enabled, and all the features specified in `not_features`
set are disabled.
If `with_features` is not specified, the flag set will be
applied unconditionally for every action specified.
## Actions
Actions provide the flexibility to modify the circumstances under
which an action executes without assuming how the action will be run. An
`action_config` specifies the tool binary that an action invokes, while a
`feature` specifies the configuration (flags) that determine how that tool
behaves when the action is invoked.
[Features](#features) reference actions to signal which Bazel actions
they affect since actions can modify the Bazel action graph. The
`CcToolchainConfigInfo` provider contains actions that have flags and tools
associated with them, such as `c++-compile`. Flags are assigned to each action
by associating them with a feature.
Each action name represents a single type of action performed by Bazel, such as
compiling or linking. There is, however, a many-to-one relationship between
actions and Bazel action types, where a Bazel action type refers to a Java class
that implements an action (such as `CppCompileAction`). In particular, the
"assembler actions" and "compiler actions" in the table below are
`CppCompileAction`, while the link actions are `CppLinkAction`.
### Assembler actions
**Action**
**Description**
`preprocess-assemble`
Assemble with preprocessing. Typically for `.S` files.
`assemble`
Assemble without preprocessing. Typically for `.s` files.
### Compiler actions
**Action**
**Description**
`cc-flags-make-variable`
Propagates `CC_FLAGS` to genrules.
`c-compile`
Compile as C.
`c++-compile`
Compile as C++.
`c++-header-parsing`
Run the compiler's parser on a header file to ensure that the header is
self-contained, as it will otherwise produce compilation errors. Applies
only to toolchains that support modules.
### Link actions
**Action**
**Description**
`c++-link-dynamic-library`
Link a shared library containing all of its dependencies.
`c++-link-nodeps-dynamic-library`
Link a shared library only containing `cc_library` sources.
`c++-link-executable`
Link a final ready-to-run library.
### AR actions
AR actions assemble object files into archive libraries (`.a` files) via `ar`
and encode some semantics into the name.
**Action**
**Description**
`c++-link-static-library`
Create a static library (archive).
### LTO actions
**Action**
**Description**
`lto-backend`
ThinLTO action compiling bitcodes into native objects.
`lto-index`
ThinLTO action generating global index.
## Using action\_config
The `action_config` is a Starlark struct that describes a Bazel
action by specifying the tool (binary) to invoke during the action and sets of
flags, defined by features. These flags apply constraints to the action's
execution.
The `action_config()` constructor has the following parameters:
**Attribute**
**Description**
`action_name`
The Bazel action to which this action corresponds.
Bazel uses this attribute to discover per-action tool and execution
requirements.
`tools`
The executable to invoke. The tool applied to the action will be the
first tool in the list with a feature set that matches the feature
configuration. Default value must be provided.
`flag_sets`
A list of flags that applies to a group of actions. Same as for a
feature.
`env_sets`
A list of environment constraints that applies to a group of actions.
Same as for a feature.
An `action_config` can require and imply other features and
`action_config`s as dictated by the
[feature relationships](#feature-relationships) described earlier. This behavior
is similar to that of a feature.
The last two attributes are redundant against the corresponding attributes on
features and are included because some Bazel actions require certain flags or
environment variables and the goal is to avoid unnecessary `action_config`+`feature`
pairs. Typically, sharing a single feature across multiple `action_config`s is
preferred.
You can not define more than one `action_config` with the same `action_name`
within the same toolchain. This prevents ambiguity in tool paths
and enforces the intention behind `action_config` - that an action's properties
are clearly described in a single place in the toolchain.
### Using tool constructor
An`action_config` can specify a set of tools via its `tools` parameter.
The `tool()` constructor takes in the following parameters:
**Field**
**Description**
`path`
Path to the tool in question (relative to the current location).
`with_features`
A list of feature sets out of which at least one must be satisfied
for this tool to apply.
For a given `action_config`, only a single `tool` applies
its tool path and execution requirements to the Bazel action. A tool is selected
by iterating through the `tools` attribute on an `action_config` until a tool
with a `with_feature` set matching the feature configuration is found
(see [Feature relationships](#feature-relationships) earlier on this page
for more information). You should end your tool lists with a default
tool that corresponds to an empty feature configuration.
### Example usage
Features and actions can be used together to implement Bazel actions
with diverse cross-platform semantics. For example, debug symbol generation on
macOS requires generating symbols in the compile action, then invoking a
specialized tool during the link action to create compressed dsym archive, and
then decompressing that archive to produce the application bundle and `.plist`
files consumable by Xcode.
With Bazel, this process can instead be implemented as follows, with
`unbundle-debuginfo` being a Bazel action:
load("@rules\_cc//cc:defs.bzl", "ACTION\_NAMES")
action\_configs = \[
action\_config (
action\_name = ACTION\_NAMES.cpp\_link\_executable,
tools = \[
tool(
with\_features = \[
with\_feature(features=\["generate-debug-symbols"]),
],
path = "toolchain/mac/ld-with-dsym-packaging",
),
tool (path = "toolchain/mac/ld"),
],
),
]
features = \[
feature(
name = "generate-debug-symbols",
flag\_sets = \[
flag\_set (
actions = \[
ACTION\_NAMES.c\_compile,
ACTION\_NAMES.cpp\_compile
],
flag\_groups = \[
flag\_group(
flags = \["-g"],
),
],
)
],
implies = \["unbundle-debuginfo"],
),
]
This same feature can be implemented entirely differently for Linux, which uses
`fission`, or for Windows, which produces `.pdb` files. For example, the
implementation for `fission`-based debug symbol generation might look as
follows:
load("@rules\_cc//cc:defs.bzl", "ACTION\_NAMES")
action\_configs = \[
action\_config (
name = ACTION\_NAMES.cpp\_compile,
tools = \[
tool(
path = "toolchain/bin/gcc",
),
],
),
]
features = \[
feature (
name = "generate-debug-symbols",
requires = \[with\_feature\_set(features = \["dbg"])],
flag\_sets = \[
flag\_set(
actions = \[ACTION\_NAMES.cpp\_compile],
flag\_groups = \[
flag\_group(
flags = \["-gsplit-dwarf"],
),
],
),
flag\_set(
actions = \[ACTION\_NAMES.cpp\_link\_executable],
flag\_groups = \[
flag\_group(
flags = \["-Wl", "--gdb-index"],
),
],
),
],
),
]
### Flag groups
`CcToolchainConfigInfo` allows you to bundle flags into groups that serve a
specific purpose. You can specify a flag within using pre-defined variables
within the flag value, which the compiler expands when adding the flag to the
build command. For example:
flag\_group (
flags = \["%"],
)
In this case, the contents of the flag will be replaced by the output file path
of the action.
Flag groups are expanded to the build command in the order in which they appear
in the list, top-to-bottom, left-to-right.
For flags that need to repeat with different values when added to the build
command, the flag group can iterate variables of type `list`. For example, the
variable `include_path` of type `list`:
flag\_group (
iterate\_over = "include\_paths",
flags = \["-I%"],
)
expands to `-I` for each path element in the `include_paths` list. All
flags (or `flag_group`s) in the body of a flag group declaration are expanded as
a unit. For example:
flag\_group (
iterate\_over = "include\_paths",
flags = \["-I", "%"],
)
expands to `-I ` for each path element in the `include_paths` list.
A variable can repeat multiple times. For example:
flag\_group (
iterate\_over = "include\_paths",
flags = \["-iprefix=%", "-isystem=%"],
)
expands to:
```
-iprefix= -isystem= -iprefix= -isystem=
```
Variables can correspond to structures accessible using dot-notation. For
example:
flag\_group (
flags = \["-l%"],
)
Structures can be nested and may also contain sequences. To prevent name clashes
and to be explicit, you must specify the full path through the fields. For
example:
flag\_group (
iterate\_over = "libraries\_to\_link",
flag\_groups = \[
flag\_group (
iterate\_over = "libraries\_to\_link.shared\_libraries",
flags = \["-l%"],
),
],
)
### Conditional expansion
Flag groups support conditional expansion based on the presence of a particular
variable or its field using the `expand_if_available`, `expand_if_not_available`,
`expand_if_true`, `expand_if_false`, or `expand_if_equal` attributes. For example:
flag\_group (
iterate\_over = "libraries\_to\_link",
flag\_groups = \[
flag\_group (
iterate\_over = "libraries\_to\_link.shared\_libraries",
flag\_groups = \[
flag\_group (
expand\_if\_available = "libraries\_to\_link.shared\_libraries.is\_whole\_archive",
flags = \["--whole\_archive"],
),
flag\_group (
flags = \["-l%"],
),
flag\_group (
expand\_if\_available = "libraries\_to\_link.shared\_libraries.is\_whole\_archive",
flags = \["--no\_whole\_archive"],
),
],
),
],
)
Note: The `--whole_archive` and `--no_whole_archive` options are added to
the build command only when a currently iterated library has an
`is_whole_archive` field.
## CcToolchainConfigInfo reference
This section provides a reference of build variables, features, and other
information required to successfully configure C++ rules.
### CcToolchainConfigInfo build variables
The following is a reference of `CcToolchainConfigInfo` build variables.
Note: The **Action** column indicates the relevant action type, if applicable.
**Variable**
**Action**
**Description**
**`source_file`**
compile
Source file to compile.
**`input_file`**
strip
Artifact to strip.
**`output_file`**
compile, strip
Compilation output.
**`output_assembly_file`**
compile
Emitted assembly file. Applies only when the
`compile` action emits assembly text, typically when using the
`--save_temps` flag. The contents are the same as for
`output_file`.
**`output_preprocess_file`**
compile
Preprocessed output. Applies only to compile
actions that only preprocess the source files, typically when using the
`--save_temps` flag. The contents are the same as for
`output_file`.
**`includes`**
compile
Sequence of files the compiler must
unconditionally include in the compiled source.
**`include_paths`**
compile
Sequence directories in which the compiler
searches for headers included using `#include`
and `#include "foo.h"`.
**`quote_include_paths`**
compile
Sequence of `-iquote` includes -
directories in which the compiler searches for headers included using
`#include "foo.h"`.
**`system_include_paths`**
compile
Sequence of `-isystem` includes -
directories in which the compiler searches for headers included using
`#include `.
**`dependency_file`**
compile
The `.d` dependency file generated by the compiler.
**`preprocessor_defines`**
compile
Sequence of `defines`, such as `--DDEBUG`.
**`pic`**
compile
Compiles the output as position-independent code.
**`gcov_gcno_file`**
compile
The `gcov` coverage file.
**`per_object_debug_info_file`**
compile
The per-object debug info (`.dwp`) file.
**`stripopts`**
strip
Sequence of `stripopts`.
**`legacy_compile_flags`**
compile
Sequence of flags from legacy
`CROSSTOOL` fields such as `compiler_flag`,
`optional_compiler_flag`, `cxx_flag`, and
`optional_cxx_flag`.
**`user_compile_flags`**
compile
Sequence of flags from either the
`copt` rule attribute or the `--copt`,
`--cxxopt`, and `--conlyopt` flags.
**`unfiltered_compile_flags`**
compile
Sequence of flags from the
`unfiltered_cxx_flag` legacy `CROSSTOOL` field or the
`unfiltered_compile_flags` feature. These are not filtered by
the `nocopts` rule attribute.
**`sysroot`**
The `sysroot`.
**`runtime_library_search_directories`**
link
Entries in the linker runtime search path (usually
set with the `-rpath` flag).
**`library_search_directories`**
link
Entries in the linker search path (usually set with
the `-L` flag).
**`libraries_to_link`**
link
Flags providing files to link as inputs in the linker invocation.
**`def_file_path`**
link
Location of def file used on Windows with MSVC.
**`linker_param_file`**
link
Location of linker param file created by bazel to
overcome command line length limit.
**`output_execpath`**
link
Execpath of the output of the linker.
**`generate_interface_library`**
link
`"yes"` or `"no"` depending on whether interface library should
be generated.
**`interface_library_builder_path`**
link
Path to the interface library builder tool.
**`interface_library_input_path`**
link
Input for the interface library `ifso` builder tool.
**`interface_library_output_path`**
link
Path where to generate interface library using the `ifso` builder tool.
**`legacy_link_flags`**
link
Linker flags coming from the legacy `CROSSTOOL` fields.
**`user_link_flags`**
link
Linker flags coming from the `--linkopt`
or `linkopts` attribute.
**`linkstamp_paths`**
link
A build variable giving linkstamp paths.
**`force_pic`**
link
Presence of this variable indicates that PIC/PIE code should
be generated (Bazel option `--force_pic` was passed).
**`strip_debug_symbols`**
link
Presence of this variable indicates that the debug
symbols should be stripped.
**`is_cc_test`**
link
Truthy when current action is a `cc_test`
linking action, false otherwise.
**`is_using_fission`**
compile, link
Presence of this variable indicates that fission (per-object debug info)
is activated. Debug info will be in `.dwo` files instead
of `.o` files and the compiler and linker need to know this.
**`fdo_instrument_path`**
compile, link
Path to the directory that stores FDO instrumentation profile.
**`fdo_profile_path`**
compile
Path to FDO profile.
**`fdo_prefetch_hints_path`**
compile
Path to the cache prefetch profile.
**`cs_fdo_instrument_path`**
compile, link
Path to the directory that stores context sensitive FDO
instrumentation profile.
### Well-known features
The following is a reference of features and their activation
conditions.
**Feature**
**Documentation**
**`opt | dbg | fastbuild`**
Enabled by default based on compilation mode.
**`static_linking_mode | dynamic_linking_mode`**
Enabled by default based on linking mode.
**`per_object_debug_info`**
Enabled if the `supports_fission` feature is specified and
enabled and the current compilation mode is specified in the
`--fission` flag.
**`supports_start_end_lib`**
If enabled (and the option `--start_end_lib` is set), Bazel
will not link against static libraries but instead use the
`--start-lib/--end-lib` linker options to link against objects
directly. This speeds up the build since Bazel doesn't have to build
static libraries.
**`supports_interface_shared_libraries`**
If enabled (and the option `--interface_shared_objects` is
set), Bazel will link targets that have `linkstatic` set to
False (`cc_test`s by default) against interface shared
libraries. This makes incremental relinking faster.
**`supports_dynamic_linker`**
If enabled, C++ rules will know the toolchain can produce shared
libraries.
**`static_link_cpp_runtimes`**
If enabled, Bazel will link the C++ runtime statically in static linking
mode and dynamically in dynamic linking mode. Artifacts
specified in the `cc_toolchain.static_runtime_lib` or
`cc_toolchain.dynamic_runtime_lib` attribute (depending on the
linking mode) will be added to the linking actions.
**`supports_pic`**
If enabled, toolchain will know to use PIC objects for dynamic libraries.
The `pic` variable is present whenever PIC compilation is needed. If not enabled
by default, and `--force_pic` is passed, Bazel will request `supports_pic` and
validate that the feature is enabled. If the feature is missing, or couldn't
be enabled, `--force_pic` cannot be used.
**`static_linking_mode | dynamic_linking_mode`**
Enabled by default based on linking mode.
**`no_legacy_features`**
Prevents Bazel from adding legacy features to
the C++ configuration when present. See the complete list of
features below.
**`shorten_virtual_includes`**
If enabled, virtual include header files are linked under `bin/_virtual_includes/` instead of `bin//_virtual_includes/`. Useful on Windows to avoid long path issue with MSVC.
#### Legacy features patching logic
Bazel applies the following changes to the toolchain's features for backwards
compatibility:
Moves `legacy_compile_flags` feature to the top of the toolchain
Moves `default_compile_flags` feature to the top of the toolchain
Adds `dependency_file` (if not present) feature to the top of the toolchain
Adds `pic` (if not present) feature to the top of the toolchain
Adds `per_object_debug_info` (if not present) feature to the top of the toolchain
Adds `preprocessor_defines` (if not present) feature to the top of the toolchain
Adds `includes` (if not present) feature to the top of the toolchain
Adds `include_paths` (if not present) feature to the top of the toolchain
Adds `fdo_instrument` (if not present) feature to the top of the toolchain
Adds `fdo_optimize` (if not present) feature to the top of the toolchain
Adds `cs_fdo_instrument` (if not present) feature to the top of the toolchain
Adds `cs_fdo_optimize` (if not present) feature to the top of the toolchain
Adds `fdo_prefetch_hints` (if not present) feature to the top of the toolchain
Adds `autofdo` (if not present) feature to the top of the toolchain
Adds `build_interface_libraries` (if not present) feature to the top of the toolchain
Adds `dynamic_library_linker_tool` (if not present) feature to the top of the toolchain
Adds `shared_flag` (if not present) feature to the top of the toolchain
Adds `linkstamps` (if not present) feature to the top of the toolchain
Adds `output_execpath_flags` (if not present) feature to the top of the toolchain
Adds `runtime_library_search_directories` (if not present) feature to the top of the toolchain
Adds `library_search_directories` (if not present) feature to the top of the toolchain
Adds `archiver_flags` (if not present) feature to the top of the toolchain
Adds `libraries_to_link` (if not present) feature to the top of the toolchain
Adds `force_pic_flags` (if not present) feature to the top of the toolchain
Adds `user_link_flags` (if not present) feature to the top of the toolchain
Adds `legacy_link_flags` (if not present) feature to the top of the toolchain
Adds `static_libgcc` (if not present) feature to the top of the toolchain
Adds `fission_support` (if not present) feature to the top of the toolchain
Adds `strip_debug_symbols` (if not present) feature to the top of the toolchain
Adds `coverage` (if not present) feature to the top of the toolchain
Adds `llvm_coverage_map_format` (if not present) feature to the top of the toolchain
Adds `gcc_coverage_map_format` (if not present) feature to the top of the toolchain
Adds `fully_static_link` (if not present) feature to the bottom of the toolchain
Adds `user_compile_flags` (if not present) feature to the bottom of the toolchain
Adds `sysroot` (if not present) feature to the bottom of the toolchain
Adds `unfiltered_compile_flags` (if not present) feature to the bottom of the toolchain
Adds `linker_param_file` (if not present) feature to the bottom of the toolchain
Adds `compiler_input_flags` (if not present) feature to the bottom of the toolchain
Adds `compiler_output_flags` (if not present) feature to the bottom of the toolchain
This is a long list of features. The plan is to get rid of them once
[Crosstool in Starlark](https://github.com/bazelbuild/bazel/issues/5380) is
done. For the curious reader see the implementation in
[CppActionConfigs](https://source.bazel.build/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java?q=cppactionconfigs\&ss=bazel),
and for production toolchains consider adding `no_legacy_features` to make
the toolchain more standalone.
# Configurable Build Attributes
Source: https://bazel.build/docs/configurable-attributes
***Configurable attributes***, commonly known as [`select()`](/reference/be/functions#select), is a Bazel feature that lets users toggle the values
of build rule attributes at the command line.
This can be used, for example, for a multiplatform library that automatically
chooses the appropriate implementation for the architecture, or for a
feature-configurable binary that can be customized at build time.
## Example
```python theme={null}
# myapp/BUILD
cc_binary(
name = "mybinary",
srcs = ["main.cc"],
deps = select({
":arm_build": [":arm_lib"],
":x86_debug_build": [":x86_dev_lib"],
"//conditions:default": [":generic_lib"],
}),
)
config_setting(
name = "arm_build",
values = {"cpu": "arm"},
)
config_setting(
name = "x86_debug_build",
values = {
"cpu": "x86",
"compilation_mode": "dbg",
},
)
```
This declares a `cc_binary` that "chooses" its deps based on the flags at the
command line. Specifically, `deps` becomes:
Command
deps =
`bazel build //myapp:mybinary --cpu=arm`
`[":arm_lib"]`
`bazel build //myapp:mybinary -c dbg --cpu=x86`
`[":x86_dev_lib"]`
`bazel build //myapp:mybinary --cpu=ppc`
`[":generic_lib"]`
`bazel build //myapp:mybinary -c dbg --cpu=ppc`
`[":generic_lib"]`
`select()` serves as a placeholder for a value that will be chosen based on
*configuration conditions*, which are labels referencing [`config_setting`](/reference/be/general#config_setting)
targets. By using `select()` in a configurable attribute, the attribute
effectively adopts different values when different conditions hold.
Matches must be unambiguous: if multiple conditions match then either:
* They all resolve to the same value. For example, when running on linux x86, this is unambiguous
`{"@platforms//os:linux": "Hello", "@platforms//cpu:x86_64": "Hello"}` because both branches resolve to "hello".
* One's `values` is a strict superset of all others'. For example, `values = {"cpu": "x86", "compilation_mode": "dbg"}`
is an unambiguous specialization of `values = {"cpu": "x86"}`.
The built-in condition [`//conditions:default`](#default-condition) automatically matches when
nothing else does.
While this example uses `deps`, `select()` works just as well on `srcs`,
`resources`, `cmd`, and most other attributes. Only a small number of attributes
are *non-configurable*, and these are clearly annotated. For example,
`config_setting`'s own
[`values`](/reference/be/general#config_setting.values) attribute is non-configurable.
## `select()` and dependencies
Certain attributes change the build parameters for all transitive dependencies
under a target. For example, `genrule`'s `tools` changes `--cpu` to the CPU of
the machine running Bazel (which, thanks to cross-compilation, may be different
than the CPU the target is built for). This is known as a
[configuration transition](/reference/glossary#transition).
Given
```python theme={null}
#myapp/BUILD
config_setting(
name = "arm_cpu",
values = {"cpu": "arm"},
)
config_setting(
name = "x86_cpu",
values = {"cpu": "x86"},
)
genrule(
name = "my_genrule",
srcs = select({
":arm_cpu": ["g_arm.src"],
":x86_cpu": ["g_x86.src"],
}),
tools = select({
":arm_cpu": [":tool1"],
":x86_cpu": [":tool2"],
}),
)
cc_binary(
name = "tool1",
srcs = select({
":arm_cpu": ["armtool.cc"],
":x86_cpu": ["x86tool.cc"],
}),
)
```
running
```sh theme={null}
$ bazel build //myapp:my_genrule --cpu=arm
```
on an `x86` developer machine binds the build to `g_arm.src`, `tool1`, and
`x86tool.cc`. Both of the `select`s attached to `my_genrule` use `my_genrule`'s
build parameters, which include `--cpu=arm`. The `tools` attribute changes
`--cpu` to `x86` for `tool1` and its transitive dependencies. The `select` on
`tool1` uses `tool1`'s build parameters, which include `--cpu=x86`.
## Configuration conditions
Each key in a configurable attribute is a label reference to a
[`config_setting`](/reference/be/general#config_setting) or
[`constraint_value`](/reference/be/platforms-and-toolchains#constraint_value).
`config_setting` is just a collection of
expected command line flag settings. By encapsulating these in a target, it's
easy to maintain "standard" conditions users can reference from multiple places.
`constraint_value` provides support for [multi-platform behavior](#platforms).
### Built-in flags
Flags like `--cpu` are built into Bazel: the build tool natively understands
them for all builds in all projects. These are specified with
[`config_setting`](/reference/be/general#config_setting)'s
[`values`](/reference/be/general#config_setting.values) attribute:
```python theme={null}
config_setting(
name = "meaningful_condition_name",
values = {
"flag1": "value1",
"flag2": "value2",
...
},
)
```
`flagN` is a flag name (without `--`, so `"cpu"` instead of `"--cpu"`). `valueN`
is the expected value for that flag. `:meaningful_condition_name` matches if
*every* entry in `values` matches. Order is irrelevant.
`valueN` is parsed as if it was set on the command line. This means:
* `values = { "compilation_mode": "opt" }` matches `bazel build -c opt`
* `values = { "force_pic": "true" }` matches `bazel build --force_pic=1`
* `values = { "force_pic": "0" }` matches `bazel build --noforce_pic`
`config_setting` only supports flags that affect target behavior. For example,
[`--show_progress`](/docs/user-manual#show-progress) isn't allowed because
it only affects how Bazel reports progress to the user. Targets can't use that
flag to construct their results. The exact set of supported flags isn't
documented. In practice, most flags that "make sense" work.
### Custom flags
You can model your own project-specific flags with
[Starlark build settings][BuildSettings]. Unlike built-in flags, these are
defined as build targets, so Bazel references them with target labels.
These are triggered with [`config_setting`](/reference/be/general#config_setting)'s
[`flag_values`](/reference/be/general#config_setting.flag_values)
attribute:
```python theme={null}
config_setting(
name = "meaningful_condition_name",
flag_values = {
"//myflags:flag1": "value1",
"//myflags:flag2": "value2",
...
},
)
```
Behavior is the same as for [built-in flags](#built-in-flags). See [here](https://github.com/bazelbuild/examples/tree/HEAD/configurations/select_on_build_setting)
for a working example.
[`--define`](/reference/command-line-reference#flag--define)
is an alternative legacy syntax for custom flags (for example
`--define foo=bar`). This can be expressed either in the
[values](/reference/be/general#config_setting.values) attribute
(`values = {"define": "foo=bar"}`) or the
[define\_values](/reference/be/general#config_setting.define_values) attribute
(`define_values = {"foo": "bar"}`). `--define` is only supported for backwards
compatibility. Prefer Starlark build settings whenever possible.
`values`, `flag_values`, and `define_values` evaluate independently. The
`config_setting` matches if all values across all of them match.
## The default condition
The built-in condition `//conditions:default` matches when no other condition
matches.
Because of the "exactly one match" rule, a configurable attribute with no match
and no default condition emits a `"no matching conditions"` error. This can
protect against silent failures from unexpected settings:
```python theme={null}
# myapp/BUILD
config_setting(
name = "x86_cpu",
values = {"cpu": "x86"},
)
cc_library(
name = "x86_only_lib",
srcs = select({
":x86_cpu": ["lib.cc"],
}),
)
```
```sh theme={null}
$ bazel build //myapp:x86_only_lib --cpu=arm
ERROR: Configurable attribute "srcs" doesn't match this configuration (would
a default condition help?).
Conditions checked:
//myapp:x86_cpu
```
For even clearer errors, you can set custom messages with `select()`'s
[`no_match_error`](#custom-error-messages) attribute.
## Platforms
While the ability to specify multiple flags on the command line provides
flexibility, it can also be burdensome to individually set each one every time
you want to build a target.
[Platforms](/extending/platforms)
let you consolidate these into simple bundles.
```python theme={null}
# myapp/BUILD
sh_binary(
name = "my_rocks",
srcs = select({
":basalt": ["pyroxene.sh"],
":marble": ["calcite.sh"],
"//conditions:default": ["feldspar.sh"],
}),
)
config_setting(
name = "basalt",
constraint_values = [
":black",
":igneous",
],
)
config_setting(
name = "marble",
constraint_values = [
":white",
":metamorphic",
],
)
# constraint_setting acts as an enum type, and constraint_value as an enum value.
constraint_setting(name = "color")
constraint_value(name = "black", constraint_setting = "color")
constraint_value(name = "white", constraint_setting = "color")
constraint_setting(name = "texture")
constraint_value(name = "smooth", constraint_setting = "texture")
constraint_setting(name = "type")
constraint_value(name = "igneous", constraint_setting = "type")
constraint_value(name = "metamorphic", constraint_setting = "type")
platform(
name = "basalt_platform",
constraint_values = [
":black",
":igneous",
],
)
platform(
name = "marble_platform",
constraint_values = [
":white",
":smooth",
":metamorphic",
],
)
```
The platform can be specified on the command line. It activates the
`config_setting`s that contain a subset of the platform's `constraint_values`,
allowing those `config_setting`s to match in `select()` expressions.
For example, in order to set the `srcs` attribute of `my_rocks` to `calcite.sh`,
you can simply run
```sh theme={null}
bazel build //my_app:my_rocks --platforms=//myapp:marble_platform
```
Without platforms, this might look something like
```sh theme={null}
bazel build //my_app:my_rocks --define color=white --define texture=smooth --define type=metamorphic
```
`select()` can also directly read `constraint_value`s:
```python theme={null}
constraint_setting(name = "type")
constraint_value(name = "igneous", constraint_setting = "type")
constraint_value(name = "metamorphic", constraint_setting = "type")
sh_binary(
name = "my_rocks",
srcs = select({
":igneous": ["igneous.sh"],
":metamorphic" ["metamorphic.sh"],
}),
)
```
This saves the need for boilerplate `config_setting`s when you only need to
check against single values.
Platforms are still under development. See the
[documentation](/concepts/platforms) for details.
## Combining `select()`s
`select` can appear multiple times in the same attribute:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"] +
select({
":armeabi_mode": ["armeabi_src.sh"],
":x86_mode": ["x86_src.sh"],
}) +
select({
":opt_mode": ["opt_extras.sh"],
":dbg_mode": ["dbg_extras.sh"],
}),
)
```
Note: Some restrictions apply on what can be combined in the `select`s values:
* Duplicate labels can appear in different paths of the same `select`.
* Duplicate labels can *not* appear within the same path of a `select`.
* Duplicate labels can *not* appear across multiple combined `select`s (no matter what path)
`select` cannot appear inside another `select`. If you need to nest `selects`
and your attribute takes other targets as values, use an intermediate target:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":armeabi_mode": [":armeabi_lib"],
...
}),
)
sh_library(
name = "armeabi_lib",
srcs = select({
":opt_mode": ["armeabi_with_opt.sh"],
...
}),
)
```
If you need a `select` to match when multiple conditions match, consider [AND chaining](#and-chaining).
## OR chaining
Consider the following:
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1": [":standard_lib"],
":config2": [":standard_lib"],
":config3": [":standard_lib"],
":config4": [":special_lib"],
}),
)
```
Most conditions evaluate to the same dep. But this syntax is hard to read and
maintain. It would be nice to not have to repeat `[":standard_lib"]` multiple
times.
One option is to predefine the value as a BUILD variable:
```python theme={null}
STANDARD_DEP = [":standard_lib"]
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1": STANDARD_DEP,
":config2": STANDARD_DEP,
":config3": STANDARD_DEP,
":config4": [":special_lib"],
}),
)
```
This makes it easier to manage the dependency. But it still causes unnecessary
duplication.
For more direct support, use one of the following:
### `selects.with_or`
The
[with\_or](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectswith_or)
macro in [Skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`selects`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md)
module supports `OR`ing conditions directly inside a `select`:
```python theme={null}
load("@bazel_skylib//lib:selects.bzl", "selects")
```
```python theme={null}
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = selects.with_or({
(":config1", ":config2", ":config3"): [":standard_lib"],
":config4": [":special_lib"],
}),
)
```
### `selects.config_setting_group`
The
[config\_setting\_group](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectsconfig_setting_group)
macro in [Skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`selects`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md)
module supports `OR`ing multiple `config_setting`s:
```python theme={null}
load("@bazel_skylib//lib:selects.bzl", "selects")
```
```python theme={null}
config_setting(
name = "config1",
values = {"cpu": "arm"},
)
config_setting(
name = "config2",
values = {"compilation_mode": "dbg"},
)
selects.config_setting_group(
name = "config1_or_2",
match_any = [":config1", ":config2"],
)
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1_or_2": [":standard_lib"],
"//conditions:default": [":other_lib"],
}),
)
```
Unlike `selects.with_or`, different targets can share `:config1_or_2` across
different attributes.
It's an error for multiple conditions to match unless one is an unambiguous
"specialization" of the others or they all resolve to the same value. See [here](#configurable-build-example) for details.
## AND chaining
If you need a `select` branch to match when multiple conditions match, use the
[Skylib](https://github.com/bazelbuild/bazel-skylib) macro
[config\_setting\_group](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/selects_doc.md#selectsconfig_setting_group):
```python theme={null}
config_setting(
name = "config1",
values = {"cpu": "arm"},
)
config_setting(
name = "config2",
values = {"compilation_mode": "dbg"},
)
selects.config_setting_group(
name = "config1_and_2",
match_all = [":config1", ":config2"],
)
sh_binary(
name = "my_target",
srcs = ["always_include.sh"],
deps = select({
":config1_and_2": [":standard_lib"],
"//conditions:default": [":other_lib"],
}),
)
```
Unlike OR chaining, existing `config_setting`s can't be directly `AND`ed
inside a `select`. You have to explicitly wrap them in a `config_setting_group`.
## Custom error messages
By default, when no condition matches, the target the `select()` is attached to
fails with the error:
```sh theme={null}
ERROR: Configurable attribute "deps" doesn't match this configuration (would
a default condition help?).
Conditions checked:
//tools/cc_target_os:darwin
//tools/cc_target_os:android
```
This can be customized with the [`no_match_error`](/reference/be/functions#select)
attribute:
```python theme={null}
cc_library(
name = "my_lib",
deps = select(
{
"//tools/cc_target_os:android": [":android_deps"],
"//tools/cc_target_os:windows": [":windows_deps"],
},
no_match_error = "Please build with an Android or Windows toolchain",
),
)
```
```sh theme={null}
$ bazel build //myapp:my_lib
ERROR: Configurable attribute "deps" doesn't match this configuration: Please
build with an Android or Windows toolchain
```
## Rules compatibility
Rule implementations receive the *resolved values* of configurable
attributes. For example, given:
```python theme={null}
# myapp/BUILD
some_rule(
name = "my_target",
some_attr = select({
":foo_mode": [":foo"],
":bar_mode": [":bar"],
}),
)
```
```sh theme={null}
$ bazel build //myapp/my_target --define mode=foo
```
Rule implementation code sees `ctx.attr.some_attr` as `[":foo"]`.
Macros can accept `select()` clauses and pass them through to native
rules. But *they cannot directly manipulate them*. For example, there's no way
for a macro to convert
```python theme={null}
select({"foo": "val"}, ...)
```
to
```python theme={null}
select({"foo": "val_with_suffix"}, ...)
```
This is for two reasons.
First, macros that need to know which path a `select` will choose *cannot work*
because macros are evaluated in Bazel's [loading phase](/run/build#loading),
which occurs before flag values are known.
This is a core Bazel design restriction that's unlikely to change any time soon.
Second, macros that just need to iterate over *all* `select` paths, while
technically feasible, lack a coherent UI. Further design is necessary to change
this.
## Bazel query and cquery
Bazel [`query`](/query/guide) operates over Bazel's
[loading phase](/reference/glossary#loading-phase).
This means it doesn't know what command line flags a target uses since those
flags aren't evaluated until later in the build (in the
[analysis phase](/reference/glossary#analysis-phase)).
So it can't determine which `select()` branches are chosen.
Bazel [`cquery`](/query/cquery) operates after Bazel's analysis phase, so it has
all this information and can accurately resolve `select()`s.
Consider:
```python theme={null}
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
```
```python theme={null}
# myapp/BUILD
string_flag(
name = "dog_type",
build_setting_default = "cat"
)
cc_library(
name = "my_lib",
deps = select({
":long": [":foo_dep"],
":short": [":bar_dep"],
}),
)
config_setting(
name = "long",
flag_values = {":dog_type": "dachshund"},
)
config_setting(
name = "short",
flag_values = {":dog_type": "pug"},
)
```
`query` overapproximates `:my_lib`'s dependencies:
```sh theme={null}
$ bazel query 'deps(//myapp:my_lib)'
//myapp:my_lib
//myapp:foo_dep
//myapp:bar_dep
```
while `cquery` shows its exact dependencies:
```sh theme={null}
$ bazel cquery 'deps(//myapp:my_lib)' --//myapp:dog_type=pug
//myapp:my_lib
//myapp:bar_dep
```
## FAQ
### Why doesn't select() work in macros?
select() *does* work in rules! See [Rules compatibility](#rules-compatibility) for
details.
The key issue this question usually means is that select() doesn't work in
*macros*. These are different than *rules*. See the
documentation on [rules](/extending/rules) and [macros](/extending/macros)
to understand the difference.
Here's an end-to-end example:
Define a rule and macro:
```python theme={null}
# myapp/defs.bzl
# Rule implementation: when an attribute is read, all select()s have already
# been resolved. So it looks like a plain old attribute just like any other.
def _impl(ctx):
name = ctx.attr.name
allcaps = ctx.attr.my_config_string.upper() # This works fine on all values.
print("My name is " + name + " with custom message: " + allcaps)
# Rule declaration:
my_custom_bazel_rule = rule(
implementation = _impl,
attrs = {"my_config_string": attr.string()},
)
# Macro declaration:
def my_custom_bazel_macro(name, my_config_string):
allcaps = my_config_string.upper() # This line won't work with select(s).
print("My name is " + name + " with custom message: " + allcaps)
```
Instantiate the rule and macro:
```python theme={null}
# myapp/BUILD
load("//myapp:defs.bzl", "my_custom_bazel_rule")
load("//myapp:defs.bzl", "my_custom_bazel_macro")
my_custom_bazel_rule(
name = "happy_rule",
my_config_string = select({
"//third_party/bazel_platforms/cpu:x86_32": "first string",
"//third_party/bazel_platforms/cpu:ppc": "second string",
}),
)
my_custom_bazel_macro(
name = "happy_macro",
my_config_string = "fixed string",
)
my_custom_bazel_macro(
name = "sad_macro",
my_config_string = select({
"//third_party/bazel_platforms/cpu:x86_32": "first string",
"//third_party/bazel_platforms/cpu:ppc": "other string",
}),
)
```
Building fails because `sad_macro` can't process the `select()`:
```sh theme={null}
$ bazel build //myapp:all
ERROR: /myworkspace/myapp/BUILD:17:1: Traceback
(most recent call last):
File "/myworkspace/myapp/BUILD", line 17
my_custom_bazel_macro(name = "sad_macro", my_config_stri..."}))
File "/myworkspace/myapp/defs.bzl", line 4, in
my_custom_bazel_macro
my_config_string.upper()
type 'select' has no method upper().
ERROR: error loading package 'myapp': Package 'myapp' contains errors.
```
Building succeeds when you comment out `sad_macro`:
```sh theme={null}
# Comment out sad_macro so it doesn't mess up the build.
$ bazel build //myapp:all
DEBUG: /myworkspace/myapp/defs.bzl:5:3: My name is happy_macro with custom message: FIXED STRING.
DEBUG: /myworkspace/myapp/hi.bzl:15:3: My name is happy_rule with custom message: FIRST STRING.
```
This is impossible to change because *by definition* macros are evaluated before
Bazel reads the build's command line flags. That means there isn't enough
information to evaluate select()s.
Macros can, however, pass `select()`s as opaque blobs to rules:
```python theme={null}
# myapp/defs.bzl
def my_custom_bazel_macro(name, my_config_string):
print("Invoking macro " + name)
my_custom_bazel_rule(
name = name + "_as_target",
my_config_string = my_config_string,
)
```
```sh theme={null}
$ bazel build //myapp:sad_macro_less_sad
DEBUG: /myworkspace/myapp/defs.bzl:23:3: Invoking macro sad_macro_less_sad.
DEBUG: /myworkspace/myapp/defs.bzl:15:3: My name is sad_macro_less_sad with custom message: FIRST STRING.
```
### Why does select() always return true?
Because *macros* (but not rules) by definition
[can't evaluate `select()`s](#faq-select-macro), any attempt to do so
usually produces an error:
```sh theme={null}
ERROR: /myworkspace/myapp/BUILD:17:1: Traceback
(most recent call last):
File "/myworkspace/myapp/BUILD", line 17
my_custom_bazel_macro(name = "sad_macro", my_config_stri..."}))
File "/myworkspace/myapp/defs.bzl", line 4, in
my_custom_bazel_macro
my_config_string.upper()
type 'select' has no method upper().
```
Booleans are a special case that fail silently, so you should be particularly
vigilant with them:
```sh theme={null}
$ cat myapp/defs.bzl
def my_boolean_macro(boolval):
print("TRUE" if boolval else "FALSE")
$ cat myapp/BUILD
load("//myapp:defs.bzl", "my_boolean_macro")
my_boolean_macro(
boolval = select({
"//third_party/bazel_platforms/cpu:x86_32": True,
"//third_party/bazel_platforms/cpu:ppc": False,
}),
)
$ bazel build //myapp:all --cpu=x86
DEBUG: /myworkspace/myapp/defs.bzl:4:3: TRUE.
$ bazel build //mypro:all --cpu=ppc
DEBUG: /myworkspace/myapp/defs.bzl:4:3: TRUE.
```
This happens because macros don't understand the contents of `select()`.
So what they're really evaluting is the `select()` object itself. According to
[Pythonic](https://docs.python.org/release/2.5.2/lib/truth.html) design
standards, all objects aside from a very small number of exceptions
automatically return true.
### Can I read select() like a dict?
Macros [can't](#faq-select-macro) evaluate select(s) because macros evaluate before
Bazel knows what the build's command line parameters are. Can they at least read
the `select()`'s dictionary to, for example, add a suffix to each value?
Conceptually this is possible, but [it isn't yet a Bazel feature](https://github.com/bazelbuild/bazel/issues/8419).
What you *can* do today is prepare a straight dictionary, then feed it into a
`select()`:
```sh theme={null}
$ cat myapp/defs.bzl
def selecty_genrule(name, select_cmd):
for key in select_cmd.keys():
select_cmd[key] += " WITH SUFFIX"
native.genrule(
name = name,
outs = [name + ".out"],
srcs = [],
cmd = "echo " + select(select_cmd + {"//conditions:default": "default"})
+ " > $@"
)
$ cat myapp/BUILD
selecty_genrule(
name = "selecty",
select_cmd = {
"//third_party/bazel_platforms/cpu:x86_32": "x86 mode",
},
)
$ bazel build //testapp:selecty --cpu=x86 && cat bazel-genfiles/testapp/selecty.out
x86 mode WITH SUFFIX
```
If you'd like to support both `select()` and native types, you can do this:
```sh theme={null}
$ cat myapp/defs.bzl
def selecty_genrule(name, select_cmd):
cmd_suffix = ""
if type(select_cmd) == "string":
cmd_suffix = select_cmd + " WITH SUFFIX"
elif type(select_cmd) == "dict":
for key in select_cmd.keys():
select_cmd[key] += " WITH SUFFIX"
cmd_suffix = select(select_cmd + {"//conditions:default": "default"})
native.genrule(
name = name,
outs = [name + ".out"],
srcs = [],
cmd = "echo " + cmd_suffix + "> $@",
)
```
### Why doesn't select() work with bind()?
First of all, do not use `bind()`. It is deprecated in favor of `alias()`.
The technical answer is that [`bind()`](/reference/be/workspace#bind) is a repo
rule, not a BUILD rule.
Repo rules do not have a specific configuration, and aren't evaluated in
the same way as BUILD rules. Therefore, a `select()` in a `bind()` can't
actually evaluate to any specific branch.
Instead, you should use [`alias()`](/reference/be/general#alias), with a `select()` in
the `actual` attribute, to perform this type of run-time determination. This
works correctly, since `alias()` is a BUILD rule, and is evaluated with a
specific configuration.
You can even have a `bind()` target point to an `alias()`, if needed.
```sh theme={null}
$ cat WORKSPACE
workspace(name = "myapp")
bind(name = "openssl", actual = "//:ssl")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(name = "alternative", ...)
http_archive(name = "boringssl", ...)
$ cat BUILD
config_setting(
name = "alt_ssl",
define_values = {
"ssl_library": "alternative",
},
)
alias(
name = "ssl",
actual = select({
"//:alt_ssl": "@alternative//:ssl",
"//conditions:default": "@boringssl//:ssl",
}),
)
```
With this setup, you can pass `--define ssl_library=alternative`, and any target
that depends on either `//:ssl` or `//external:ssl` will see the alternative
located at `@alternative//:ssl`.
But really, stop using `bind()`.
### Why doesn't my select() choose what I expect?
If `//myapp:foo` has a `select()` that doesn't choose the condition you expect,
use [cquery](/query/cquery) and `bazel config` to debug:
If `//myapp:foo` is the top-level target you're building, run:
```sh theme={null}
$ bazel cquery //myapp:foo
//myapp:foo (12e23b9a2b534a)
```
If you're building some other target `//bar` that depends on
//myapp:foo somewhere in its subgraph, run:
```sh theme={null}
$ bazel cquery 'somepath(//bar, //myapp:foo)'
//bar:bar (3ag3193fee94a2)
//bar:intermediate_dep (12e23b9a2b534a)
//myapp:foo (12e23b9a2b534a)
```
The `(12e23b9a2b534a)` next to `//myapp:foo` is a *hash* of the
configuration that resolves `//myapp:foo`'s `select()`. You can inspect its
values with `bazel config`:
```sh theme={null}
$ bazel config 12e23b9a2b534a
BuildConfigurationValue 12e23b9a2b534a
Fragment com.google.devtools.build.lib.analysis.config.CoreOptions {
cpu: darwin
compilation_mode: fastbuild
...
}
Fragment com.google.devtools.build.lib.rules.cpp.CppOptions {
linkopt: [-Dfoo=bar]
...
}
...
```
Then compare this output against the settings expected by each `config_setting`.
`//myapp:foo` may exist in different configurations in the same build. See the
[cquery docs](/query/cquery) for guidance on using `somepath` to get the right
one.
Caution: To prevent restarting the Bazel server, invoke `bazel config` with the
same command line flags as the `bazel cquery`. The `config` command relies on
the configuration nodes from the still-running server of the previous command.
### Why doesn't `select()` work with platforms?
Bazel doesn't support configurable attributes checking whether a given platform
is the target platform because the semantics are unclear.
For example:
```py theme={null}
platform(
name = "x86_linux_platform",
constraint_values = [
"@platforms//cpu:x86",
"@platforms//os:linux",
],
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":x86_linux_platform": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
In this `BUILD` file, which `select()` should be used if the target platform has both the
`@platforms//cpu:x86` and `@platforms//os:linux` constraints, but is **not** the
`:x86_linux_platform` defined here? The author of the `BUILD` file and the user
who defined the separate platform may have different ideas.
#### What should I do instead?
Instead, define a `config_setting` that matches **any** platform with
these constraints:
```py theme={null}
config_setting(
name = "is_x86_linux",
constraint_values = [
"@platforms//cpu:x86",
"@platforms//os:linux",
],
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":is_x86_linux": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
This process defines specific semantics, making it clearer to users what
platforms meet the desired conditions.
#### What if I really, really want to `select` on the platform?
If your build requirements specifically require checking the platform, you
can flip the value of the `--platforms` flag in a `config_setting`:
```py theme={null}
config_setting(
name = "is_specific_x86_linux_platform",
values = {
"platforms": ["//package:x86_linux_platform"],
},
)
cc_library(
name = "lib",
srcs = [...],
linkopts = select({
":is_specific_x86_linux_platform": ["--enable_x86_optimizations"],
"//conditions:default": [],
}),
)
```
The Bazel team doesn't endorse doing this; it overly constrains your build and
confuses users when the expected condition does not match.
[BuildSettings]: /extending/config#user-defined-build-settings
# bazel mobile-install
Source: https://bazel.build/docs/mobile-install
Fast iterative development for Android
This page describes how `bazel mobile-install` makes iterative development
for Android much faster. It describes the benefits of this approach versus the
drawbacks of separate build and install steps.
## Summary
To install small changes to an Android app very quickly, do the following:
1. Find the `android_binary` rule of the app you want to install.
2. Connect your device to `adb`.
3. Run `bazel mobile-install :your_target`. App startup will be a little
slower than usual.
4. Edit the code or Android resources.
5. Run `bazel mobile-install :your_target`.
6. Enjoy a fast and minimal incremental installation!
Some command line options to Bazel that may be useful:
* `--adb` tells Bazel which adb binary to use
* `--adb_arg` can be used to add extra arguments to the command line of `adb`.
One useful application of this is to select which device you want to install
to if you have multiple devices connected to your workstation:
`bazel mobile-install :your_target -- --adb_arg=-s --adb_arg=`
When in doubt, look at the
[example](https://github.com/bazelbuild/rules_android/tree/main/examples/basicapp),
contact us on [Google Groups](https://groups.google.com/forum/#!forum/bazel-discuss),
or [file a GitHub issue](https://github.com/bazelbuild/rules_android/issues)
## Introduction
One of the most important attributes of a developer's toolchain is speed: there
is a world of difference between changing the code and seeing it run within a
second and having to wait minutes, sometimes hours, before you get any feedback
on whether your changes do what you expect them to.
Unfortunately, the traditional Android toolchain for building an .apk entails
many monolithic, sequential steps and all of these have to be done in order to
build an Android app. At Google, waiting five minutes to build a single-line
change was not unusual on larger projects like Google Maps.
`bazel mobile-install` makes iterative development for Android much faster by
using a combination of change pruning, work sharding, and clever manipulation of
Android internals, all without changing any of your app's code.
## Problems with traditional app installation
Building an Android app has some issues, including:
* Dexing. By default, the Dexer tool (historically `dx`, now `d8` or `r8`)
is invoked exactly once in the build and it does not know how to reuse work from
previous builds: it dexes every method again, even though only one method was
changed.
* Uploading data to the device. adb does not use the full bandwidth of a USB 2.0
connection, and larger apps can take a lot of time to upload. The entire app is
uploaded, even if only small parts have changed, for example, a resource or a
single method, so this can be a major bottleneck.
* Compilation to native code. Android L introduced ART, a new Android runtime,
which compiles apps ahead-of-time rather than compiling them just-in-time like
Dalvik. This makes apps much faster at the cost of longer installation
time. This is a good tradeoff for users because they typically install an app
once and use it many times, but results in slower development where an app is
installed many times and each version is run at most a handful of times.
## The approach of `bazel mobile-install`
`bazel mobile-install `makes the following improvements:
* Sharded desugaring and dexing. After building the app's Java code, Bazel
shards the class files into approximately equal-sized parts and invokes `d8`
separately on them. `d8` is not invoked on shards that did not change since
the last build. These shards are then compiled into separate sharded APKs.
* Incremental file transfer. Android resources, .dex files, and native
libraries are removed from the main .apk and are stored in under a separate
mobile-install directory. This makes it possible to update code and Android
resources independently without reinstalling the whole app. Thus,
transferring the files takes less time and only the .dex files that have
changed are recompiled on-device.
* Sharded installation. Mobile-install uses Android Studio's
[`apkdeployer`](https://maven.google.com/web/index.html?q=deployer#com.android.tools.apkdeployer:apkdeployer)
tool to combine sharded APKs on the connected device and provide a cohesive
experience.
### Sharded Dexing
Sharded dexing is reasonably straightforward: once the .jar files are built, a
[tool](https://github.com/bazelbuild/rules_android/blob/main/src/tools/java/com/google/devtools/build/android/ziputils/DexMapper.java)
shards them into separate .jar files of approximately equal size, then invokes
`d8` on those that were changed since the previous build. The logic that
determines which shards to dex is not specific to Android: it just uses the
general change pruning algorithm of Bazel.
The first version of the sharding algorithm simply ordered the .class files
alphabetically, then cut the list up into equal-sized parts, but this proved to
be suboptimal: if a class was added or removed (even a nested or an anonymous
one), it would cause all the classes alphabetically after it to shift by one,
resulting in dexing those shards again. Thus, it was decided to shard Java
packages rather than individual classes. Of course, this still results in
dexing many shards if a new package is added or removed, but that is much less
frequent than adding or removing a single class.
The number of shards is controlled by command-line configuration, using the
`--define=num_dex_shards=N` flag. In an ideal world, Bazel would
automatically determine how many shards are best, but Bazel currently must know
the set of actions (for example, commands to be executed during the build) before
executing any of them, so it cannot determine the optimal number of shards
because it doesn't know how many Java classes there will eventually be in the
app. Generally speaking, the more shards, the faster the build and the
installation will be, but the slower app startup becomes, because the dynamic
linker has to do more work. The sweet spot is usually between 10 and 50 shards.
### Incremental deployment
Incremental APK shard transfer and installation is now handled by the
`apkdeployer` utility described in ["The approach of mobile-install"](#approach-mobile-install).
Whereas earlier (native) versions of mobile-install required manually tracking
first-time installations and selectively apply the `--incremental`
flag on subsequent installation, the most recent version in [`rules_android`](https://github.com/bazelbuild/rules_android/tree/main/mobile_install)
has been greatly simplified. The same mobile-install
invocation can be used regardless of how many times the app has been installed
or reinstalled.
At a high level, the `apkdeployer` tool is a wrapper around various `adb`
sub-commands. The main entrypoint logic can be found in the
[`com.android.tools.deployer.Deployer`](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:deploy/deployer/src/main/java/com/android/tools/deployer/Deployer.java)
class, with other utility classes colocated in the same package.
The `Deployer` class ingests, among other things, a list of paths to split
APKs and a protobuf with information about the installation, and leverages
deployment features for [Android app bundles](https://developer.android.com/guide/app-bundle)
in order to create an install session and incrementally deploy app splits.
See the [`ApkPreInstaller`](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:deploy/deployer/src/main/java/com/android/tools/deployer/ApkPreInstaller.java)
and [`ApkInstaller`](https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:deploy/deployer/src/main/java/com/android/tools/deployer/ApkInstaller.java)
classes for implementation details.
## Results
### Performance
In general, `bazel mobile-install` results in a 4x to 10x speedup of building
and installing large apps after a small change.
The following numbers were computed for a few Google products:

This, of course, depends on the nature of the change: recompilation after
changing a base library takes more time.
### Limitations
The tricks the stub application plays don't work in every case.
The following cases highlight where it does not work as expected:
* Mobile-install is only supported via the Starlark rules of `rules_android`.
See the ["brief history of mobile-install"](#mobile-install-history) for
more detail.
* Only devices running ART are supported. Mobile-install uses API and runtime features
that only exist on devices running ART, not Dalvik. Any Android runtime more
recent than Android L (API 21+) should be compatible.
* Bazel itself must be run with a tool Java runtime *and* language version
of 17 or higher.
* Bazel versions prior to 8.4.0 must specify some additional flags for
mobile-install. See [the Bazel Android tutorial](/start/android-app). These
flags inform Bazel where the Starlark mobile-install aspect is and which
rules are supported.
### A brief history of mobile-install
Earlier Bazel versions *natively* included built-in build and test rules for
popular languages and ecosystems such as C++, Java, and Android. These rules
were therefore referred to as *native* rules. Bazel 8 (released in 2024) removed
support for these rules because many of them had been migrated to the
[Starlark](/rules/language) language. See the ["Bazel 8.0 LTS blog post"](https://blog.bazel.build/2024/12/09/bazel-8-release.html)
for more details.
The legacy native Android rules also supported a legacy *native* version of
mobile-install functionality. This is referred to as "mobile-install v1" or
"native mobile-install" now. This functionality was deleted in Bazel 8, along
with the built-in Android rules.
Now, all mobile-install functionality, as well as all Android build and test
rules, are implemented in Starlark and reside in the `rules_android` GitHub
repository. The latest version is known as "mobile-install v3" or "MIv3".
*Naming note*: There was a "mobile-install **v2**" available only internally
at Google at one point, but this was never published externally, and only v3
continues to be used for both Google-internal and OSS rules\_android deployment.
# Sandboxing
Source: https://bazel.build/docs/sandboxing
This article covers sandboxing in Bazel and debugging your sandboxing
environment.
*Sandboxing* is a permission restricting strategy that isolates processes from
each other or from resources in a system. For Bazel, this means restricting file
system access.
Bazel's file system sandbox runs processes in a working directory that only
contains known inputs, such that compilers and other tools don't see source
files they should not access, unless they know the absolute paths to them.
Sandboxing doesn't hide the host environment in any way. Processes can freely
access all files on the file system. However, on platforms that support user
namespaces, processes can't modify any files outside their working directory.
This ensures that the build graph doesn't have hidden dependencies that could
affect the reproducibility of the build.
More specifically, Bazel constructs an `execroot/` directory for each action,
which acts as the action's work directory at execution time. `execroot/`
contains all input files to the action and serves as the container for any
generated outputs. Bazel then uses an operating-system-provided technique,
containers on Linux and `sandbox-exec` on macOS, to constrain the action within
`execroot/`.
## Reasons for sandboxing
* Without action sandboxing, Bazel doesn't know if a tool uses undeclared
input files (files that are not explicitly listed in the dependencies of an
action). When one of the undeclared input files changes, Bazel still
believes that the build is up-to-date and won’t rebuild the action. This can
result in an incorrect incremental build.
* Incorrect reuse of cache entries creates problems during remote caching. A
bad cache entry in a shared cache affects every developer on the project,
and wiping the entire remote cache is not a feasible solution.
* Sandboxing mimics the behavior of remote execution — if a build works well
with sandboxing, it will likely also work with remote execution. By making
remote execution upload all necessary files (including local tools), you can
significantly reduce maintenance costs for compile clusters compared to
having to install the tools on every machine in the cluster every time you
want to try out a new compiler or make a change to an existing tool.
## What sandbox strategy to use
You can choose which kind of sandboxing to use, if any, with the
[strategy flags](/docs/user-manual#strategy-options). Using the `sandboxed`
strategy makes Bazel pick one of the sandbox implementations listed below,
preferring an OS-specific sandbox to the less hermetic generic one.
[Persistent workers](/remote/persistent) run in a generic sandbox if you pass
the `--worker_sandboxing` flag. In addition to the plain boolean form, the flag
can be scoped to a specific worker-key mnemonic with
`--worker_sandboxing==` (for example
`--worker_sandboxing --worker_sandboxing=Javac=no` to sandbox all singleplex
workers except `Javac`; a later plain boolean value applies to all mnemonics
again).
The `local` (a.k.a. `standalone`) strategy does not do any kind of sandboxing.
It simply executes the action's command line with the working directory set to
the execroot of your workspace.
`processwrapper-sandbox` is a sandboxing strategy that does not require any
"advanced" features - it should work on any POSIX system out of the box. It
builds a sandbox directory consisting of symlinks that point to the original
source files, executes the action's command line with the working directory set
to this directory instead of the execroot, then moves the known output artifacts
out of the sandbox into the execroot and deletes the sandbox. This prevents the
action from accidentally using any input files that are not declared and from
littering the execroot with unknown output files.
`linux-sandbox` goes one step further and builds on top of the
`processwrapper-sandbox`. Similar to what Docker does under the hood, it uses
Linux Namespaces (User, Mount, PID, Network and IPC namespaces) to isolate the
action from the host. That is, it makes the entire filesystem read-only except
for the sandbox directory, so the action cannot accidentally modify anything on
the host filesystem. This prevents situations like a buggy test accidentally rm
-rf'ing your \$HOME directory. Optionally, you can also prevent the action from
accessing the network. `linux-sandbox` uses PID namespaces to prevent the action
from seeing any other processes and to reliably kill all processes (even daemons
spawned by the action) at the end.
`darwin-sandbox` is similar, but for macOS. It uses Apple's `sandbox-exec` tool
to achieve roughly the same as the Linux sandbox.
Both the `linux-sandbox` and the `darwin-sandbox` do not work in a "nested"
scenario due to restrictions in the mechanisms provided by the operating
systems. Because Docker also uses Linux namespaces for its container magic, you
cannot easily run `linux-sandbox` inside a Docker container, unless you use
`docker run --privileged`. On macOS, you cannot run `sandbox-exec` inside a
process that's already being sandboxed. Thus, in these cases, Bazel
automatically falls back to using `processwrapper-sandbox` (or `local` if no
sandbox strategy is supported).
If you want to prevent silent fallback and enforce a specific sandboxing
strategy — such as to ensure consistent, reproducible CI checks across
environments:
* **Enforce general sandboxing**: Pass `--spawn_strategy=sandboxed` (without
`local` in the fallback list). If sandboxing cannot execute, Bazel fails the
action rather than silently falling back to un-sandboxed execution (though
it still falls back to `processwrapper-sandbox` if OS namespaces are unsupported).
* **Enforce OS-level sandboxing (e.g. `linux-sandbox`)**: Explicitly request
the strategy by name, such as `--spawn_strategy=linux-sandbox` or
`--spawn_strategy=worker,linux-sandbox`. This is useful when builds or tests
strictly require kernel namespace features (such as network or mount isolation)
and must not quietly degrade to `processwrapper-sandbox`. If the requested
strategy is not supported on the host platform or environment, Bazel
immediately errors out at the start of the build (for example: `'linux-sandbox'
was requested for default strategies but no strategy with that identifier was registered`).
* **Best-effort sandboxing**: Pass multiple strategies separated by commas in
order of preference (for example, `--spawn_strategy=sandboxed,local` or
`--spawn_strategy=linux-sandbox,processwrapper-sandbox,local`). Bazel tries
each registered strategy in order.
* **Disable sandboxing completely**: Pass `--spawn_strategy=local`.
Dynamic execution usually requires sandboxing for local execution. To opt out,
pass the `--experimental_local_lockfree_output` flag. Dynamic execution silently
sandboxes [persistent workers](/remote/persistent).
## Downsides to sandboxing
* Sandboxing incurs extra setup and teardown cost. How big this cost is
depends on many factors, including the shape of the build and the
performance of the host OS. For Linux, sandboxed builds are rarely more than
a few percent slower. Setting `--reuse_sandbox_directories` can
mitigate the setup and teardown cost.
* Sandboxing effectively disables any cache the tool may have. You can
mitigate this by using [persistent workers](/remote/persistent), at
the cost of weaker sandbox guarantees.
* [Multiplex workers](/remote/multiplex) require explicit worker support
to be sandboxed. Workers that do not support multiplex sandboxing run as
singleplex workers under dynamic execution, which can cost extra memory.
## Debugging
Follow the strategies below to debug issues with sandboxing.
### Deactivated namespaces and containers
On some platforms, such as
[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/)
cluster nodes, Docker containers, or Debian/Ubuntu distributions, user
namespaces or mount operations may be restricted by default due to security
policies:
* **User namespace clone sysctl**: If `/proc/sys/kernel/unprivileged_userns_clone`
exists and contains `0`, you can activate user namespaces on the host with:
```posix-terminal theme={null}
sudo sysctl kernel.unprivileged_userns_clone=1
```
* **Docker / container privileges**: `linux-sandbox` requires the `CLONE_NEWUSER`,
`CLONE_NEWNS`, `CLONE_NEWPID`, and `CLONE_NEWIPC` clone flags and mount namespace
isolation (`mount(..., MS_REC | MS_PRIVATE, ...)`). In unprivileged Docker
containers, default seccomp profiles block the necessary `clone` or `mount`
syscalls. To run `linux-sandbox` inside Docker, launch the container with
`docker run --privileged` or grant the necessary capabilities and relax the
seccomp filter:
```posix-terminal theme={null}
docker run --cap-add=SYS_ADMIN --security-opt seccomp=unconfined ...
```
* **Kubernetes Pod security**: In Kubernetes, Pods running Bazel with
`linux-sandbox` require `securityContext.privileged: true` or
`securityContext.capabilities.add: ["SYS_ADMIN"]` with an unconfined seccomp
profile. If running in an unprivileged container where user namespaces cannot
be enabled, either use `--spawn_strategy=processwrapper-sandbox` for portable
symlink-based sandboxing without namespaces, or run Bazel builds via remote
execution (`--spawn_strategy=remote`).
### Rule execution failures
The sandbox may fail to execute rules because of the system setup. If you see a
message like `namespace-sandbox.c:633: execvp(argv[0], argv): No such file or
directory`, try to deactivate the sandbox with `--strategy=Genrule=local` for
genrules, and `--spawn_strategy=local` for other rules.
### Detailed debugging for build failures
If your build failed, use `--verbose_failures` and `--sandbox_debug` to make
Bazel show the exact command it ran when your build failed, including the part
that sets up the sandbox.
Example error message:
```
ERROR: path/to/your/project/BUILD:1:1: compilation of rule
'//path/to/your/project:all' failed:
Sandboxed execution failed, which may be legitimate (such as a compiler error),
or due to missing dependencies. To enter the sandbox environment for easier
debugging, run the following command in parentheses. On command failure, a bash
shell running inside the sandbox will then automatically be spawned
namespace-sandbox failed: error executing command
(cd /some/path && \
exec env - \
LANG=en_US \
PATH=/some/path/bin:/bin:/usr/bin \
PYTHONPATH=/usr/local/some/path \
/some/path/namespace-sandbox @/sandbox/root/path/this-sandbox-name.params --
/some/path/to/your/some-compiler --some-params some-target)
```
You can now inspect the generated sandbox directory and see which files Bazel
created and run the command again to see how it behaves.
Note that Bazel does not delete the sandbox directory when you use
`--sandbox_debug`. Unless you are actively debugging, you should disable
`--sandbox_debug` because it fills up your disk over time.
# Commands and Options
Source: https://bazel.build/docs/user-manual
This page covers the options that are available with various Bazel commands,
such as `bazel build`, `bazel run`, and `bazel test`. This page is a companion
to the list of Bazel's commands in [Build with Bazel](/run/build).
## Target syntax
Some commands, like `build` or `test`, can operate on a list of targets. They
use a syntax more flexible than labels, which is documented in
[Specifying targets to build](/run/build#specifying-build-targets).
## Options
The following sections describe the options available during a
build. When `--long` is used on a help command, the on-line
help messages provide summary information about the meaning, type and
default value for each option.
Most options can only be specified once. When specified multiple times, the
last instance wins. Options that can be specified multiple times are
identified in the on-line help with the text 'may be used multiple times'.
### Package location
#### `--package_path`
**WARNING:** The `--package_path` option is deprecated. Bazel prefers packages
in the main repository to be under the workspace root.
This option specifies the set of directories that are searched to
find the BUILD file for a given package.
Bazel finds its packages by searching the package path. This is a colon
separated ordered list of bazel directories, each being the root of a
partial source tree.
*To specify a custom package path* using the `--package_path` option:
Package path elements may be specified in three formats:
1. If the first character is `/`, the path is absolute.
2. If the path starts with `%workspace%`, the path is taken relative
to the nearest enclosing bazel directory.
For instance, if your working directory
is `/home/bob/clients/bob_client/bazel/foo`, then the
string `%workspace%` in the package-path is expanded
to `/home/bob/clients/bob_client/bazel`.
3. Anything else is taken relative to the working directory.
This is usually not what you mean to do,
and may behave unexpectedly if you use Bazel from directories below the bazel workspace.
For instance, if you use the package-path element `.`,
and then cd into the directory
`/home/bob/clients/bob_client/bazel/foo`, packages
will be resolved from the
`/home/bob/clients/bob_client/bazel/foo` directory.
If you use a non-default package path, specify it in your
[Bazel configuration file](/run/bazelrc) for convenience.
*Bazel doesn't require any packages to be in the
current directory*, so you can do a build from an empty bazel
workspace if all the necessary packages can be found somewhere else
on the package path.
Example: Building from an empty client
#### `--deleted_packages`
This option specifies a comma-separated list of packages which Bazel
should consider deleted, and not attempt to load from any directory
on the package path. This can be used to simulate the deletion of packages without
actually deleting them. This option can be passed multiple times, in which case
the individual lists are concatenated.
### Error checking
These options control Bazel's error-checking and/or warnings.
#### `--[no]check_visibility`
If this option is set to false, visibility checks are demoted to warnings.
The default value of this option is true, so that by default, visibility
checking is done.
#### `--output_filter=regex`
The `--output_filter` option will only show build and compilation
warnings for targets that match the regular expression. If a target does not
match the given regular expression and its execution succeeds, its standard
output and standard error are thrown away.
Here are some typical values for this option:
### Tool flags
These options control which options Bazel will pass to other tools.
#### `--copt=cc-option`
This option takes an argument which is to be passed to the compiler.
The argument will be passed to the compiler whenever it is invoked
for preprocessing, compiling, and/or assembling C, C++, or
assembler code. It will not be passed when linking.
This option can be used multiple times. For example:
% bazel build --copt="-g0" --copt="-fpic" //foo
will compile the `foo` library without debug tables, generating
position-independent code.
Note: Changing `--copt` settings will force a recompilation
of all affected object files. Also note that copts values listed in specific
cc\_library or cc\_binary build rules will be placed on the compiler command line
*after* these options.
Warning: C++-specific options (such as `-fno-implicit-templates`)
should be specified in `--cxxopt`, not in
`--copt`. Likewise, C-specific options (such as -Wstrict-prototypes)
should be specified in `--conlyopt`, not in `copt`.
Similarly, compiler options that only have an
effect at link time (such as `-l`) should be specified in
`--linkopt`, not in `--copt`.
#### `--host_copt=cc-option`
This option takes an argument which is to be passed to the compiler for source files
that are compiled in the exec configuration. This is analogous to
the [`--copt`](#copt) option, but applies only to the
exec configuration.
#### `--host_conlyopt=cc-option`
This option takes an argument which is to be passed to the compiler for C source files
that are compiled in the exec configuration. This is analogous to
the [`--conlyopt`](#cconlyopt) option, but applies only
to the exec configuration.
#### `--host_cxxopt=cc-option`
This option takes an argument which is to be passed to the compiler for C++ source files
that are compiled in the exec configuration. This is analogous to
the [`--cxxopt`](#cxxopt) option, but applies only to the
exec configuration.
#### `--host_linkopt=linker-option`
This option takes an argument which is to be passed to the linker for source files
that are compiled in the exec configuration. This is analogous to
the [`--linkopt`](#linkopt) option, but applies only to
the exec configuration.
#### `--conlyopt=cc-option`
This option takes an argument which is to be passed to the compiler when compiling C source files.
This is similar to `--copt`, but only applies to C compilation,
not to C++ compilation or linking. So you can pass C-specific options
(such as `-Wno-pointer-sign`) using `--conlyopt`.
Note: copts parameters listed in specific cc\_library or cc\_binary build rules
are placed on the compiler command line *after* these options.
#### `--cxxopt=cc-option`
This option takes an argument which is to be passed to the compiler when
compiling C++ source files.
This is similar to `--copt`, but only applies to C++ compilation,
not to C compilation or linking. So you can pass C++-specific options
(such as `-fpermissive` or `-fno-implicit-templates`) using `--cxxopt`.
For example:
Note: copts parameters listed in specific cc\_library or cc\_binary build rules
are placed on the compiler command line *after* these options.
#### `--linkopt=linker-option`
This option takes an argument which is to be passed to the compiler when linking.
This is similar to `--copt`, but only applies to linking,
not to compilation. So you can pass compiler options that only make sense
at link time (such as `-lssp` or `-Wl,--wrap,abort`)
using `--linkopt`. For example:
Build rules can also specify link options in their attributes. This option's
settings always take precedence. Also see
[cc\_library.linkopts](/reference/be/c-cpp#cc_library.linkopts).
#### `--strip (always|never|sometimes)`
This option determines whether Bazel will strip debugging information from
all binaries and shared libraries, by invoking the linker with the `-Wl,--strip-debug` option.
`--strip=always` means always strip debugging information.
`--strip=never` means never strip debugging information.
The default value of `--strip=sometimes` means strip if the `--compilation_mode`
is `fastbuild`.
% bazel build --strip=always //foo:bar
will compile the target while stripping debugging information from all generated
binaries.
Note: If you want debugging information, it's not enough to disable stripping;
you also need to make sure that the debugging information was generated by the
compiler, which you can do by using either `-c dbg` or `--copt -g`.
Bazel's `--strip` option corresponds with ld's `--strip-debug` option:
it only strips debugging information. If for some reason you want to strip *all* symbols,
not just *debug* symbols, you would need to use ld's `--strip-all` option,
which you can do by passing `--linkopt=-Wl,--strip-all` to Bazel. Also be
aware that setting Bazel's `--strip` flag will override
`--linkopt=-Wl,--strip-all`, so you should only set one or the other.
If you are only building a single binary and want all symbols stripped, you could also
pass `--stripopt=--strip-all` and explicitly build the
`//foo:bar.stripped` version of the target. As described in the section on
`--stripopt`, this applies a strip action after the final binary is
linked rather than including stripping in all of the build's link actions.
#### `--stripopt=strip-option`
This is an additional option to pass to the `strip` command when generating
a [`*.stripped` binary](/reference/be/c-cpp#cc_binary_implicit_outputs). The default
is `-S -p`. This option can be used multiple times.
Note: `--stripopt` does not apply to the stripping of the main
binary with `[--strip](#flag--strip)=(always|sometimes)`.
#### `--fdo_instrument=profile-output-dir`
The `--fdo_instrument` option enables the generation of
FDO (feedback directed optimization) profile output when the
built C/C++ binary is executed. For GCC, the argument provided is used as a
directory prefix for a per-object file directory tree of .gcda files
containing profile information for each .o file.
Once the profile data tree has been generated, the profile tree
should be zipped up, and provided to the
`--fdo_optimize=profile-zip`
Bazel option to enable the FDO-optimized compilation.
For the LLVM compiler the argument is also the directory under which the raw LLVM profile
data file(s) is dumped. For example:
`--fdo_instrument=/path/to/rawprof/dir/`.
The options `--fdo_instrument` and `--fdo_optimize` cannot be used at the same time.
#### `--fdo_optimize=profile-zip`
The `--fdo_optimize` option enables the use of the
per-object file profile information to perform FDO (feedback
directed optimization) optimizations when compiling. For GCC, the argument
provided is the zip file containing the previously-generated file tree
of .gcda files containing profile information for each .o file.
Alternatively, the argument provided can point to an auto profile
identified by the extension .afdo.
Note: This option also accepts labels that resolve to source files. You
may need to add an `exports_files` directive to the corresponding package to
make the file visible to Bazel.
For the LLVM compiler the argument provided should point to the indexed LLVM
profile output file prepared by the llvm-profdata tool, and should have a .profdata
extension.
The options `--fdo_instrument` and `--fdo_optimize` cannot be used at the same time.
#### `--java_language_version=version`
This option specifies the version of Java sources. For example:
compiles and allows only constructs compatible with Java 8 specification.
Default value is 11.
Possible values are: 8, 9, 10, 11, 17, and 21 and may be extended by
registering custom Java toolchains using `default_java_toolchain`.
#### `--tool_java_language_version=version`
The Java language version used to build tools that are executed during a build.
Default value is 11.
#### `--java_runtime_version=version`
This option specifies the version of JVM to use to execute the code and run the tests. For
example:
% bazel run --java\_runtime\_version=remotejdk\_11 java/com/example/common/foo:java\_application
downloads JDK 11 from a remote repository and run the Java application using it.
Default value is `local_jdk`.
Possible values are: `local_jdk`, `local_jdk_version`,
`remotejdk_11`, `remotejdk_17`, and `remotejdk_21`.
You can extend the values by registering custom JVM using either
`local_java_repository` or `remote_java_repository` repository rules.
#### `--tool_java_runtime_version=version`
The version of JVM used to execute tools that are needed during a build.
Default value is `remotejdk_11`.
#### `--jvmopt=jvm-option`
This option allows option arguments to be passed to the Java VM. It can be used
with one big argument, or multiple times with individual arguments. For example:
will use the server VM for launching all Java binaries and set the
startup heap size for the VM to 256 MB.
#### `--javacopt=javac-option`
This option allows option arguments to be passed to javac. It can be used
with one big argument, or multiple times with individual arguments. For example:
will rebuild a java\_binary with the javac default debug info
(instead of the bazel default).
The option is passed to javac after the Bazel built-in default options for
javac and before the per-rule options. The last specification of
any option to javac wins. The default options for javac are:
-source 8 -target 8 -encoding UTF-8
Note: Changing `--javacopt` settings will force a recompilation
of all affected classes. Also note that javacopts parameters listed in
specific java\_library or java\_binary build rules will be placed on the javac
command line *after* these options.
#### `--strict_java_deps (default|strict|off|warn|error)`
This option controls whether javac checks for missing direct dependencies.
Java targets must explicitly declare all directly used targets as
dependencies. This flag instructs javac to determine the jars actually used
for type checking each java file, and warn/error if they are not the output
of a direct dependency of the current target.
* `off` means checking is disabled.
* `warn` means javac will generate standard java warnings of
type `[strict]` for each missing direct dependency.
* `default`, `strict` and `error` all
mean javac will generate errors instead of warnings, causing the current
target to fail to build if any missing direct dependencies are found.
This is also the default behavior when the flag is unspecified.
### Build semantics
These options affect the build commands and/or the output file contents.
#### `--compilation_mode (fastbuild|opt|dbg)` (-c)
The `--compilation_mode` option (often shortened to `-c`,
especially `-c opt`) takes an argument of `fastbuild`, `dbg`
or `opt`, and affects various C/C++ code-generation
options, such as the level of optimization and the completeness of
debug tables. Bazel uses a different output directory for each
different compilation mode, so you can switch between modes without
needing to do a full rebuild *every* time.
* `fastbuild` means build as fast as possible:
generate minimal debugging information (`-gmlt
-Wl,-S`), and don't optimize. This is the
default. Note: `-DNDEBUG` will **not** be set.
* `dbg` means build with debugging enabled (`-g`),
so that you can use gdb (or another debugger).
* `opt` means build with optimization enabled and
with `assert()` calls disabled (`-O2 -DNDEBUG`).
Debugging information will not be generated in `opt` mode
unless you also pass `--copt -g`.
#### `--cpu=cpu`
This option specifies the target CPU architecture to be used for
the compilation of binaries during the build.
Note: A particular combination of crosstool version, compiler version,
and target CPU is allowed only if it has been specified in the currently
used CROSSTOOL file.
#### `--action_env=VAR=VALUE`
Specifies the set of environment variables available during the execution of all actions.
Variables can be either specified by name, in which case the value will be taken from the
invocation environment, or by the `name=value` pair which sets the value independent of the
invocation environment.
This `--action_env` flag can be specified multiple times. If a value is assigned to the same
variable across multiple `--action_env` flags, the latest assignment wins.
#### `--experimental_action_listener=label`
Warning: Extra actions are deprecated. Use
[aspects](/extending/aspects)
instead.
The `experimental_action_listener` option instructs Bazel to use
details from the [`action_listener`](/reference/be/extra-actions#action_listener) rule specified by label to
insert [`extra_actions`](/reference/be/extra-actions#extra_action) into the build graph.
#### `--[no]experimental_extra_action_top_level_only`
Warning: Extra actions are deprecated. Use
[aspects](/extending/aspects) instead.
If this option is set to true, extra actions specified by the
[ `--experimental_action_listener`](#experimental-action-listener) command
line option will only be scheduled for top level targets.
#### `--experimental_extra_action_filter=regex`
Warning: Extra actions are deprecated. Use
[aspects](/extending/aspects) instead.
The `experimental_extra_action_filter` option instructs Bazel to
filter the set of targets to schedule `extra_actions` for.
This flag is only applicable in combination with the
[`--experimental_action_listener`](#experimental-action-listener) flag.
By default all `extra_actions` in the transitive closure of the
requested targets-to-build get scheduled for execution.
`--experimental_extra_action_filter` will restrict scheduling to
`extra_actions` of which the owner's label matches the specified
regular expression.
The following example will limit scheduling of `extra_actions`
to only apply to actions of which the owner's label contains '/bar/':
#### `--host_cpu=cpu`
This option specifies the name of the CPU architecture that should be
used to build host tools.
#### `--android_platforms=platform[,platform]*`
The platforms to build the transitive `deps` of
`android_binary` rules (specifically for native dependencies like C++). For
example, if a `cc_library` appears in the transitive `deps` of an
`android_binary` rule it is be built once for each platform specified with
`--android_platforms` for the `android_binary` rule, and included in the final
output.
There is no default value for this flag: a custom Android platform must be
defined and used.
One `.so` file is created and packaged in the APK for each platform specified
with `--android_platforms`. The `.so` file's name prefixes the name of the
`android_binary` rule with "lib". For example, if the name of the
`android_binary` is "foo", then the file is `libfoo.so`.
#### `--per_file_copt=[+-]regex[,[+-]regex]...@option[,option]...`
When present, any C++ file with a label or an execution path matching one of the inclusion regex
expressions and not matching any of the exclusion expressions will be built
with the given options. The label matching uses the canonical form of the label
(i.e //`package`:`label_name`).
The execution path is the relative path to your workspace directory including the base name
(including extension) of the C++ file. It also includes any platform dependent prefixes.
Note: If only one of the label or the execution path matches the options will be used.
To match the generated files (such as genrule outputs)
Bazel can only use the execution path. In this case the regexp shouldn't start with '//'
since that doesn't match any execution paths. Package names can be used like this:
`--per_file_copt=base/.*\.pb\.cc@-g0`. This will match every
`.pb.cc` file under a directory called `base`.
This option can be used multiple times.
The option is applied regardless of the compilation mode used. For example, it is possible
to compile with `--compilation_mode=opt` and selectively compile some
files with stronger optimization turned on, or with optimization disabled.
**Caveat**: If some files are selectively compiled with debug symbols the symbols
might be stripped during linking. This can be prevented by setting
`--strip=never`.
**Syntax**: `[+-]regex[,[+-]regex]...@option[,option]...` Where
`regex` stands for a regular expression that can be prefixed with
a `+` to identify include patterns and with `-` to identify
exclude patterns. `option` stands for an arbitrary option that is passed
to the C++ compiler. If an option contains a `,` it has to be quoted like so
`\,`. Options can also contain `@`, since only the first
`@` is used to separate regular expressions from options.
**Example**:
`--per_file_copt=//foo:.*\.cc,-//foo:file\.cc@-O0,-fprofile-arcs`
adds the `-O0` and the `-fprofile-arcs` options to the command
line of the C++ compiler for all `.cc` files in `//foo/` except `file.cc`.
#### `--dynamic_mode=mode`
Determines whether C++ binaries will be linked dynamically, interacting with
the [linkstatic attribute](/reference/be/c-cpp#cc_binary.linkstatic) on build rules.
Modes:
* `default`: Allows bazel to choose whether to link dynamically.
See [linkstatic](/reference/be/c-cpp#cc_binary.linkstatic) for more
information.
* `fully`: Links all targets dynamically. This will speed up
linking time, and reduce the size of the resulting binaries.
* `off`: Links all targets in
[mostly static](/reference/be/c-cpp#cc_binary.linkstatic) mode.
If `-static` is set in linkopts, targets will change to fully static.
#### `--fission (yes|no|[dbg][,opt][,fastbuild])`
Enables [Fission](https://gcc.gnu.org/wiki/DebugFission),
which writes C++ debug information to dedicated .dwo files instead of .o files, where it would
otherwise go. This substantially reduces the input size to links and can reduce link times.
When set to `[dbg][,opt][,fastbuild]` (example:
`--fission=dbg,fastbuild`), Fission is enabled
only for the specified set of compilation modes. This is useful for bazelrc
settings. When set to `yes`, Fission is enabled
universally. When set to `no`, Fission is disabled
universally. Default is `no`.
#### `--force_ignore_dash_static`
If this flag is set, any `-static` options in linkopts of
`cc_*` rules BUILD files are ignored. This is only intended as a
workaround for C++ hardening builds.
#### `--[no]force_pic`
If enabled, all C++ compilations produce position-independent code ("-fPIC"),
links prefer PIC pre-built libraries over non-PIC libraries, and links produce
position-independent executables ("-pie"). Default is disabled.
Note: Dynamically linked binaries (for example `--dynamic_mode fully`)
generate PIC code regardless of this flag's setting. So this flag is for cases
where users want PIC code explicitly generated for static links.
#### `--android_resource_shrinking`
Selects whether to perform resource shrinking for android\_binary rules. Sets the default for the
[shrink\_resources attribute](/reference/be/android#android_binary.shrink_resources) on
android\_binary rules; see the documentation for that rule for further details. Defaults to off.
#### `--custom_malloc=malloc-library-target`
When specified, always use the given malloc implementation, overriding all
`malloc="target"` attributes, including in those targets that use the
default (by not specifying any `malloc`).
#### `--crosstool_top=label`
This option specifies the location of the crosstool compiler suite
to be used for all C++ compilation during a build. Bazel will look in that
location for a CROSSTOOL file and uses that to automatically determine
settings for `--compiler`.
#### `--host_crosstool_top=label`
If not specified, Bazel uses the value of `--crosstool_top` to compile
code in the exec configuration, such as tools run during the build. The main purpose of this flag
is to enable cross-compilation.
#### `--apple_crosstool_top=label`
The crosstool to use for compiling C/C++ rules in the transitive `deps` of
objc\_*, ios\_\_*, and apple\_\* rules. For those targets, this flag overwrites
`--crosstool_top`.
#### `--compiler=version`
This option specifies the C/C++ compiler version (such as `gcc-4.1.0`)
to be used for the compilation of binaries during the build. If you want to
build with a custom crosstool, you should use a CROSSTOOL file instead of
specifying this flag.
Note: Only certain combinations of crosstool version, compiler version,
and target CPU are allowed.
#### `--android_sdk=label`
Deprecated. This shouldn't be directly specified.
This option specifies the Android SDK/platform toolchain
and Android runtime library that will be used to build any Android-related
rule.
The Android SDK will be automatically selected if an `android_sdk_repository`
rule is defined in the WORKSPACE file.
#### `--java_toolchain=label`
No-op. Kept only for backwards compatibility.
#### `--host_java_toolchain=label`
No-op. Kept only for backwards compatibility.
#### `--javabase=(label)`
No-op. Kept only for backwards compatibility.
#### `--host_javabase=label`
No-op. Kept only for backwards compatibility.
### Execution strategy
These options affect how Bazel will execute the build.
They should not have any significant effect on the output files
generated by the build. Typically their main effect is on the
speed of the build.
#### `--spawn_strategy=strategy`
This option controls where and how commands are executed.
* `standalone` causes commands to be executed as local subprocesses. This value is
deprecated. Please use `local` instead.
* `sandboxed` causes commands to be executed inside a sandbox on the local machine.
This requires that all input files, data dependencies and tools are listed as direct
dependencies in the `srcs`, `data` and `tools` attributes.
Bazel enables local sandboxing by default, on systems that support sandboxed execution.
* `processwrapper-sandbox` causes commands to be executed inside a portable symlink-based
sandbox without OS-specific namespace or container mechanisms.
* `linux-sandbox` causes commands to be executed inside a Linux namespace sandbox (using
User, Mount, PID, Network, and IPC namespaces).
* `darwin-sandbox` causes commands to be executed inside a macOS sandbox using `sandbox-exec`.
* `windows-sandbox` causes commands to be executed inside a Windows sandbox.
* `local` causes commands to be executed as local subprocesses.
* `worker` causes commands to be executed using a persistent worker, if available.
* `docker` causes commands to be executed inside a docker sandbox on the local machine.
This requires that docker is installed.
* `remote` causes commands to be executed remotely; this is only available if a
remote executor has been configured separately.
#### `--strategy mnemonic=strategy`
This option controls where and how commands are executed, overriding the
[--spawn\_strategy](#spawn-strategy) (and
[--genrule\_strategy](#genrule-strategy) with mnemonic
Genrule) on a per-mnemonic basis. See
[--spawn\_strategy](#spawn-strategy) for the supported
strategies and their effects.
#### `--strategy_regexp==`
This option specifies which strategy should be used to execute commands that have descriptions
matching a certain `regex_filter`. See
[--per\_file\_copt](#per-file-copt) for details on
regex\_filter matching. See
[--spawn\_strategy](#spawn-strategy) for the supported
strategies and their effects.
The last `regex_filter` that matches the description is used. This option overrides
other flags for specifying strategy.
* Example: `--strategy_regexp=//foo.*\\.cc,-//foo/bar=local` means to run actions using
`local` strategy if their descriptions match //foo.\*.cc but not //foo/bar.
* Example:
`--strategy_regexp='Compiling.*/bar=local' --strategy_regexp=Compiling=sandboxed`
runs 'Compiling //foo/bar/baz' with the `sandboxed` strategy, but reversing
the order runs it with `local`.
* Example: `--strategy_regexp='Compiling.*/bar=local,sandboxed'` runs
'Compiling //foo/bar/baz' with the `local` strategy and falls back to
`sandboxed` if it fails.
#### `--genrule_strategy=strategy`
This is a deprecated short-hand for `--strategy=Genrule=strategy`.
#### `--jobs=n` (-j)
This option, which takes an integer argument, specifies a limit on
the number of jobs that should be executed concurrently during the
execution phase of the build.
Note : The number of concurrent jobs that Bazel will run
is determined not only by the `--jobs` setting, but also
by Bazel's scheduler, which tries to avoid running concurrent jobs
that will use up more resources (RAM or CPU) than are available,
based on some (very crude) estimates of the resource consumption
of each job. The behavior of the scheduler can be controlled by
the `--local_resources` option.
#### `--progress_report_interval=n`
Bazel periodically prints a progress report on jobs that are not
finished yet (such as long running tests). This option sets the
reporting frequency, progress will be printed every `n`
seconds.
The default is 0, that means an incremental algorithm: the first
report will be printed after 10 seconds, then 30 seconds and after
that progress is reported once every minute.
When bazel is using cursor control, as specified by
[`--curses`](#curses), progress is reported every second.
#### `--local_resources resources or resource expression`
These options specify the amount of local resources (RAM in MB and number of CPU logical cores)
that Bazel can take into consideration when scheduling build and test activities to run locally. They take
an float, or a keyword (HOST\_RAM or HOST\_CPUS) optionally followed by `[-|*`float`]`
(for example, `--local_resources=cpu=2`, `--local_resources=memory=HOST_RAM*.5`,
`--local_resources=cpu=HOST_CPUS-1`).
The flags are independent; one or both may be set. By default, Bazel estimates
the amount of RAM and number of CPU cores directly from the local system's configuration.
#### `--[no]build_runfile_links`
This option, which is enabled by default, specifies whether the runfiles
symlinks for tests and binaries should be built in the output directory.
Using `--nobuild_runfile_links` can be useful
to validate if all targets compile without incurring the overhead
for building the runfiles trees.
When tests (or applications) are executed, their run-time data
dependencies are gathered together in one place. Within Bazel's
output tree, this "runfiles" tree is typically rooted as a sibling of
the corresponding binary or test.
During test execution, runfiles may be accessed using paths of the form
`$TEST_SRCDIR/canonical_repo_name/packagename/filename`.
The runfiles tree ensures that tests have access to all the files
upon which they have a declared dependence, and nothing more. By
default, the runfiles tree is implemented by constructing a set of
symbolic links to the required files. As the set of links grows, so
does the cost of this operation, and for some large builds it can
contribute significantly to overall build time, particularly because
each individual test (or application) requires its own runfiles tree.
#### `--[no]build_runfile_manifests`
This option, which is enabled by default, specifies whether runfiles manifests
should be written to the output tree.
Disabling it implies `--nobuild_runfile_links`.
It can be disabled when executing tests remotely, as runfiles trees will
be created remotely from in-memory manifests.
#### `--[no]discard_analysis_cache`
When this option is enabled, Bazel will discard the analysis cache
right before execution starts, thus freeing up additional memory
(around 10%) for the [execution phase](/run/build#execution).
The drawback is that further incremental builds will be slower. See also
[memory-saving mode](/configure/memory).
#### `--[no]keep_going` (-k)
As in GNU Make, the execution phase of a build stops when the first
error is encountered. Sometimes it is useful to try to build as
much as possible even in the face of errors. This option enables
that behavior, and when it is specified, the build will attempt to
build every target whose prerequisites were successfully built, but
will ignore errors.
While this option is usually associated with the execution phase of
a build, it also affects the analysis phase: if several targets are
specified in a build command, but only some of them can be
successfully analyzed, the build will stop with an error
unless `--keep_going` is specified, in which case the
build will proceed to the execution phase, but only for the targets
that were successfully analyzed.
#### `--[no]use_ijars`
This option changes the way `java_library` targets are
compiled by Bazel. Instead of using the output of a
`java_library` for compiling dependent
`java_library` targets, Bazel will create interface jars
that contain only the signatures of non-private members (public,
protected, and default (package) access methods and fields) and use
the interface jars to compile the dependent targets. This makes it
possible to avoid recompilation when changes are only made to
method bodies or private members of a class.
Note: Using `--use_ijars` might give you a different
error message when you are accidentally referring to a non visible
member of another class: Instead of getting an error that the member
is not visible you will get an error that the member does not exist.
Changing the `--use_ijars` setting will force a recompilation of all affected
classes.
#### `--[no]interface_shared_objects`
This option enables *interface shared objects*, which makes binaries and
other shared libraries depend on the *interface* of a shared object,
rather than its implementation. When only the implementation changes, Bazel
can avoid rebuilding targets that depend on the changed shared library
unnecessarily.
### Output selection
These options determine what to build or test.
#### `--[no]build`
This option causes the execution phase of the build to occur; it is
on by default. When it is switched off, the execution phase is
skipped, and only the first two phases, loading and analysis, occur.
This option can be useful for validating BUILD files and detecting
errors in the inputs, without actually building anything.
#### `--[no]build_tests_only`
If specified, Bazel will build only what is necessary to run the `*_test`
and `test_suite` rules that were not filtered due to their
[size](#test-size-filters),
[timeout](#test-timeout-filters),
[tag](#test-tag-filters), or
[language](#test-lang-filters).
If specified, Bazel will ignore other targets specified on the command line.
By default, this option is disabled and Bazel will build everything
requested, including `*_test` and `test_suite` rules that are filtered out from
testing. This is useful because running
`bazel test --build_tests_only foo/...` may not detect all build
breakages in the `foo` tree.
#### `--[no]check_up_to_date`
This option causes Bazel not to perform a build, but merely check
whether all specified targets are up-to-date. If so, the build
completes successfully, as usual. However, if any files are out of
date, instead of being built, an error is reported and the build
fails. This option may be useful to determine whether a build has
been performed more recently than a source edit (for example, for pre-submit
checks) without incurring the cost of a build.
See also [`--check_tests_up_to_date`](#check-tests-up-to-date).
#### `--[no]compile_one_dependency`
Compile a single dependency of the argument files. This is useful for
syntax checking source files in IDEs, for example, by rebuilding a single
target that depends on the source file to detect errors as early as
possible in the edit/build/test cycle. This argument affects the way all
non-flag arguments are interpreted: each argument must be a
file target label or a plain filename relative to the current working
directory, and one rule that depends on each source filename is built. For
C++ and Java
sources, rules in the same language space are preferentially chosen. For
multiple rules with the same preference, the one that appears first in the
BUILD file is chosen. An explicitly named target pattern which does not
reference a source file results in an error.
#### `--save_temps`
The `--save_temps` option causes temporary outputs from the compiler to be
saved. These include .s files (assembler code), .i (preprocessed C) and .ii
(preprocessed C++) files. These outputs are often useful for debugging. Temps will only be
generated for the set of targets specified on the command line.
Note: The implementation of `--save_temps` does not use the compiler's
`-save-temps` flag. Instead, there are two passes, one with `-S`
and one with `-E`. A consequence of this is that if your build fails,
Bazel may not yet have produced the ".i" or ".ii" and ".s" files.
If you're trying to use `--save_temps` to debug a failed compilation,
you may need to also use `--keep_going` so that Bazel will still try to
produce the preprocessed files after the compilation fails.
The `--save_temps` flag currently works only for cc\_\* rules.
To ensure that Bazel prints the location of the additional output files, check that
your [`--show_result n`](#show-result)
setting is high enough.
#### `--build_tag_filters=tag[,tag]*`
If specified, Bazel will build only targets that have at least one required tag
(if any of them are specified) and does not have any excluded tags. Build tag
filter is specified as comma delimited list of tag keywords, optionally
preceded with '-' sign used to denote excluded tags. Required tags may also
have a preceding '+' sign.
When running tests, Bazel ignores `--build_tag_filters` for test targets,
which are built and run even if they do not match this filter. To avoid building them, filter
test targets using `--test_tag_filters` or by explicitly excluding them.
#### `--test_size_filters=size[,size]*`
If specified, Bazel will test (or build if `--build_tests_only`
is also specified) only test targets with the given size. Test size filter
is specified as comma delimited list of allowed test size values (small,
medium, large or enormous), optionally preceded with '-' sign used to denote
excluded test sizes. For example,
% bazel test --test\_size\_filters=small,medium //foo:all
and
% bazel test --test\_size\_filters=-large,-enormous //foo:all
will test only small and medium tests inside //foo.
By default, test size filtering is not applied.
#### `--test_timeout_filters=timeout[,timeout]*`
If specified, Bazel will test (or build if `--build_tests_only`
is also specified) only test targets with the given timeout. Test timeout filter
is specified as comma delimited list of allowed test timeout values (short,
moderate, long or eternal), optionally preceded with '-' sign used to denote
excluded test timeouts. See [--test\_size\_filters](#test-size-filters)
for example syntax.
By default, test timeout filtering is not applied.
#### `--test_tag_filters=tag[,tag]*`
If specified, Bazel will test (or build if `--build_tests_only`
is also specified) only test targets that have at least one required tag
(if any of them are specified) and does not have any excluded tags. Test tag
filter is specified as comma delimited list of tag keywords, optionally
preceded with '-' sign used to denote excluded tags. Required tags may also
have a preceding '+' sign.
For example,
% bazel test --test\_tag\_filters=performance,stress,-flaky //myproject:all
will test targets that are tagged with either `performance` or
`stress` tag but are **not** tagged with the `flaky` tag.
By default, test tag filtering is not applied. Note that you can also filter
on test's `size` and `local` tags in
this manner.
#### `--test_lang_filters=string[,string]*`
Specifies a comma-separated list of strings referring to names of test rule
classes. To refer to the rule class `foo_test`, use the string "foo". Bazel will
test (or build if `--build_tests_only` is also specified) only
targets of the referenced rule classes. To instead exclude those targets, use
the string "-foo". For example,
% bazel test --test\_lang\_filters=foo,bar //baz/...
will test only targets that are instances of `foo_test` or `bar_test` in
`//baz/...`, while
% bazel test --test\_lang\_filters=-foo,-bar //baz/...
will test all the targets in `//baz/...` except for the `foo_test` and
`bar_test` instances.
Tip: You can use `bazel query --output=label_kind "//p:t"` to
learn the rule class name of the target `//p:t`. And you can
look at the pair of instantiation stacks in the output of
`bazel query --output=build "//p:t"` to learn why that target
is an instance of that rule class.
Warning: The option name "--test\_lang\_filter" is vestigal and is therefore
unfortunately misleading; don't make assumptions about the semantics based on
the name.
#### `--test_filter=filter-expression`
Specifies a filter that the test runner may use to pick a subset of tests for
running. All targets specified in the invocation are built, but depending on
the expression only some of them may be executed; in some cases, only certain
test methods are run.
The particular interpretation of filter-expression is up to
the test framework responsible for running the test. It may be a glob,
substring, or regexp. `--test_filter` is a convenience
over passing different `--test_arg` filter arguments,
but not all frameworks support it.
### Verbosity
These options control the verbosity of Bazel's output,
either to the terminal, or to additional log files.
#### `--explain=logfile`
This option, which requires a filename argument, causes the
dependency checker in `bazel build`'s execution phase to
explain, for each build step, either why it is being executed, or
that it is up-to-date. The explanation is written
to *logfile*.
If you are encountering unexpected rebuilds, this option can help to
understand the reason. Add it to your `.bazelrc` so that
logging occurs for all subsequent builds, and then inspect the log
when you see an execution step executed unexpectedly. This option
may carry a small performance penalty, so you might want to remove
it when it is no longer needed.
#### `--verbose_explanations`
This option increases the verbosity of the explanations generated
when the [--explain](#explain) option is enabled.
In particular, if verbose explanations are enabled,
and an output file is rebuilt because the command used to
build it has changed, then the output in the explanation file will
include the full details of the new command (at least for most
commands).
Using this option may significantly increase the length of the
generated explanation file and the performance penalty of using
`--explain`.
If `--explain` is not enabled, then
`--verbose_explanations` has no effect.
#### `--profile=file`
This option, which takes a filename argument, causes Bazel to write
profiling data into a file. The build profile can be useful in understanding
where Bazel's `build` command is spending its time. See
[JSON trace profile](/advanced/performance/json-trace-profile) for profile
format and tooling details.
#### `--[no]show_loading_progress`
This option causes Bazel to output package-loading progress
messages. If it is disabled, the messages won't be shown.
#### `--[no]show_progress`
This option causes progress messages to be displayed; it is on by
default. When disabled, progress messages are suppressed.
#### `--show_progress_rate_limit=n`
This option causes bazel to display at most one progress message per `n` seconds,
where n is a real number.
The default value for this option is 0.02, meaning bazel will limit the progress
messages to one per every 0.02 seconds.
#### `--show_result=n`
This option controls the printing of result information at the end
of a `bazel build` command. By default, if a single
build target was specified, Bazel prints a message stating whether
or not the target was successfully brought up-to-date, and if so,
the list of output files that the target created. If multiple
targets were specified, result information is not displayed.
While the result information may be useful for builds of a single
target or a few targets, for large builds (such as an entire top-level
project tree), this information can be overwhelming and distracting;
this option allows it to be controlled. `--show_result`
takes an integer argument, which is the maximum number of targets
for which full result information should be printed. By default,
the value is 1. Above this threshold, no result information is
shown for individual targets. Thus zero causes the result
information to be suppressed always, and a very large value causes
the result to be printed always.
Users may wish to choose a value in-between if they regularly
alternate between building a small group of targets (for example,
during the compile-edit-test cycle) and a large group of targets
(for example, when establishing a new workspace or running
regression tests). In the former case, the result information is
very useful whereas in the latter case it is less so. As with all
options, this can be specified implicitly via
the [`.bazelrc`](/run/bazelrc) file.
The files are printed so as to make it easy to copy and paste the
filename to the shell, to run built executables. The "up-to-date"
or "failed" messages for each target can be easily parsed by scripts
which drive a build.
#### `--sandbox_debug`
This option causes Bazel to print extra debugging information when using sandboxing for action
execution. This option also preserves sandbox directories, so that the files visible to actions
during execution can be examined.
#### `--subcommands` (`-s`)
This option causes Bazel's execution phase to print the full command line
for each command prior to executing it.
```
>>>> # //examples/cpp:hello-world [action 'Linking examples/cpp/hello-world']
(cd /home/johndoe/.cache/bazel/_bazel_johndoe/4c084335afceb392cfbe7c31afee3a9f/bazel && \
exec env - \
/usr/bin/gcc -o bazel-out/local-fastbuild/bin/examples/cpp/hello-world -B/usr/bin/ -Wl,-z,relro,-z,now -no-canonical-prefixes -pass-exit-codes -Wl,-S -Wl,@bazel-out/local_linux-fastbuild/bin/examples/cpp/hello-world-2.params)
```
Where possible, commands are printed in a Bourne shell compatible syntax,
so that they can be easily copied and pasted to a shell command prompt.
(The surrounding parentheses are provided to protect your shell from the
`cd` and `exec` calls; be sure to copy them!)
However some commands are implemented internally within Bazel, such as
creating symlink trees. For these there's no command line to display.
`--subcommands=pretty_print` may be passed to print
the arguments of the command as a list rather than as a single line. This may
help make long command lines more readable.
See also [--verbose\_failures](#verbose-failures), below.
For logging subcommands to a file in a tool-friendly format, see
[--execution\_log\_json\_file](/reference/command-line-reference#flag--execution_log_json_file)
and
[--execution\_log\_binary\_file](/reference/command-line-reference#flag--execution_log_binary_file).
#### `--verbose_failures`
This option causes Bazel's execution phase to print the full command line
for commands that failed. This can be invaluable for debugging a
failing build.
Failing commands are printed in a Bourne shell compatible syntax, suitable
for copying and pasting to a shell prompt.
### Workspace status
Use these options to "stamp" Bazel-built binaries: to embed additional information into the
binaries, such as the source control revision or other workspace-related information. You can use
this mechanism with rules that support the `stamp` attribute, such as
`genrule`, `cc_binary`, and more.
#### `--workspace_status_command=program`
This flag lets you specify a binary that Bazel runs before each build. The program can report
information about the status of the workspace, such as the current source control revision.
The flag's value must be a path to a native program. On Linux/macOS this may be any executable.
On Windows this must be a native binary, typically an ".exe", ".bat", or a ".cmd" file.
The program should print zero or more key/value pairs to standard output, one entry on each line,
then exit with zero (otherwise the build fails). The key names can be anything but they may only
use upper case letters and underscores. The first space after the key name separates it from the
value. The value is the rest of the line (including additional whitespaces). Neither the key nor
the value may span multiple lines. Keys must not be duplicated.
Bazel partitions the keys into two buckets: "stable" and "volatile". (The names "stable" and
"volatile" are a bit counter-intuitive, so don't think much about them.)
Bazel then writes the key-value pairs into two files:
* `bazel-out/stable-status.txt`
contains all keys and values where the key's name starts with `STABLE_`
* `bazel-out/volatile-status.txt`
contains the rest of the keys and their values
The contract is:
* "stable" keys' values should change rarely, if possible. If the contents of
`bazel-out/stable-status.txt`
change, Bazel invalidates the actions that depend on them. In
other words, if a stable key's value changes, Bazel will rerun stamped actions.
Therefore the stable status should not contain things like timestamps, because they change all
the time, and would make Bazel rerun stamped actions with each build.
Bazel always outputs the following stable keys:
* `BUILD_EMBED_LABEL`: value of `--embed_label`
* `BUILD_HOST`: the name of the host machine that Bazel is running on
* `BUILD_USER`: the name of the user that Bazel is running as
* "volatile" keys' values may change often. Bazel expects them to change all the time, like
timestamps do, and duly updates the
`bazel-out/volatile-status.txt`
file. In order to avoid
rerunning stamped actions all the time though, **Bazel pretends that the volatile file never
changes**. In other words, if the volatile status file is the only file whose contents has
changed, Bazel will not invalidate actions that depend on it. If other inputs of the actions
have changed, then Bazel reruns that action, and the action will see the updated volatile
status, but just the volatile status changing alone will not invalidate the action.
Bazel always outputs the following volatile keys:
* `BUILD_TIMESTAMP`: time of the build in seconds since the Unix Epoch (the value
of `System.currentTimeMillis()` divided by a thousand)
* `FORMATTED_DATE`: time of the build Formatted as
`yyyy MMM d HH mm ss EEE`(for example 2023 Jun 2 01 44 29 Fri) in UTC.
On Linux/macOS you can pass `--workspace_status_command=/bin/true` to
disable retrieving workspace status, because `true` does nothing, successfully (exits
with zero) and prints no output. On Windows you can pass the path of MSYS's `true.exe`
for the same effect.
If the workspace status command fails (exits non-zero) for any reason, the build will fail.
Example program on Linux using Git:
Pass this program's path with `--workspace_status_command`, and the stable status file
will include the STABLE lines and the volatile status file will include the rest of the lines.
#### Using workspace status in your build
The status key-value pairs can be used in your build through Starlark actions
and templates. Many binary or 'top-level' rules, and other rules like
`genrule`, support the `stamp` attribute, which can embed workspace status
information into the compiled binaries.
For example, when using `cc_binary` with `stamp = 1`, Bazel will automatically
make the workspace status available to the build. You can then access these
values through template files:
```python theme={null}
# In your BUILD file
cc_binary(
name = "my_binary",
srcs = ["main.cc"],
stamp = 1, # Enable stamping to include workspace status
)
# For custom use of workspace status, you can use ctx.actions.declare_file
# and read the status files from ctx.workspace_status
```
For Java projects, you can use the `bazel_java_build_info` rule to generate
Java source files with workspace status information:
```python theme={null}
load("@bazel_tools//tools/build_defs/build_info:bazel_java_build_info.bzl", "bazel_java_build_info")
bazel_java_build_info(
name = "build_info",
stamp = 1,
)
java_binary(
name = "my_app",
srcs = ["Main.java", ":build_info"],
main_class = "com.example.Main",
)
```
This will generate a Java source file containing the workspace status values
as string constants, which you can then use in your Java code:
```java theme={null}
// In your Java code
public class Main {
public static void main(String[] args) {
System.out.println("Build label: " + BuildInfo.BUILD_LABEL);
System.out.println("Build host: " + BuildInfo.BUILD_HOST);
System.out.println("Build user: " + BuildInfo.BUILD_USER);
}
}
```
#### `--[no]stamp`
This option, in conjunction with the `stamp` rule attribute, controls whether to
embed build information in binaries.
Stamping can be enabled or disabled explicitly on a per-rule basis using the
`stamp` attribute. Please refer to the Build Encyclopedia for details. When
a rule sets `stamp = -1` (the default for `*_binary` rules), this option
determines whether stamping is enabled.
Bazel never stamps binaries that are built for the exec configuration,
regardless of this option or the `stamp` attribute. For rules that set `stamp =
0` (the default for `*_test` rules), stamping is disabled regardless of
`--[no]stamp`. Specifying `--stamp` does not force targets to be rebuilt if
their dependencies have not changed.
Setting `--nostamp` is generally desireable for build performance, as it
reduces input volatility and maximizes build caching.
### Platform
Use these options to control the host and target platforms that configure how builds work, and to
control what execution platforms and toolchains are available to Bazel rules.
Please see background information on [Platforms](/extending/platforms) and [Toolchains](/extending/toolchains).
#### `--platforms=labels`
The labels of the platform rules describing the target platforms for the
current command.
#### `--host_platform=label`
The label of a platform rule that describes the host system.
#### `--extra_execution_platforms=labels`
The platforms that are available as execution platforms to run actions.
Platforms can be specified by exact target, or as a target pattern. These
platforms will be considered before those declared in MODULE.bazel files by
[register\_execution\_platforms()](/rules/lib/globals/module#register_execution_platforms).
This option accepts a comma-separated list of platforms in order of priority.
If the flag is passed multiple times, the most recent overrides.
#### `--extra_toolchains=labels`
The toolchain rules to be considered during toolchain resolution. Toolchains
can be specified by exact target, or as a target pattern. These toolchains will
be considered before those declared in MODULE.bazel files by
[register\_toolchains()](/rules/lib/globals/module#register_toolchains).
#### `--toolchain_resolution_debug=regex`
Print debug information while finding toolchains if the toolchain type matches
the regex. Multiple regexes can be separated by commas. The regex can be
negated by using a `-` at the beginning. This might help developers
of Bazel or Starlark rules with debugging failures due to missing toolchains.
### Miscellaneous
#### `--flag_alias=alias_name=target_path`
A convenience flag used to bind longer Starlark build settings to a shorter name. For more
details, see the
[Starlark Configurations](/extending/config#using-build-setting-aliases).
#### `--symlink_prefix=string`
Changes the prefix of the generated convenience symlinks. The
default value for the symlink prefix is `bazel-` which
will create the symlinks `bazel-bin`, `bazel-testlogs`, and
`bazel-genfiles`.
If the symbolic links cannot be created for any reason, a warning is
issued but the build is still considered a success. In particular,
this allows you to build in a read-only directory or one that you have no
permission to write into. Any paths printed in informational
messages at the conclusion of a build will only use the
symlink-relative short form if the symlinks point to the expected
location; in other words, you can rely on the correctness of those
paths, even if you cannot rely on the symlinks being created.
Some common values of this option:
* **Suppress symlink creation:**
`--symlink_prefix=/` will cause Bazel to not
create or update any symlinks, including the `bazel-out` and
`bazel-`
symlinks. Use this option to suppress symlink creation entirely.
* **Reduce clutter:**
`--symlink_prefix=.bazel/` will cause Bazel to create
symlinks called `bin` (etc) inside a hidden directory `.bazel`.
#### `--platform_suffix=string`
Adds a suffix to the configuration short name, which is used to determine the
output directory. Setting this option to different values puts the files into
different directories, for example to improve cache hit rates for builds that
otherwise clobber each others output files, or to keep the output files around
for comparisons.
#### `--default_visibility=(private|public)`
Temporary flag for testing bazel default visibility changes. Not intended for general use
but documented for completeness' sake.
#### `--starlark_cpu_profile=_file_`
This flag, whose value is the name of a file, causes Bazel to gather
statistics about CPU usage by all Starlark threads,
and write the profile, in [pprof](https://github.com/google/pprof) format,
to the named file.
Use this option to help identify Starlark functions that
make loading and analysis slow due to excessive computation. For example:
$bazel build --nobuild --starlark_cpu_profile=/tmp/pprof.gz my/project/...$ pprof /tmp/pprof.gz
(pprof) top
Type: CPU
Time: Feb 6, 2020 at 12:06pm (PST)
Duration: 5.26s, Total samples = 3.34s (63.55%)
Showing nodes accounting for 3.34s, 100% of 3.34s total
flat flat% sum% cum cum%
1.86s 55.69% 55.69% 1.86s 55.69% sort\_source\_files
1.02s 30.54% 86.23% 1.02s 30.54% expand\_all\_combinations
0.44s 13.17% 99.40% 0.44s 13.17% range
0.02s 0.6% 100% 3.34s 100% sorted
0 0% 100% 1.38s 41.32% my/project/main/BUILD
0 0% 100% 1.96s 58.68% my/project/library.bzl
0 0% 100% 3.34s 100% main
For different views of the same data, try the `pprof` commands `svg`,
`web`, and `list`.
## Using Bazel for releases
Bazel is used both by software engineers during the development
cycle, and by release engineers when preparing binaries for deployment
to production. This section provides a list of tips for release
engineers using Bazel.
### Significant options
When using Bazel for release builds, the same issues arise as for other scripts
that perform a build. For more details, see
[Call Bazel from scripts](/run/scripts). In particular, the following options
are strongly recommended:
* [`--bazelrc=/dev/null`](/run/bazelrc)
* [`--nokeep_state_after_build`](/reference/command-line-reference#common_options-flag--keep_state_after_build)
These options are also important:
* [`--package_path`](#package-path)
* [`--symlink_prefix`](#symlink-prefix):
for managing builds for multiple configurations,
it may be convenient to distinguish each build
with a distinct identifier, such as "64bit" vs. "32bit". This option
differentiates the `bazel-bin` (etc.) symlinks.
## Running tests
To build and run tests with bazel, type `bazel test` followed by
the name of the test targets.
By default, this command performs simultaneous build and test
activity, building all specified targets (including any non-test
targets specified on the command line) and testing
`*_test` and `test_suite` targets as soon as
their prerequisites are built, meaning that test execution is
interleaved with building. Doing so usually results in significant
speed gains.
### Options for `bazel test`
#### `--cache_test_results=(yes|no|auto)` (`-t`)
If this option is set to 'auto' (the default) then Bazel will only rerun a test if any of the
following conditions applies:
* Bazel detects changes in the test or its dependencies
* the test is marked as `external`
* multiple test runs were requested with `--runs_per_test`
* the test failed.
If 'no', all tests will be executed unconditionally.
If 'yes', the caching behavior will be the same as auto
except that it may cache test failures and test runs with
`--runs_per_test`.
Note: Test results are *always* saved in Bazel's output tree,
regardless of whether this option is enabled, so
you needn't have used `--cache_test_results` on the
prior run(s) of `bazel test` in order to get cache hits.
The option only affects whether Bazel will *use* previously
saved results, not whether it will save results of the current run.
Users who have enabled this option by default in
their `.bazelrc` file may find the
abbreviations `-t` (on) or `-t-` (off)
convenient for overriding the default on a particular run.
#### `--check_tests_up_to_date`
This option tells Bazel not to run the tests, but to merely check and report
the cached test results. If there are any tests which have not been
previously built and run, or whose tests results are out-of-date (for example, because
the source code or the build options have changed), then Bazel will report
an error message ("test result is not up-to-date"), will record the test's
status as "NO STATUS" (in red, if color output is enabled), and will return
a non-zero exit code.
This option also implies
[`--check_up_to_date`](#check-up-to-date) behavior.
This option may be useful for pre-submit checks.
#### `--test_verbose_timeout_warnings`
This option tells Bazel to explicitly warn the user if a test's timeout is
significantly longer than the test's actual execution time. While a test's
timeout should be set such that it is not flaky, a test that has a highly
over-generous timeout can hide real problems that crop up unexpectedly.
For instance, a test that normally executes in a minute or two should not have
a timeout of ETERNAL or LONG as these are much, much too generous.
This option is useful to help users decide on a good timeout value or
sanity check existing timeout values.
Note: Each test shard is allotted the timeout of the entire
`XX_test` target. Using this option does not affect a test's timeout
value, merely warns if Bazel thinks the timeout could be restricted further.
#### `--[no]test_keep_going`
By default, all tests are run to completion. If this flag is disabled,
however, the build is aborted on any non-passing test. Subsequent build steps
and test invocations are not run, and in-flight invocations are canceled.
Do not specify both `--notest_keep_going` and `--keep_going`.
#### `--flaky_test_attempts=attempts`
This option specifies the maximum number of times a test should be attempted
if it fails for any reason. A test that initially fails but eventually
succeeds is reported as `FLAKY` on the test summary. It is,
however, considered to be passed when it comes to identifying Bazel exit code
or total number of passed tests. Tests that fail all allowed attempts are
considered to be failed.
By default (when this option is not specified, or when it is set to
default), only a single attempt is allowed for regular tests, and
3 for test rules with the `flaky` attribute set. You can specify
an integer value to override the maximum limit of test attempts. Bazel allows
a maximum of 10 test attempts in order to prevent abuse of the system.
#### `--runs_per_test=[regex@]number`
This option specifies the number of times each test should be executed. All
test executions are treated as separate tests (fallback functionality
will apply to each of them independently).
The status of a target with failing runs depends on the value of the
`--runs_per_test_detects_flakes` flag:
* If absent, any failing run causes the entire test to fail.
* If present and two runs from the same shard return PASS and FAIL, the test
will receive a status of flaky (unless other failing runs cause it to
fail).
If a single number is specified, all tests will run that many times.
Alternatively, a regular expression may be specified using the syntax
regex\@number. This constrains the effect of `--runs_per_test` to targets
which match the regex (`--runs_per_test=^//pizza:.*@4` runs all tests
under `//pizza/` 4 times).
This form of `--runs_per_test` may be specified more than once.
#### `--[no]runs_per_test_detects_flakes`
If this option is specified (by default it is not), Bazel will detect flaky
test shards through `--runs_per_test`. If one or more runs for a single shard
fail and one or more runs for the same shard pass, the target will be
considered flaky with the flag. If unspecified, the target will report a
failing status.
#### `--test_summary=output_style`
Specifies how the test result summary should be displayed.
* `short` lists all tests that ran to completion, along with the name of
the file containing the test output if the test failed. This is the
default value.
* `short_uncached` like `short`, but omits tests whose results were cached.
* `terse` lists only failed and flaky tests.
* `detailed` lists all tests that ran to completion and prints each
individual test case (passed, skipped, and failed). The names of test
output files are omitted.
* `detailed_uncached` like `detailed`, but omits tests whose results were
cached.
* `testcase` prints a summary at test-case resolution without detailed
information about failed test cases.
* `none` does not print a test summary.
#### `--test_output=output_style`
Specifies how test output should be displayed:
* `summary` shows a summary of whether each test passed or
failed. Also shows the output log file name for failed tests. The summary
will be printed at the end of the build (during the build, one would see
just simple progress messages when tests start, pass or fail).
This is the default behavior.
* `errors` sends combined stdout/stderr output from failed tests
only into the stdout immediately after test is completed, ensuring that
test output from simultaneous tests is not interleaved with each other.
Prints a summary at the build as per summary output above.
* `all` is similar to `errors` but prints output for
all tests, including those which passed.
* `streamed` streams stdout/stderr output from each test in
real-time.
#### `--java_debug`
This option causes the Java virtual machine of a java test to wait for a connection from a
JDWP-compliant debugger before starting the test. This option implies `--test_output=streamed`.
#### `--[no]verbose_test_summary`
By default this option is enabled, causing test times and other additional
information (such as test attempts) to be printed to the test summary. If
`--noverbose_test_summary` is specified, test summary will
include only test name, test status and cached test indicator and will
be formatted to stay within 80 characters when possible.
#### `--test_tmpdir=path`
Specifies temporary directory for tests. Each test will be executed in a
separate subdirectory inside this directory. The directory will be cleaned at
the beginning of each `bazel test` command.
By default, Bazel will place this directory under the Bazel output base directory.
Note: This is a directory for running tests, not storing test results
(those are always stored under the `bazel-out` directory).
#### `--test_timeout=seconds` OR `--test_timeout=seconds,seconds,seconds,seconds`
Overrides the timeout value for all tests by using specified number of
seconds as a new timeout value. If only one value is provided, then it will
be used for all test timeout categories.
Alternatively, four comma-separated values may be provided, specifying
individual timeouts for short, moderate, long and eternal tests (in that
order).
In either form, zero or a negative value for any of the test sizes will
be substituted by the default timeout for the given timeout categories as
defined by the page [Writing Tests](/reference/test-encyclopedia).
By default, Bazel will use these timeouts for all tests by
inferring the timeout limit from the test's size whether the size is
implicitly or explicitly set.
Tests which explicitly state their timeout category as distinct from their
size will receive the same value as if that timeout had been implicitly set by
the size tag. So a test of size 'small' which declares a 'long' timeout will
have the same effective timeout that a 'large' tests has with no explicit
timeout.
#### `--test_arg=arg`
Passes command-line options/flags/arguments to each test process. This
option can be used multiple times to pass several arguments. For example,
`--test_arg=--logtostderr --test_arg=--v=3`.
Note that, unlike the `bazel run` command, you can't pass test arguments
directly as in `bazel test -- target --logtostderr --v=3`. That's because
extraneous arguments passed to `bazel test` are interpreted as additional test
targets. That is, `--logtostderr` and `--v=3` would each be interpreted as a
test target. This ambiguity doesn't exist for a `bazel run` command, which only
accepts one target.
`--test_arg` can be passed to a `bazel run` command, but it's ignored unless the
target being run is a test target. (As with any other flag, if it's passed in a
`bazel run` command after a `--` token, it's not processed by Bazel but
forwarded verbatim to the executed target.)
#### `--test_env=variable=_value_` OR `--test_env=variable`
Specifies additional variables that must be injected into the test
environment for each test. If value is not specified it will be
inherited from the shell environment used to start the `bazel test`
command.
The environment can be accessed from within a test by using
`System.getenv("var")` (Java), `getenv("var")` (C or C++),
#### `--run_under=command-prefix`
This specifies a prefix that the test runner will insert in front
of the test command before running it. The
command-prefix is split into words using Bourne shell
tokenization rules, and then the list of words is prepended to the
command that will be executed.
If the first word is a fully-qualified label (starts with
`//`) it is built. Then the label is substituted by the
corresponding executable location that is prepended to the command
that will be executed along with the other words.
Some caveats apply:
* The PATH used for running tests may be different than the PATH in your environment,
so you may need to use an **absolute path** for the `--run_under`
command (the first word in command-prefix).
* **`stdin` is not connected**, so `--run_under`
can't be used for interactive commands.
Examples:
#### Test selection
As documented under [Output selection options](#output-selection),
you can filter tests by [size](#test-size-filters),
[timeout](#test-timeout-filters),
[tag](#test-tag-filters), or
[language](#test-lang-filters). A convenience
[general name filter](#test-filter) can forward particular
filter args to the test runner.
#### Other options for `bazel test`
The syntax and the remaining options are exactly like
[`bazel build`](/run/build).
## Running executables
The `bazel run` command is similar to `bazel build`, except
it is used to build *and run* a single target. Here is a typical session
(`//java/myapp:myapp` says hello and prints out its args):
Note: `--` is needed so that Bazel
does not interpret `--arg1` and `--arg2` as
Bazel options, but rather as part of the command line for running the binary.
Additionally, Bazel will avoid logging these arguments to the console in case
they contain sensitive information.
`bazel run` is similar, but not identical, to directly invoking
the binary built by Bazel and its behavior is different depending on whether the
binary to be invoked is a test or not.
When the binary is not a test, the current working directory will be the
runfiles tree of the binary.
When the binary is a test, the current working directory will be the exec root
and a good-faith attempt is made to replicate the environment tests are usually
run in. The emulation is not perfect, though, and tests that have multiple
shards cannot be run this way (the
`--test_sharding_strategy=disabled` command line option can be used
to work around this)
The following extra environment variables are also available to the binary:
* `BUILD_WORKSPACE_DIRECTORY`: the root of the workspace where the
build was run.
* `BUILD_WORKING_DIRECTORY`: the current working directory where
Bazel was run from.
* `BUILD_ID`: the build ID of the `bazel run` invocation. This is usually
unique, except if Bazel was run with `--script_path` and the resulting
script is re-used.
* `BUILD_EXECROOT`: the execution root of the `bazel run` invocation.
These can be used, for example, to interpret file names on the command line in
a user-friendly way.
### Options for `bazel run`
#### `--run_under=command-prefix`
This has the same effect as the `--run_under` option for
`bazel test` ([see above](#test-run-under)),
except that it applies to the command being run by `bazel
run` rather than to the tests being run by `bazel test`
and cannot run under label.
#### Filtering logging outputs from Bazel
When invoking a binary with `bazel run`, Bazel prints logging output from Bazel
itself and the binary under invocation. To make the logs less noisy, you can
suppress the outputs from Bazel itself with the `--ui_event_filters` and
`--noshow_progress` flags.
For example:
`bazel run --ui_event_filters=-info,-stdout,-stderr --noshow_progress //java/myapp:myapp`
### Executing tests
`bazel run` can also execute test binaries, which has the effect of
running the test in a close approximation of the environment described at
[Writing Tests](/reference/test-encyclopedia). Note that none of the
`--test_*` arguments have an effect when running a test in this manner except
`--test_arg` .
## Cleaning build outputs
### The `clean` command
Bazel has a `clean` command, analogous to that of Make.
It deletes the output directories for all build configurations performed
by this Bazel instance, or the entire working tree created by this
Bazel instance, and resets internal caches. If executed without any
command-line options, then the output directory for all configurations
will be cleaned.
Recall that each Bazel instance is associated with a single workspace, thus the
`clean` command will delete all outputs from all builds you've done
with that Bazel instance in that workspace.
To completely remove the entire working tree created by a Bazel
instance, you can specify the `--expunge` option. When
executed with `--expunge`, the clean command simply
removes the entire output base tree which, in addition to the build
output, contains all temp files created by Bazel. It also
stops the Bazel server after the clean, equivalent to the [`shutdown`](#shutdown) command. For example, to
clean up all disk and memory traces of a Bazel instance, you could
specify:
% bazel clean --expunge
Alternatively, you can expunge in the background by using
`--expunge_async`. It is safe to invoke a Bazel command
in the same client while the asynchronous expunge continues to run.
Note: This may introduce IO contention.
The `clean` command is provided primarily as a means of
reclaiming disk space for workspaces that are no longer needed.
Bazel's incremental rebuilds may not be
perfect so `clean` can be used to recover a consistent
state when problems arise.
Bazel's design is such that these problems are fixable and
these bugs are a high priority to be fixed. If you
ever find an incorrect incremental build, file a bug report, and report bugs in the tools
rather than using `clean`.
## Querying the dependency graph
Bazel includes a query language for asking questions about the
dependency graph used during the build. The query language is used
by two commands: query and cquery. The major difference between the
two commands is that query runs after the [loading phase](/run/build#loading)
and cquery runs after the [analysis phase](/run/build#analysis). These tools are an
invaluable aid to many software engineering tasks.
The query language is based on the idea of
algebraic operations over graphs; it is documented in detail in
[Bazel Query Reference](/query/language).
Please refer to that document for reference, for
examples, and for query-specific command-line options.
The query tool accepts several command-line
option. `--output` selects the output format.
`--[no]keep_going` (disabled by default) causes the query
tool to continue to make progress upon errors; this behavior may be
disabled if an incomplete result is not acceptable in case of errors.
The `--[no]tool_deps` option,
enabled by default, causes dependencies in non-target configurations to be included in the
dependency graph over which the query operates.
The `--[no]implicit_deps` option, enabled by default, causes
implicit dependencies to be included in the dependency graph over which the query operates. An
implicit dependency is one that is not explicitly specified in the BUILD file
but added by bazel.
Example: "Show the locations of the definitions (in BUILD files) of
all genrules required to build all the tests in the PEBL tree."
## Querying the action graph
Caution: The aquery command is still experimental and its API will change.
The `aquery` command allows you to query for actions in your build graph.
It operates on the post-analysis configured target graph and exposes
information about actions, artifacts and their relationships.
The tool accepts several command-line options.
`--output` selects the output format. The default output format
(`text`) is human-readable, use `proto` or `textproto` for
machine-readable format.
Notably, the aquery command runs on top of a regular Bazel build and inherits
the set of options available during a build.
It supports the same set of functions that is also available to traditional
`query` but `siblings`, `buildfiles` and
`tests`.
For more details, see [Action Graph Query](/query/aquery).
## Miscellaneous commands and options
### `help`
The `help` command provides on-line help. By default, it
shows a summary of available commands and help topics, as shown in
[Building with Bazel](/run/build#quickstart).
Specifying an argument displays detailed help for a particular
topic. Most topics are Bazel commands, such as `build`
or `query`, but there are some additional help topics
that do not correspond to commands.
#### `--[no]long` (`-l`)
By default, `bazel help [topic]` prints only a
summary of the relevant options for a topic. If
the `--long` option is specified, the type, default value
and full description of each option is also printed.
### `shutdown`
Bazel server processes may be stopped by using the `shutdown`
command. This command causes the Bazel server to exit as soon as it
becomes idle (for example, after the completion of any builds or other
commands that are currently in progress). For more details, see
[Client/server implementation](/run/client-server).
Bazel servers stop themselves after an idle timeout, so this command
is rarely necessary; however, it can be useful in scripts when it is
known that no further builds will occur in a given workspace.
`shutdown` accepts one
option, `--iff_heap_size_greater_than _n_`, which
requires an integer argument (in MB). If specified, this makes the shutdown
conditional on the amount of memory already consumed. This is
useful for scripts that initiate a lot of builds, as any memory
leaks in the Bazel server could cause it to crash spuriously on
occasion; performing a conditional restart preempts this condition.
### `info`
The `info` command prints various values associated with
the Bazel server instance, or with a specific build configuration.
(These may be used by scripts that drive a build.)
The `info` command also permits a single (optional)
argument, which is the name of one of the keys in the list below.
In this case, `bazel info key` will print only
the value for that one key. (This is especially convenient when
scripting Bazel, as it avoids the need to pipe the result
through `sed -ne /key:/s/key://p`:
#### Configuration-independent data
* `release`: the release label for this Bazel
instance, or "development version" if this is not a released
binary.
* `workspace` the absolute path to the base workspace
directory.
* `install_base`: the absolute path to the installation
directory used by this Bazel instance for the current user. Bazel
installs its internally required executables below this directory.
* `output_base`: the absolute path to the base output
directory used by this Bazel instance for the current user and
workspace combination. Bazel puts all of its scratch and build
output below this directory.
* `execution_root`: the absolute path to the execution
root directory under output\_base. This directory is the root for all files
accessible to commands executed during the build, and is the working
directory for those commands. If the workspace directory is writable, a
symlink named `bazel-`
is placed there pointing to this directory.
* `output_path`: the absolute path to the output
directory beneath the execution root used for all files actually
generated as a result of build commands. If the workspace directory is
writable, a symlink named `bazel-out` is placed there pointing
to this directory.
* `server_pid`: the process ID of the Bazel server
process.
* `server_log`: the absolute path to the Bazel server's debug log file.
This file contains debugging information for all commands over the lifetime of the
Bazel server, and is intended for human consumption by Bazel developers and power users.
* `command_log`: the absolute path to the command log file;
this contains the interleaved stdout and stderr streams of the most recent
Bazel command. Note that running `bazel info` will overwrite the
contents of this file, since it then becomes the most recent Bazel command.
However, the location of the command log file will not change unless you
change the setting of the `--output_base` or
`--output_user_root` options.
* `used-heap-size`,
`committed-heap-size`,
`max-heap-size`: reports various JVM heap size
parameters. Respectively: memory currently used, memory currently
guaranteed to be available to the JVM from the system, maximum
possible allocation.
* `gc-count`, `gc-time`: The cumulative count of
garbage collections since the start of this Bazel server and the time spent
to perform them. Note that these values are not reset at the start of every
build.
* `package_path`: A colon-separated list of paths which would be
searched for packages by bazel. Has the same format as the
`--package_path` build command line argument.
Example: the process ID of the Bazel server.
% bazel info server\_pid
1285
#### Configuration-specific data
These data may be affected by the configuration options passed
to `bazel info`, for
example `--cpu`, `--compilation_mode`,
etc. The `info` command accepts all
the options that control dependency
analysis, since some of these determine the location of the
output directory of a build, the choice of compiler, etc.
* `bazel-bin`, `bazel-testlogs`,
`bazel-genfiles`: reports the absolute path to
the `bazel-*` directories in which programs generated by the
build are located. This is usually, though not always, the same as
the `bazel-*` symlinks created in the base workspace directory after a
successful build. However, if the workspace directory is read-only,
no `bazel-*` symlinks can be created. Scripts that use
the value reported by `bazel info`, instead of assuming the
existence of the symlink, will be more robust.
* The complete
["Make" environment](/reference/be/make-variables). If the `--show_make_env` flag is
specified, all variables in the current configuration's "Make" environment
are also displayed (such as `CC`, `GLIBC_VERSION`, etc).
These are the variables accessed using the `$(CC)`
or `varref("CC")` syntax inside BUILD files.
Example: the C++ compiler for the current configuration.
This is the `$(CC)` variable in the "Make" environment,
so the `--show_make_env` flag is needed.
% bazel info --show\_make\_env -c opt COMPILATION\_MODE
opt
Example: the `bazel-bin` output directory for the current
configuration. This is guaranteed to be correct even in cases where
the `bazel-bin` symlink cannot be created for some reason
(such as if you are building from a read-only directory).
% bazel info --cpu=piii bazel-bin
/var/tmp/\_bazel\_johndoe/fbd0e8a34f61ce5d491e3da69d959fe6/execroot/io\_bazel/bazel-out/piii-opt/bin
% bazel info --cpu=k8 bazel-bin
/var/tmp/\_bazel\_johndoe/fbd0e8a34f61ce5d491e3da69d959fe6/execroot/io\_bazel/bazel-out/k8-opt/bin
### `version` and `--version`
The version command prints version details about the built Bazel
binary, including the changelist at which it was built and the date.
These are particularly useful in determining if you have the latest
Bazel, or if you are reporting bugs. Some of the interesting values
are:
* `changelist`: the changelist at which this version of
Bazel was released.
* `label`: the release label for this Bazel
instance, or "development version" if this is not a released
binary. Very useful when reporting bugs.
`bazel --version`, with no other args, will emit the same output as
`bazel version --gnu_format`, except without the side-effect of potentially starting
a Bazel server or unpacking the server archive. `bazel --version` can be run from
anywhere - it does not require a workspace directory.
### `mobile-install`
The `mobile-install` command installs apps to mobile devices.
Currently only Android devices running ART are supported.
See [bazel mobile-install](/docs/mobile-install) for more information.
Note: This command does not install the same thing that
`bazel build` produces: Bazel tweaks the app so that it can be
built, installed and re-installed quickly. This should, however, be mostly
transparent to the app.
The following options are supported:
#### `--incremental`
If set, Bazel tries to install the app incrementally, that is, only those
parts that have changed since the last build. This cannot update resources
referenced from `AndroidManifest.xml`, native code or Java
resources (such as those referenced by `Class.getResource()`). If these
things change, this option must be omitted. Contrary to the spirit of Bazel
and due to limitations of the Android platform, it is the
**responsibility of the user** to know when this command is good enough and
when a full install is needed.
If you are using a device with Marshmallow or later, consider the
[`--split_apks`](#split-apks) flag.
#### `--split_apks`
Whether to use split apks to install and update the application on the device.
Works only with devices with Marshmallow or later. Note that the
[`--incremental`](#incremental) flag
is not necessary when using `--split_apks`.
#### `--start_app`
Starts the app in a clean state after installing. Equivalent to `--start=COLD`.
#### `--debug_app`
Waits for debugger to be attached before starting the app in a clean state after installing.
Equivalent to `--start=DEBUG`.
#### `--start=_start_type_`
How the app should be started after installing it. Supported \_start\_type\_s are:
* `NO` Does not start the app. This is the default.
* `COLD` Starts the app from a clean state after install.
* `WARM` Preserves and restores the application state on incremental installs.
* `DEBUG` Waits for the debugger before starting the app in a clean state after
install.
Note: If more than one of `--start=_start_type_`, `--start_app` or
`--debug_app` is set, the last value is used.
#### `--adb=path`
Indicates the `adb` binary to be used.
The default is to use the adb in the Android SDK specified by
[`--android_sdk`](#android-sdk).
#### `--adb_arg=serial`
Extra arguments to `adb`. These come before the subcommand in the
command line and are typically used to specify which device to install to.
For example, to select the Android device or emulator to use:
#### `--incremental_install_verbosity=number`
The verbosity for incremental install. Set to 1 for debug logging to be
printed to the console.
### `dump`
The `dump` command prints to stdout a dump of the
internal state of the Bazel server. This command is intended
primarily for use by Bazel developers, so the output of this command
is not specified, and is subject to change.
By default, command will just print help message outlining possible
options to dump specific areas of the Bazel state. In order to dump
internal state, at least one of the options must be specified.
Following options are supported:
* `--action_cache` dumps action cache content.
* `--packages` dumps package cache content.
* `--skyframe` dumps state of internal Bazel dependency graph.
* `--rules` dumps rule summary for each rule and aspect class,
including counts and action counts. This includes both native and Starlark rules.
If memory tracking is enabled, then the rules' memory consumption is also printed.
* `--skylark_memory` dumps a
[pprof](https://github.com/google/pprof) compatible .gz file to the specified path.
You must enable memory tracking for this to work.
#### Memory tracking
Some `dump` commands require memory tracking. To turn this on, you have to pass
startup flags to Bazel:
* `--host_jvm_args=-javaagent:$BAZEL/third_party/allocation_instrumenter/java-allocation-instrumenter-3.3.4.jar`
* `--host_jvm_args=-DRULE_MEMORY_TRACKER=1`
The java-agent is checked into Bazel at
`third_party/allocation_instrumenter/java-allocation-instrumenter-3.3.4.jar`, so
make sure you adjust `$BAZEL` for where you keep your Bazel repository.
Do not forget to keep passing these options to Bazel for every command or the server will
restart.
Example:
### `canonicalize-flags`
The [`canonicalize-flags`](/reference/command-line-reference#canonicalize-flags-options)
command, which takes a list of options for a Bazel command and returns a list of
options that has the same effect. The new list of options is canonical. For example,
two lists of options with the same effect are canonicalized to the same new list.
The `--for_command` option can be used to select between different
commands. At this time, only `build` and `test` are
supported. Options that the given command does not support cause an error.
Note: A small number of options cannot be reordered, because Bazel cannot
ensure that the effect is identical. Also note that this command
*does not* expand flags from `--config`.
As an example:
### Startup options
The options described in this section affect the startup of the Java
virtual machine used by Bazel server process, and they apply to all
subsequent commands handled by that server. If there is an already
running Bazel server and the startup options do not match, it will
be restarted.
All of the options described in this section must be specified using the
`--key=value` or `--key value`
syntax. Also, these options must appear *before* the name of the Bazel
command. Use `startup --key=value` to list these in a `.bazelrc` file.
#### `--output_base=dir`
This option requires a path argument, which must specify a
writable directory. Bazel will use this location to write all its
output. The output base is also the key by which the client locates
the Bazel server. By changing the output base, you change the server
which will handle the command.
By default, the output base is derived from the user's login name,
and the name of the workspace directory (actually, its MD5 digest),
so a typical value looks like:
`/var/tmp/google/_bazel_johndoe/d41d8cd98f00b204e9800998ecf8427e`.
Note: The client uses the output base to find the Bazel server
instance, so if you specify a different output base in a Bazel
command, a different server will be found (or started) to handle the
request. It's possible to perform two concurrent builds in the same
workspace directory by varying the output base.
For example:
In this command, the two Bazel commands run concurrently (because of
the shell `&` operator), each using a different Bazel
server instance (because of the different output bases).
In contrast, if the default output base was used in both commands,
then both requests would be sent to the same server, which would
handle them sequentially: building `//foo` first, followed
by an incremental build of `//bar`.
Note: We recommend you do not use an NFS or similar networked file system for the root
directory, as the higher access latency will cause noticeably slower builds.
#### `--output_user_root=dir`
Points to the root directory where output and install bases are created. The directory
must either not exist or be owned by the calling user. In the past,
this was allowed to point to a directory shared among various users
but it's not allowed any longer. This may be allowed once
[issue #11100](https://github.com/bazelbuild/bazel/issues/11100) is addressed.
If the `--output_base` option is specified, it overrides
using `--output_user_root` to calculate the output base.
The install base location is calculated based on
`--output_user_root`, plus the MD5 identity of the Bazel embedded
binaries.
You can use the `--output_user_root` option to choose an
alternate base location for all of Bazel's output (install base and output
base) if there is a better location in your filesystem layout.
Note: We recommend you do not use an NFS or similar networked file system for the root
directory, as the higher access latency will cause noticeably slower builds.
#### `--server_javabase=dir`
Specifies the Java virtual machine in which *Bazel itself* runs. The value must be a path to
the directory containing a JDK or JRE. It should not be a label.
This option should appear before any Bazel command, for example:
This flag does *not* affect the JVMs used by Bazel subprocesses such as applications, tests,
tools, and so on. Use build options [--javabase](#javabase) or
[--host\_javabase](#host-javabase) instead.
This flag was previously named `--host_javabase` (sometimes referred to as the
'left-hand side' `--host_javabase`), but was renamed to avoid confusion with the
build flag [--host\_javabase](#host-javabase) (sometimes referred to as the
'right-hand side' `--host_javabase`).
#### `--host_jvm_args=string`
Specifies a startup option to be passed to the Java virtual machine in which *Bazel itself*
runs. This can be used to set the stack size, for example:
% bazel --host\_jvm\_args="-Xss256K" build //foo
This option can be used multiple times with individual arguments. Note that
setting this flag should rarely be needed. You can also pass a space-separated list of strings,
each of which will be interpreted as a separate JVM argument, but this feature will soon be
deprecated.
That this does *not* affect any JVMs used by
subprocesses of Bazel: applications, tests, tools, and so on. To pass
JVM options to executable Java programs, whether run by `bazel
run` or on the command-line, you should use
the `--jvm_flags` argument which
all `java_binary` and `java_test` programs
support. Alternatively for tests, use `bazel test --test_arg=--jvm_flags=foo ...`.
#### `--host_jvm_debug`
This option causes the Java virtual machine to wait for a connection
from a JDWP-compliant debugger before
calling the main method of *Bazel itself*. This is primarily
intended for use by Bazel developers.
Note: This does *not* affect any JVMs used by subprocesses of Bazel:
applications, tests, tools, etc.
#### `--autodetect_server_javabase`
This option causes Bazel to automatically search for an installed JDK on startup,
and to fall back to the installed JRE if the embedded JRE isn't available.
`--explicit_server_javabase` can be used to pick an explicit JRE to
run Bazel with.
#### `--batch`
Batch mode causes Bazel to not use the
[standard client/server mode](/run/client-server), but instead runs a bazel
java process for a single command, which has been used for more predictable
semantics with respect to signal handling, job control, and environment
variable inheritance, and is necessary for running bazel in a chroot jail.
Batch mode retains proper queueing semantics within the same output\_base.
That is, simultaneous invocations will be processed in order, without overlap.
If a batch mode Bazel is run on a client with a running server, it first
kills the server before processing the command.
Bazel will run slower in batch mode, or with the alternatives described above.
This is because, among other things, the build file cache is memory-resident, so it is not
preserved between sequential batch invocations.
Therefore, using batch mode often makes more sense in cases where performance
is less critical, such as continuous builds.
Warning: `--batch` is sufficiently slower than standard
client/server mode. Additionally it might not support all of the features and optimizations which
are made possible by a persistent Bazel server. If you're using `--batch`
for the purpose of build isolation, you should use the command option
`--nokeep_state_after_build`, which guarantees that no incremental
in-memory state is kept between builds. In order to restart the Bazel server and JVM after a
build, please explicitly do so using the "shutdown" command.
#### `--max_idle_secs=n`
This option specifies how long, in seconds, the Bazel server process
should wait after the last client request, before it exits. The
default value is 10800 (3 hours). `--max_idle_secs=0` will cause the
Bazel server process to persist indefinitely.
Note: this flag is only read if Bazel needs
to start a new server. Changing this option will not cause the server to restart.
Note: system sleep time where a build is not running is counted as idle time.
This option may be used by scripts that invoke Bazel to ensure that
they do not leave Bazel server processes on a user's machine when they
would not be running otherwise.
For example, a presubmit script might wish to
invoke `bazel query` to ensure that a user's pending
change does not introduce unwanted dependencies. However, if the
user has not done a recent build in that workspace, it would be
undesirable for the presubmit script to start a Bazel server just
for it to remain idle for the rest of the day.
By specifying a small value of `--max_idle_secs` in the
query request, the script can ensure that *if* it caused a new
server to start, that server will exit promptly, but if instead
there was already a server running, that server will continue to run
until it has been idle for the usual time. Of course, the existing
server's idle timer will be reset.
#### `--[no]shutdown_on_low_sys_mem`
If enabled and `--max_idle_secs` is set to a positive duration, shut down an idle
build server when available system memory falls below critical thresholds.
Supported on Linux and macOS (no-op on Windows).
To avoid interrupting workflows or thrashing during active development, the server
only checks memory after it has been continuously idle for at least **5 minutes**
(any incoming command resets this idle window). While idle past 5 minutes, it checks
memory every 5 seconds:
* **Linux:** The server exits if available RAM (from `/proc/meminfo`) drops below
**both** 1 GiB and 5% of total system RAM.
* **macOS:** The server exits if the kernel signals a memory pressure level of
`WARNING` or `CRITICAL` via `dispatch_source_memorypressure`.
This flag is especially useful on multi-project developer workstations where multiple
idle Bazel servers across different repositories or output bases can cause system-wide
memory pressure. You can enable it globally in your user configuration file:
```ini theme={null}
# ~/.bazelrc
startup --shutdown_on_low_sys_mem
```
#### `--[no]block_for_lock`
If enabled, Bazel will wait for other Bazel commands holding the
server lock to complete before progressing. If disabled, Bazel will
exit in error if it cannot immediately acquire the lock and
proceed.
Developers might use this in presubmit checks to avoid long waits caused
by another Bazel command in the same client.
#### `--io_nice_level=n`
Sets a level from 0-7 for best-effort IO scheduling. 0 is highest priority,
7 is lowest. The anticipatory scheduler may only honor up to priority 4.
Negative values are ignored.
#### `--batch_cpu_scheduling`
Use `batch` CPU scheduling for Bazel. This policy is useful for
workloads that are non-interactive, but do not want to lower their nice value.
See 'man 2 sched\_setscheduler'. This policy may provide for better system
interactivity at the expense of Bazel throughput.
### Miscellaneous options
#### `--[no]announce_rc`
Controls whether Bazel announces startup options and command options read from
the bazelrc files when starting up.
#### `--color (yes|no|auto)`
This option determines whether Bazel will use colors to highlight
its output on the screen.
If this option is set to `yes`, color output is enabled.
If this option is set to `auto`, Bazel will use color output only if
the output is being sent to a terminal and the TERM environment variable
is set to a value other than `dumb`, `emacs`, or `xterm-mono`.
If this option is set to `no`, color output is disabled,
regardless of whether the output is going to a terminal and regardless
of the setting of the TERM environment variable.
#### `--config=name`
Selects additional config section from
[the rc files](/run/bazelrc#bazelrc-file-locations); for the current `command`,
it also pulls in the options from `command:name` if such a section exists. Can be
specified multiple times to add flags from several config sections. Expansions can refer to other
definitions (for example, expansions can be chained).
#### `--curses (yes|no|auto)`
This option determines whether Bazel will use cursor controls
in its screen output. This results in less scrolling data, and a more
compact, easy-to-read stream of output from Bazel. This works well with
`--color`.
If this option is set to `yes`, use of cursor controls is enabled.
If this option is set to `no`, use of cursor controls is disabled.
If this option is set to `auto`, use of cursor controls will be
enabled under the same conditions as for `--color=auto`.
#### `--[no]show_timestamps`
If specified, a timestamp is added to each message generated by
Bazel specifying the time at which the message was output.
# Installing / Updating Bazel using Bazelisk
Source: https://bazel.build/install/bazelisk
## Installing Bazel
[Bazelisk](https://github.com/bazelbuild/bazelisk) is the
recommended way to install Bazel on Ubuntu, Windows, and macOS. It automatically
downloads and installs the appropriate version of Bazel. Use Bazelisk if you
need to switch between different versions of Bazel depending on the current
working directory, or to always keep Bazel updated to the latest release.
For more details, see
[the official README](https://github.com/bazelbuild/bazelisk/blob/master/README.md).
## Updating Bazel
Bazel has a [backward compatibility policy](/release/backward-compatibility)
(see [guidance for rolling out incompatible changes](/contribute/breaking-changes) if you
are the author of one). That page summarizes best practices on how to test and
migrate your project with upcoming incompatible changes and how to provide
feedback to the incompatible change authors.
### Managing Bazel versions with Bazelisk
[Bazelisk](https://github.com/bazelbuild/bazelisk) helps you manage
Bazel versions.
Bazelisk can:
* Auto-update Bazel to the latest LTS or rolling release.
* Build the project with a Bazel version specified in the .bazelversion
file. Check in that file into your version control to ensure reproducibility
of your builds.
* Help migrate your project for incompatible changes (see above)
* Easily try release candidates
### Recommended migration process
Within minor updates to any LTS release, any
project can be prepared for the next release without breaking
compatibility with the current release. However, there may be
backward-incompatible changes between major LTS versions.
Follow this process to migrate from one major version to another:
1. Read the release notes to get advice on how to migrate to the next version.
2. Major incompatible changes should have an associated `--incompatible_*` flag
and a corresponding GitHub issue:
* Migration guidance is available in the associated GitHub issue.
* Tooling is available for some of incompatible changes migration. For
example, [buildifier](https://github.com/bazelbuild/buildtools/releases).
* Report migration problems by commenting on the associated GitHub issue.
After migration, you can continue to build your projects without worrying about
backward-compatibility until the next major release.
# Compiling Bazel from Source
Source: https://bazel.build/install/compile-source
This page describes how to install Bazel from source and provides
troubleshooting tips for common issues.
To build Bazel from source, you can do one of the following:
* Build it [using an existing Bazel binary](#build-bazel-using-bazel)
* Build it [without an existing Bazel binary](#bootstrap-bazel) which is known
as *bootstrapping*.
## Build Bazel using Bazel
### Summary
1. Get the latest Bazel release from the
[GitHub release page](https://github.com/bazelbuild/bazel/releases) or with
[Bazelisk](https://github.com/bazelbuild/bazelisk).
2. [Download Bazel's sources from GitHub](https://github.com/bazelbuild/bazel/archive/master.zip)
and extract somewhere.
Alternatively you can git clone the source tree from [https://github.com/bazelbuild/bazel](https://github.com/bazelbuild/bazel)
3. Install the same prerequisites as for bootstrapping (see
[for Unix-like systems](#bootstrap-unix-prereq) or
[for Windows](#bootstrap-windows-prereq))
4. Build a development build of Bazel using Bazel:
`bazel build //src:bazel-dev` (or `bazel build //src:bazel-dev.exe` on
Windows).
**Note:** Many rulesets rely on the Bazel version for feature detection.
For this to work correctly, the version must be embedded in the binary.
Build `bazel-dev` with:
`bazel build --stamp --embed_label="X.Y.Z" //src:bazel-dev`
where `X.Y.Z` is the Bazel version being built (for example, `8.6.0`).
5. The resulting binary is at `bazel-bin/src/bazel-dev`
(or `bazel-bin\src\bazel-dev.exe` on Windows). You can copy it wherever you
like and use immediately without further installation.
Detailed instructions follow below.
### Step 1: Get the latest Bazel release
**Goal**: Install or download a release version of Bazel. Make sure you can run
it by typing `bazel` in a terminal.
**Reason**: To build Bazel from a GitHub source tree, you need a pre-existing
Bazel binary. You can install one from a package manager or download one from
GitHub. See [Installing Bazel](/install). (Or you can [build from scratch (bootstrap)](#bootstrap-bazel).)
**Troubleshooting**:
* If you cannot run Bazel by typing `bazel` in a terminal:
* Maybe your Bazel binary's directory is not on the PATH.
This is not a big problem. Instead of typing `bazel`, you will need to
type the full path.
* Maybe the Bazel binary itself is not called `bazel` (on Unixes) or
`bazel.exe` (on Windows).
This is not a big problem. You can either rename the binary, or type the
binary's name instead of `bazel`.
* Maybe the binary is not executable (on Unixes).
You must make the binary executable by running `chmod +x /path/to/bazel`.
### Step 2: Download Bazel's sources from GitHub
If you are familiar with Git, then just git clone [https://github.com/bazelbuild/bazel](https://github.com/bazelbuild/bazel)
Otherwise:
1. Download the
[latest sources as a zip file](https://github.com/bazelbuild/bazel/archive/master.zip).
2. Extract the contents somewhere.
For example create a `bazel-src` directory under your home directory and
extract there.
### Step 3: Install prerequisites
Install the same prerequisites as for bootstrapping (see below) -- JDK, C++
compiler, MSYS2 (if you are building on Windows), etc.
### Step 4a: Build Bazel on Ubuntu Linux, macOS, and other Unix-like systems
For instructions for Windows, see [Build Bazel on Windows](#build-bazel-on-windows).
**Goal**: Run Bazel to build a custom Bazel binary (`bazel-bin/src/bazel-dev`).
**Instructions**:
1. Start a Bash terminal
2. `cd` into the directory where you extracted (or cloned) Bazel's sources.
For example if you extracted the sources under your home directory, run:
cd \~/bazel-src
3. Build Bazel from source:
bazel build //src:bazel-dev
Alternatively you can run `bazel build //src:bazel --compilation_mode=opt`
to yield a smaller binary but it's slower to build.
You can build with `--stamp --embed_label=X.Y.Z` flag to embed a Bazel
version for the binary so that `bazel --version` outputs the given version.
4. The output will be at `bazel-bin/src/bazel-dev` (or `bazel-bin/src/bazel`).
### Step 4b: Build Bazel on Windows
For instructions for Unix-like systems, see
[Ubuntu Linux, macOS, and other Unix-like systems](#build-bazel-on-unixes).
**Goal**: Run Bazel to build a custom Bazel binary
(`bazel-bin\src\bazel-dev.exe`).
**Instructions**:
1. Start Command Prompt (Start Menu > Run > "cmd.exe")
2. `cd` into the directory where you extracted (or cloned) Bazel's sources.
For example if you extracted the sources under your home directory, run:
cd %USERPROFILE%\bazel-src
3. Build Bazel from source:
bazel build //src:bazel-dev.exe
Alternatively you can run `bazel build //src:bazel.exe --compilation_mode=opt` to yield a smaller binary but it's slower to build.
You can build with `--stamp --embed_label=X.Y.Z` flag to embed a Bazel
version for the binary so that `bazel --version` outputs the given version.
4. The output will be at `bazel-bin\src\bazel-dev.exe` (or
`bazel-bin\src\bazel.exe`).
### Step 5: Install the built binary
Actually, there's nothing to install.
The output of the previous step is a self-contained Bazel binary. You can copy
it to any directory and use immediately. (It's useful if that directory is on
your PATH so that you can run "bazel" everywhere.)
***
## Build Bazel from scratch (bootstrapping)
You can also build Bazel from scratch, without using an existing Bazel binary.
### Step 1: Download Bazel's sources (distribution archive)
(This step is the same for all platforms.)
1. Download `bazel--dist.zip` from
[GitHub](https://github.com/bazelbuild/bazel/releases/latest), for example
`bazel-0.28.1-dist.zip`.
**Attention**:
* There is a **single, architecture-independent** distribution archive.
There are no architecture-specific or OS-specific distribution archives.
* These sources are **not the same as the GitHub source tree**. You
have to use the distribution archive to bootstrap Bazel. You cannot
use a source tree cloned from GitHub. (The distribution archive contains
generated source files that are required for bootstrapping and are not part
of the normal Git source tree.)
2. Unpack the distribution archive somewhere on disk.
You should verify the signature made by Bazel's
[release key](https://releases.bazel.build/bazel-release.pub.gpg) 3D5919B448457EE0.
### Step 2a: Bootstrap Bazel on Ubuntu Linux, macOS, and other Unix-like systems
For instructions for Windows, see [Bootstrap Bazel on Windows](#bootstrap-windows).
#### 2.1. Install the prerequisites
* **Bash**
* **zip, unzip**
* **C++ build toolchain**
* **JDK.** Version 25 is required.
* **Python**. Version 3 is required.
For example on Ubuntu Linux you can install these requirements using the
following command:
```sh theme={null}
sudo apt-get install build-essential openjdk-25-jdk python3 zip unzip
```
#### 2.2. Bootstrap Bazel on Unix
1. Open a shell or Terminal window.
2. `cd` to the directory where you unpacked the distribution archive.
3. Run the compilation script: `env EXTRA_BAZEL_ARGS="--tool_java_runtime_version=local_jdk" bash ./compile.sh`.
The compiled output is placed into `output/bazel`. This is a self-contained
Bazel binary, without an embedded JDK. You can copy it anywhere or use it
in-place. For convenience, copy this binary to a directory that's on your
`PATH` (such as `/usr/local/bin` on Linux).
To build the `bazel` binary in a reproducible way, also set
[`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/specs/source-date-epoch/)
in the "Run the compilation script" step.
### Step 2b: Bootstrap Bazel on Windows
For instructions for Unix-like systems, see
[Bootstrap Bazel on Ubuntu Linux, macOS, and other Unix-like systems](#bootstrap-unix).
#### 2.1. Install the prerequisites
* [MSYS2 shell](https://msys2.github.io/)
* **The MSYS2 packages for zip and unzip.** Run the following command in the MSYS2 shell:
```
pacman -S zip unzip patch
```
* **The Visual C++ compiler.** Install the Visual C++ compiler either as part
of Visual Studio 2015 or newer, or by installing the latest [Build Tools for Visual Studio 2017](https://aka.ms/BuildTools).
* **JDK.** Version 25 is required.
* **Python**. Versions 2 and 3 are supported, installing one of them is
enough. You need the Windows-native version (downloadable from
[https://www.python.org](https://www.python.org)). Versions installed via
pacman in MSYS2 will not work.
#### 2.2. Bootstrap Bazel on Windows
1. Open the MSYS2 shell.
2. Set the following environment variables:
* Either `BAZEL_VS` or `BAZEL_VC` (they are *not* the same): Set to the
path to the Visual Studio directory (BAZEL\_V**S**) or to the Visual
C++ directory (BAZEL\_V**C**). Setting one of them is enough.
* `BAZEL_SH`: Path of the MSYS2 `bash.exe`. See the command in the
examples below.
Do not set this to `C:\Windows\System32\bash.exe`. (You have that file
if you installed Windows Subsystem for Linux.) Bazel does not support
this version of `bash.exe`.
* `PATH`: Add the Python directory.
* `JAVA_HOME`: Set to the JDK directory.
**Example** (using BAZEL\_V**S**):
export BAZEL\_VS="C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools"
export BAZEL\_SH="$(cygpath -m $(realpath $(which bash)))"
export PATH="/c/python27:$PATH"
export JAVA\_HOME="C:/Program Files/Java/jdk-25"
or (using BAZEL\_V**C**):
export BAZEL\_VC="C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC"
export BAZEL\_SH="$(cygpath -m $(realpath $(which bash)))"
export PATH="/c/python27:$PATH"
export JAVA\_HOME="C:/Program Files/Java/jdk-25"
3. `cd` to the directory where you unpacked the distribution archive.
4. Run the compilation script: `env EXTRA_BAZEL_ARGS="--tool_java_runtime_version=local_jdk" ./compile.sh`
The compiled output is placed into `output/bazel.exe`. This is a self-contained
Bazel binary, without an embedded JDK. You can copy it anywhere or use it
in-place. For convenience, copy this binary to a directory that's on
your `PATH`.
To build the `bazel.exe` binary in a reproducible way, also set
[`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/specs/source-date-epoch/)
in the "Run the compilation script" step.
You don't need to run Bazel from the MSYS2 shell. You can run Bazel from the
Command Prompt (`cmd.exe`) or PowerShell.
# Command-Line Completion
Source: https://bazel.build/install/completion
You can enable command-line completion (also known as tab-completion) in Bash
and Zsh. This lets you tab-complete command names, flags names and flag values,
and target names.
## Bash
Bazel comes with a Bash completion script.
If you installed Bazel:
* From the APT repository, then you're done -- the Bash completion script is
already installed in `/etc/bash_completion.d`.
* From Homebrew, then you're done -- the Bash completion script is
already installed in `$(brew --prefix)/etc/bash_completion.d`.
* From the installer downloaded from GitHub, then:
1. Locate the absolute path of the completion file. The installer copied it
to the `bin` directory.
Example: if you ran the installer with `--user`, this will be
`$HOME/.bazel/bin`. If you ran the installer as root, this will be
`/usr/local/lib/bazel/bin`.
2. Do one of the following:
* Either copy this file to your completion directory (if you have
one).
Example: on Ubuntu this is the `/etc/bash_completion.d` directory.
* Or source the completion file from Bash's RC file.
Add a line similar to the one below to your `~/.bashrc` (on Ubuntu)
or `~/.bash_profile` (on macOS), using the path to your completion
file's absolute path:
```
source /path/to/bazel-complete.bash
```
* Via [bootstrapping](/install/compile-source), then:
1. Emit the completion script into a file:
```
bazel help completion bash > bazel-complete.bash
```
2. Do one of the following:
* Copy this file to your completion directory, if you have
one.
Example: on Ubuntu this is the `/etc/bash_completion.d` directory
* Copy it somewhere on your local disk, such as to `$HOME`, and
source the completion file from Bash's RC file.
Add a line similar to the one below to your `~/.bashrc` (on Ubuntu)
or `~/.bash_profile` (on macOS), using the path to your completion
file's absolute path:
```
source /path/to/bazel-complete.bash
```
## Zsh
Bazel comes with a Zsh completion script.
If you installed Bazel:
* From the APT repository, then you're done -- the Zsh completion script is
already installed in `/usr/share/zsh/vendor-completions`.
> If you have a heavily customized `.zshrc` and the autocomplete
> does not function, try one of the following solutions:
>
> Add the following to your `.zshrc`:
>
> ```
> zstyle :compinstall filename '/home/tradical/.zshrc'
>
> autoload -Uz compinit
> compinit
> ```
>
> or
>
> Follow the instructions
> [here](https://stackoverflow.com/questions/58331977/bazel-tab-auto-complete-in-zsh-not-working)
>
> If you are using `oh-my-zsh`, you may want to install and enable
> the `zsh-autocomplete` plugin. If you'd prefer not to, use one of the
> solutions described above.
* From Homebrew, then you're done -- the Zsh completion script is
already installed in `$(brew --prefix)/share/zsh/site-functions`.
* From the installer downloaded from GitHub, then:
1. Locate the absolute path of the completion file. The installer copied it
to the `bin` directory.
Example: if you ran the installer with `--user`, this will be
`$HOME/.bazel/bin`. If you ran the installer as root, this will be
`/usr/local/lib/bazel/bin`.
2. Add this script to a directory on your `$fpath`:
```
fpath[1,0]=~/.zsh/completion/
mkdir -p ~/.zsh/completion/
cp /path/from/above/step/_bazel ~/.zsh/completion
```
You may have to call `rm -f ~/.zcompdump; compinit`
the first time to make it work.
3. Optionally, add the following to your .zshrc.
```
# This way the completion script does not have to parse Bazel's options
# repeatedly. The directory in cache-path must be created manually.
zstyle ':completion:*' use-cache on
zstyle ':completion:*' cache-path ~/.zsh/cache
```
# Getting Started with Bazel Docker Container
Source: https://bazel.build/install/docker-container
This page provides details on the contents of the Bazel container, how to build
the [abseil-cpp](https://github.com/abseil/abseil-cpp) project using Bazel
inside the Bazel container, and how to build this project directly
from the host machine using the Bazel container with directory mounting.
## Build Abseil project from your host machine with directory mounting
The instructions in this section allow you to build using the Bazel container
with the sources checked out in your host environment. A container is started up
for each build command you execute. Build results are cached in your host
environment so they can be reused across builds.
Clone the project to a directory in your host machine.
```posix-terminal theme={null}
git clone --depth 1 --branch 20220623.1 https://github.com/abseil/abseil-cpp.git /src/workspace
```
Create a folder that will have cached results to be shared across builds.
```posix-terminal theme={null}
mkdir -p /tmp/build_output/
```
Use the Bazel container to build the project and make the build
outputs available in the output folder in your host machine.
```posix-terminal theme={null}
docker run \
-e USER="$(id -u)" \
-u="$(id -u)" \
-v /src/workspace:/src/workspace \
-v /tmp/build_output:/tmp/build_output \
-w /src/workspace \
gcr.io/bazel-public/bazel:latest \
--output_user_root=/tmp/build_output \
build //absl/...
```
Build the project with sanitizers by adding the `--config=asan|tsan|msan` build
flag to select AddressSanitizer (asan), ThreadSanitizer (tsan) or
MemorySanitizer (msan) accordingly.
```posix-terminal theme={null}
docker run \
-e USER="$(id -u)" \
-u="$(id -u)" \
-v /src/workspace:/src/workspace \
-v /tmp/build_output:/tmp/build_output \
-w /src/workspace \
gcr.io/bazel-public/bazel:latest \
--output_user_root=/tmp/build_output \
build --config={asan | tsan | msan} -- //absl/... -//absl/types:variant_test
```
## Build Abseil project from inside the container
The instructions in this section allow you to build using the Bazel container
with the sources inside the container. By starting a container at the beginning
of your development workflow and doing changes in the worskpace within the
container, build results will be cached.
Start a shell in the Bazel container:
```posix-terminal theme={null}
docker run --interactive --entrypoint=/bin/bash gcr.io/bazel-public/bazel:latest
```
Each container id is unique. In the instructions below, the container was 5a99103747c6.
Clone the project.
```posix-terminal theme={null}
ubuntu@5a99103747c6:~$ git clone --depth 1 --branch 20220623.1 https://github.com/abseil/abseil-cpp.git && cd abseil-cpp/
```
Do a regular build.
```posix-terminal theme={null}
ubuntu@5a99103747c6:~/abseil-cpp$ bazel build //absl/...
```
Build the project with sanitizers by adding the `--config=asan|tsan|msan`
build flag to select AddressSanitizer (asan), ThreadSanitizer (tsan) or
MemorySanitizer (msan) accordingly.
```posix-terminal theme={null}
ubuntu@5a99103747c6:~/abseil-cpp$ bazel build --config={asan | tsan | msan} -- //absl/... -//absl/types:variant_test
```
## Explore the Bazel container
If you haven't already, start an interactive shell inside the Bazel container.
```posix-terminal theme={null}
docker run -it --entrypoint=/bin/bash gcr.io/bazel-public/bazel:latest
ubuntu@5a99103747c6:~$
```
Explore the container contents.
```posix-terminal theme={null}
ubuntu@5a99103747c6:~$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ubuntu@5a99103747c6:~$ java -version
openjdk version "1.8.0_362"
OpenJDK Runtime Environment (build 1.8.0_362-8u372-ga~us1-0ubuntu1~20.04-b09)
OpenJDK 64-Bit Server VM (build 25.362-b09, mixed mode)
ubuntu@5a99103747c6:~$ python -V
Python 3.8.10
ubuntu@5a99103747c6:~$ bazel version
WARNING: Invoking Bazel in batch mode since it is not invoked from within a workspace (below a directory having a WORKSPACE file).
Extracting Bazel installation...
Build label: 6.2.1
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Fri Jun 2 16:59:58 2023 (1685725198)
Build timestamp: 1685725198
Build timestamp as int: 1685725198
```
## Explore the Bazel Dockerfile
If you want to check how the Bazel Docker image is built, you can find its Dockerfile at [bazelbuild/continuous-integration/bazel/oci](https://github.com/bazelbuild/continuous-integration/tree/master/bazel/oci).
# Integrating Bazel with IDEs
Source: https://bazel.build/install/ide
This page covers how to integrate Bazel with IDEs, such as IntelliJ, Android
Studio, and CLion (or build your own IDE plugin). It also includes links to
installation and plugin details.
IDEs integrate with Bazel in a variety of ways, from features that allow Bazel
executions from within the IDE, to awareness of Bazel structures such as syntax
highlighting of the `BUILD` files.
If you are interested in developing an editor or IDE plugin for Bazel, please
join the `#ide` channel on the [Bazel Slack](https://slack.bazel.build) or start
a discussion on [GitHub](https://github.com/bazelbuild/bazel/discussions).
## IDEs and editors
### IntelliJ, Android Studio, and CLion
Official Bazel plugins exist for many of the JetBrains-associated IDEs.
Full documentation is linked from the listings on the JetBrains Marketplace:
* [IntelliJ plugin](https://plugins.jetbrains.com/plugin/22977-bazel)
* [Android Studio plugin](https://plugins.jetbrains.com/plugin/9185-android-studio-with-bazel)
* [CLion plugin](https://plugins.jetbrains.com/plugin/9554-clion-with-bazel)
Features:
* Interop with language-specific plugins. Supported languages include Java,
Scala, and Python.
* Import `BUILD` files into the IDE with semantic awareness of Bazel targets.
* Make your IDE aware of Starlark, the language used for Bazel's `BUILD` and
`.bzl`files
* Build, test, and execute binaries directly from the IDE
* Create configurations for debugging and running binaries.
To install, go to the IDE's plugin browser and search for `Bazel`.
To manually install older versions, download the zip files from the JetBrains
Marketplace or from [GitHub Releases](https://github.com/bazelbuild/intellij/releases)
and install the zip file from the IDE's plugin browser.
### Xcode
[rules\_xcodeproj](https://github.com/MobileNativeFoundation/rules_xcodeproj)
generates Xcode projects from Bazel `BUILD` files.
### Visual Studio Code
Official plugin for VS Code.
Features:
* Bazel Build Targets tree
* Starlark debugger for `.bzl` files during a build (set breakpoints, step
through code, inspect variables, and so on)
Find [the plugin on the Visual Studio marketplace](https://marketplace.visualstudio.com/items?itemName=BazelBuild.vscode-bazel)
or the [OpenVSX marketplace](https://open-vsx.org/extension/BazelBuild/vscode-bazel).
The plugin is [open source](https://github.com/bazelbuild/vscode-bazel).
See also: [Autocomplete for Source Code](#autocomplete-for-source-code)
### Atom
Find the [`language-bazel` package](https://atom.io/packages/language-bazel)
on the Atom package manager.
See also: [Autocomplete for Source Code](#autocomplete-for-source-code)
### Vim
See [`bazelbuild/vim-bazel` on GitHub](https://github.com/bazelbuild/vim-bazel)
See also: [Autocomplete for Source Code](#autocomplete-for-source-code)
### Emacs
See [`bazelbuild/bazel-emacs-mode` on GitHub](https://github.com/bazelbuild/emacs-bazel-mode)
See also: [Autocomplete for Source Code](#autocomplete-for-source-code)
### Visual Studio
[Lavender](https://github.com/tmandry/lavender) is an experimental project for
generating Visual Studio projects that use Bazel for building.
### Eclipse
[Bazel Eclipse Feature](https://github.com/salesforce/bazel-eclipse)
is a set of plugins for importing Bazel packages into an Eclipse workspace as
Eclipse projects.
## Autocomplete for Source Code
### C Language Family (C++, C, Objective-C, Objective-C++, and CUDA)
[`kiron1/bazel-compile-commands`](https://github.com/kiron1/bazel-compile-commands)
run `bazel-compile-commands //...` in a Bazel workspace to generate a `compile_commands.json` file.
The `compile_commands.json` file enables tools like `clang-tidy`, `clangd` (LSP) and other IDEs to
provide autocomplete, smart navigation, quick fixes, and more. The tool is written in C++ and
consumes the Protobuf output of Bazel to extract the compile commands.
[`hedronvision/bazel-compile-commands-extractor`](https://github.com/hedronvision/bazel-compile-commands-extractor) enables autocomplete, smart navigation, quick fixes, and more in a wide variety of extensible editors, including VSCode, Vim, Emacs, Atom, and Sublime. It lets language servers, like clangd and ccls, and other types of tooling, draw upon Bazel's understanding of how `cc` and `objc` code will be compiled, including how it configures cross-compilation for other platforms.
### Java
[`georgewfraser/java-language-server`](https://github.com/georgewfraser/java-language-server) - Java Language Server (LSP) with support for Bazel-built projects
## Automatically run build and test on file change
[Bazel watcher](https://github.com/bazelbuild/bazel-watcher) is a
tool for building Bazel targets when source files change.
## Building your own IDE plugin
Read the [**IDE support** blog post](https://blog.bazel.build/2016/06/10/ide-support.html) to learn more about
the Bazel APIs to use when building an IDE plugin.
# Installing Bazel
Source: https://bazel.build/install/index
This page describes the various platforms supported by Bazel and links
to the packages for more details.
[Bazelisk](/install/bazelisk) is the recommended way to install Bazel on [Ubuntu Linux](/install/ubuntu), [macOS](/install/os-x), and [Windows](/install/windows).
You can find available Bazel releases on our [release page](/release).
## Community-supported packages
Bazel community members maintain these packages. The Bazel team doesn't
officially support them. Contact the package maintainers for support.
* [Alpine Linux](https://pkgs.alpinelinux.org/packages?name=bazel*\&branch=edge\&repo=\&arch=\&origin=\&flagged=\&maintainer=)
* [Arch Linux][arch]
* [Debian](https://qa.debian.org/developer.php?email=team%2Bbazel%40tracker.debian.org)
* [Fedora](https://copr.fedorainfracloud.org/coprs/lihaohong/bazel)
* [FreeBSD](https://www.freshports.org/devel/bazel)
* [Homebrew](https://formulae.brew.sh/formula/bazel)
* [mise](/install/mise)
* [Nixpkgs](https://github.com/NixOS/nixpkgs/tree/master/pkgs/by-name/ba/bazel_9)
* [openSUSE](/install/suse)
* [Scoop](https://github.com/scoopinstaller/scoop-main/blob/master/bucket/bazel.json)
* [Raspberry Pi](https://github.com/koenvervloesem/bazel-on-arm/blob/master/README.md)
## Community-supported architectures
* [ppc64el](https://ftp2.osuosl.org/pub/ppc64el/bazel/)
For other platforms, you can try to [compile from source](/install/compile-source).
[arch]: https://archlinux.org/packages/extra/x86_64/bazel/
# Installing Bazel with mise
Source: https://bazel.build/install/mise
This page describes how to install Bazel using [mise](https://github.com/jdx/mise) the polyglot tools version manager.
```shell theme={null}
mise use -g bazel@latest
```
# Installing Bazel on macOS
Source: https://bazel.build/install/os-x
This page describes how to install Bazel on macOS and set up your environment.
You can install Bazel on macOS using one of the following methods:
* *Recommended*: [Use Bazelisk](/install/bazelisk)
* [Use Homebrew](#install-on-mac-os-x-homebrew)
* [Use the binary installer](#install-with-installer-mac-os-x)
* [Compile Bazel from source](/install/compile-source)
Bazel comes with two completion scripts. After installing Bazel, you can:
* Access the [bash completion script](/install/completion#bash)
* Install the [zsh completion script](/install/completion#zsh)
## Installing using Homebrew
### Step 1: Install Homebrew on macOS
Install [Homebrew](https://brew.sh/) (a one-time step):
```posix-terminal theme={null}
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
### Step 2: Install Bazel via Homebrew
Install the Bazel package via Homebrew as follows:
```posix-terminal theme={null}
brew install bazel
```
All set! You can confirm Bazel is installed successfully by running the
following command:
```posix-terminal theme={null}
bazel --version
```
Once installed, you can upgrade to a newer version of Bazel using the
following command:
```posix-terminal theme={null}
brew upgrade bazel
```
## Installing using the binary installer
The binary installers are on Bazel's
[GitHub releases page](https://github.com/bazelbuild/bazel/releases).
The installer contains the Bazel binary. Some additional libraries
must also be installed for Bazel to work.
### Step 1: Install Xcode command line tools
If you don't intend to use `ios_*` rules, it is sufficient to install the Xcode
command line tools package by using `xcode-select`:
```posix-terminal theme={null}
xcode-select --install
```
Otherwise, for `ios_*` rule support, you must have Xcode 6.1 or later with iOS
SDK 8.1 installed on your system.
Download Xcode from the
[App Store](https://apps.apple.com/us/app/xcode/id497799835) or the
[Apple Developer site](https://developer.apple.com/download/more/?=xcode).
Once Xcode is installed, accept the license agreement for all users with the
following command:
```posix-terminal theme={null}
sudo xcodebuild -license accept
```
### Step 2: Download the Bazel installer
Next, download the Bazel binary installer named
`bazel--installer-darwin-x86_64.sh` from the
[Bazel releases page on GitHub](https://github.com/bazelbuild/bazel/releases).
**On macOS Catalina or newer (macOS >= 11)**, due to Apple's new app signing requirements,
you need to download the installer from the terminal using `curl`, replacing
the version variable with the Bazel version you want to download:
```posix-terminal theme={null}
export BAZEL_VERSION=5.2.0
curl -fLO "https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-darwin-x86_64.sh"
```
This is a temporary workaround until the macOS release flow supports
signing ([#9304](https://github.com/bazelbuild/bazel/issues/9304)).
### Step 3: Run the installer
Run the Bazel installer as follows:
```posix-terminal theme={null}
chmod +x "bazel-$BAZEL_VERSION-installer-darwin-x86_64.sh"
./bazel-$BAZEL_VERSION-installer-darwin-x86_64.sh --user
```
The `--user` flag installs Bazel to the `$HOME/bin` directory on your system and
sets the `.bazelrc` path to `$HOME/.bazelrc`. Use the `--help` command to see
additional installation options.
If you are **on macOS Catalina or newer (macOS >= 11)** and get an error that ***“bazel-real” cannot be
opened because the developer cannot be verified***, you need to re-download
the installer from the terminal using `curl` as a workaround; see Step 2 above.
### Step 4: Set up your environment
If you ran the Bazel installer with the `--user` flag as above, the Bazel
executable is installed in your `HOME/bin` directory.
It's a good idea to add this directory to your default paths, as follows:
```posix-terminal theme={null}
export PATH="PATH:HOME/bin"
```
You can also add this command to your `~/.bashrc`, `~/.zshrc`, or `~/.profile`
file.
All set! You can confirm Bazel is installed successfully by running the
following command:
```posix-terminal theme={null}
bazel --version
```
To update to a newer release of Bazel, download and install the desired version.
# Installing Bazel on openSUSE Tumbleweed & Leap
Source: https://bazel.build/install/suse
This page describes how to install Bazel on openSUSE Tumbleweed and Leap.
`NOTE:` The Bazel team does not officially maintain openSUSE support. For issues
using Bazel on openSUSE please file a ticket at [bugzilla.opensuse.org](https://bugzilla.opensuse.org/).
Packages are provided for openSUSE Tumbleweed and Leap. You can find all
available Bazel versions via openSUSE's [software search](https://software.opensuse.org/search?utf8=%E2%9C%93\&baseproject=ALL\&q=bazel).
The commands below must be run either via `sudo` or while logged in as `root`.
## Installing Bazel on openSUSE
Run the following commands to install the package. If you need a specific
version, you can install it via the specific `bazelXXX` package, otherwise,
just `bazel` is enough:
To install the latest version of Bazel, run:
```posix-terminal theme={null}
zypper install bazel
```
You can also install a specific version of Bazel by specifying the package
version with `bazelversion`. For example, to install
Bazel 4.2, run:
```posix-terminal theme={null}
zypper install bazel4.2
```
# Installing Bazel on Ubuntu
Source: https://bazel.build/install/ubuntu
This page describes the options for installing Bazel on Ubuntu.
It also provides links to the Bazel completion scripts and the binary installer,
if needed as a backup option (for example, if you don't have admin access).
Supported Ubuntu Linux platforms:
* 22.04 (LTS)
* 20.04 (LTS)
* 18.04 (LTS)
Bazel should be compatible with other Ubuntu releases and Debian
"stretch" and above, but is untested and not guaranteed to work.
Install Bazel on Ubuntu using one of the following methods:
* *Recommended*: [Use Bazelisk](/install/bazelisk)
* [Use our custom APT repository](#install-on-ubuntu)
* [Use the binary installer](#binary-installer)
* [Use the Bazel Docker container](#docker-container)
* [Compile Bazel from source](/install/compile-source)
**Note:** For Arm-based systems, the APT repository does not contain an `arm64`
release, and there is no binary installer available. Either use Bazelisk or
compile from source.
Bazel comes with two completion scripts. After installing Bazel, you can:
* Access the [bash completion script](/install/completion#bash)
* Install the [zsh completion script](/install/completion#zsh)
## Using Bazel's apt repository
### Step 1: Add Bazel distribution URI as a package source
**Note:** This is a one-time setup step.
```posix-terminal theme={null}
sudo apt install apt-transport-https curl gnupg -y
curl -fsSL https://releases.bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg
sudo mv bazel-archive-keyring.gpg /usr/share/keyrings
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
```
The component name "jdk1.8" is kept only for legacy reasons and doesn't relate
to supported or included JDK versions. Bazel releases are Java-version agnostic.
Changing the "jdk1.8" component name would break existing users of the repo.
### Step 2: Install and update Bazel
```posix-terminal theme={null}
sudo apt update && sudo apt install bazel
```
Once installed, you can upgrade to a newer version of Bazel as part of your normal system updates:
```posix-terminal theme={null}
sudo apt update && sudo apt full-upgrade
```
The `bazel` package always installs the latest stable version of Bazel. You
can install specific, older versions of Bazel in addition to the latest one,
such as this:
```posix-terminal theme={null}
sudo apt install bazel-1.0.0
```
This installs Bazel 1.0.0 as `/usr/bin/bazel-1.0.0` on your system. This
can be useful if you need a specific version of Bazel to build a project, for
example because it uses a `.bazelversion` file to explicitly state with which
Bazel version it should be built.
Optionally, you can set `bazel` to a specific version by creating a symlink:
```posix-terminal theme={null}
sudo ln -s /usr/bin/bazel-1.0.0 /usr/bin/bazel
bazel --version # 1.0.0
```
### Step 3: Install a JDK (optional)
Bazel includes a private, bundled JRE as its runtime and doesn't require you to
install any specific version of Java.
However, if you want to build Java code using Bazel, you have to install a JDK.
```posix-terminal theme={null}
sudo apt install default-jdk
```
## Using the binary installer
Generally, you should use the apt repository, but the binary installer
can be useful if you don't have admin permissions on your machine or
can't add custom repositories.
The binary installers can be downloaded from Bazel's [GitHub releases page](https://github.com/bazelbuild/bazel/releases).
The installer contains the Bazel binary and extracts it into your `$HOME/bin`
folder. Some additional libraries must be installed manually for Bazel to work.
### Step 1: Install required packages
Bazel needs a C++ compiler and unzip / zip in order to work:
```posix-terminal theme={null}
sudo apt install g++ unzip zip
```
If you want to build Java code using Bazel, install a JDK:
```posix-terminal theme={null}
sudo apt-get install default-jdk
```
### Step 2: Run the installer
Next, download the Bazel binary installer named `bazel-version-installer-linux-x86_64.sh`
from the [Bazel releases page on GitHub](https://github.com/bazelbuild/bazel/releases).
Run it as follows:
```posix-terminal theme={null}
chmod +x bazel-version-installer-linux-x86_64.sh
./bazel-version-installer-linux-x86_64.sh --user
```
The `--user` flag installs Bazel to the `$HOME/bin` directory on your system and
sets the `.bazelrc` path to `$HOME/.bazelrc`. Use the `--help` command to see
additional installation options.
### Step 3: Set up your environment
If you ran the Bazel installer with the `--user` flag as above, the Bazel
executable is installed in your `$HOME/bin` directory.
It's a good idea to add this directory to your default paths, as follows:
```posix-terminal theme={null}
export PATH="$PATH:$HOME/bin"
```
You can also add this command to your `~/.bashrc` or `~/.zshrc` file to make it
permanent.
## Using the Bazel Docker container
We publish Docker container with Bazel installed for each Bazel version at `gcr.io/bazel-public/bazel`.
You can use the Docker container as follows:
```
$ docker pull gcr.io/bazel-public/bazel:
```
The Docker container is built by [these steps](https://github.com/bazelbuild/continuous-integration/tree/master/bazel/oci).
# Installing Bazel on Windows
Source: https://bazel.build/install/windows
This page describes the requirements and steps to install Bazel on Windows.
It also includes troubleshooting and other ways to install Bazel, such as
using Chocolatey or Scoop.
## Installing Bazel
This section covers the prerequisites, environment setup, and detailed
steps during installation on Windows.
### Check your system
Recommended: 64 bit Windows 10, version 1703 (Creators Update) or newer
To check your Windows version:
* Click the Start button.
* Type `winver` in the search box and press Enter.
* You should see the About Windows box with your Windows version information.
### Install the prerequisites
* [Microsoft Visual C++ Redistributable](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170)
### Download Bazel
*Recommended*: [Use Bazelisk](/install/bazelisk)
Alternatively you can:
* [Download the Bazel binary (`bazel-version-windows-x86_64.exe`) from GitHub](https://github.com/bazelbuild/bazel/releases).
* [Install Bazel from Chocolatey](#chocolately)
* [Install Bazel from Scoop](#scoop)
* [Build Bazel from source](/install/compile-source)
### Set up your environment
To make Bazel easily accessible from command prompts or PowerShell by default, you can rename the Bazel binary to `bazel.exe` and add it to your default paths.
```posix-terminal theme={null}
set PATH=%PATH%;path to the Bazel binary
```
You can also change your system `PATH` environment variable to make it permanent. Check out how to [set environment variables](/configure/windows#set-environment-variables).
### Done
"Success: You've installed Bazel."
To check the installation is correct, try to run:
```posix-terminal theme={null}
bazel version
```
Next, you can check out more tips and guidance here:
* [Installing compilers and language runtimes](#install-compilers)
* [Troubleshooting](#troubleshooting)
* [Best practices on Windows](/configure/windows#best-practices)
* [Tutorials](/start/#tutorials)
## Installing compilers and language runtimes
Depending on which languages you want to build, you will need:
* [MSYS2 x86\_64](https://www.msys2.org/)
MSYS2 is a software distro and building platform for Windows. It contains Bash and common Unix
tools (like `grep`, `tar`, `git`).
You will need MSYS2 to build, test, or run targets that depend on Bash. Typically these are
`genrule`, `sh_binary`, `sh_test`, but there may be more (such as Starlark rules). Bazel shows an
error if a build target needs Bash but Bazel could not locate it.
* Common MSYS2 packages
You will likely need these to build and run targets that depend on Bash. MSYS2 does not install
these tools by default, so you need to install them manually. Projects that depend on Bash tools in `PATH` need this step (for example TensorFlow).
Open the MSYS2 terminal and run this command:
```posix-terminal theme={null}
pacman -S zip unzip patch diffutils git
```
Optional: If you want to use Bazel from CMD or Powershell and still be able
to use Bash tools, make sure to add
`MSYS2_INSTALL_PATH/usr/bin` to your
`PATH` environment variable.
* [Build Tools for Visual Studio 2019](https://aka.ms/buildtools)
You will need this to build C++ code on Windows.
Also supported:
* Visual C++ Build Tools 2017 (or newer) and Windows 10 SDK
* [Java SE Development Kit 11 (JDK) for Windows x64](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html)
You will need this to build Java code on Windows.
Also supported: Java 8, 9, and 10
* [Python 3.6 for Windows x86-64](https://www.python.org/downloads/windows/)
You will need this to build Python code on Windows.
Also supported: Python 2.7 or newer for Windows x86-64
## Troubleshooting
### Bazel does not find Bash or bash.exe
**Possible reasons**:
* you installed MSYS2 not under the default install path
* you installed MSYS2 i686 instead of MSYS2 x86\_64
* you installed MSYS instead of MSYS2
**Solution**:
Ensure you installed MSYS2 x86\_64.
If that doesn't help:
1. Go to Start Menu > Settings.
2. Find the setting "Edit environment variables for your account"
3. Look at the list on the top ("User variables for \"), and click the "New\..."
button below it.
4. For "Variable name", enter `BAZEL_SH`
5. Click "Browse File..."
6. Navigate to the MSYS2 directory, then to `usr\bin` below it.
For example, this might be `C:\msys64\usr\bin` on your system.
7. Select the `bash.exe` or `bash` file and click OK
8. The "Variable value" field now has the path to `bash.exe`. Click OK to close the window.
9. Done.
If you open a new cmd.exe or PowerShell terminal and run Bazel now, it will find Bash.
### Bazel does not find Visual Studio or Visual C++
**Possible reasons**:
* you installed multiple versions of Visual Studio
* you installed and removed various versions of Visual Studio
* you installed various versions of the Windows SDK
* you installed Visual Studio not under the default install path
**Solution**:
1. Go to Start Menu > Settings.
2. Find the setting "Edit environment variables for your account"
3. Look at the list on the top ("User variables for \"), and click the "New\..."
button below it.
4. For "Variable name", enter `BAZEL_VC`
5. Click "Browse Directory..."
6. Navigate to the `VC` directory of Visual Studio.
For example, this might be `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC`
on your system.
7. Select the `VC` folder and click OK
8. The "Variable value" field now has the path to `VC`. Click OK to close the window.
9. Done.
If you open a new cmd.exe or PowerShell terminal and run Bazel now, it will find Visual C++.
## Other ways to install Bazel
### Using Chocolatey
1. Install the [Chocolatey](https://chocolatey.org) package manager
2. Install the Bazel package:
```posix-terminal theme={null}
choco install bazel
```
This command will install the latest available version of Bazel and
its dependencies, such as the MSYS2 shell. This will not install Visual C++
though.
See [Chocolatey installation and package maintenance guide](/contribute/windows-chocolatey-maintenance) for more
information about the Chocolatey package.
### Using Scoop
1. Install the [Scoop](https://scoop.sh/) package manager using the following PowerShell command:
```posix-terminal theme={null}
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
```
2. Install the Bazel package:
```posix-terminal theme={null}
scoop install bazel
```
See [Scoop installation and package maintenance guide](/contribute/windows-scoop-maintenance) for more
information about the Scoop package.
### Build from source
To build Bazel from scratch instead of installing, see [Compiling from source](/install/compile-source).
# Migrating to Bazel
Source: https://bazel.build/migrate/index
This page links to migration guides for Bazel.
* [Maven](/migrate/maven)
* [Xcode](/migrate/xcode)
# Migrating from Maven to Bazel
Source: https://bazel.build/migrate/maven
This page describes how to migrate from Maven to Bazel, including the
prerequisites and installation steps. It describes the differences between Maven
and Bazel, and provides a migration example using the Guava project.
When migrating from any build tool to Bazel, it's best to have both build tools
running in parallel until you have fully migrated your development team, CI
system, and any other relevant systems. You can run Maven and Bazel in the same
repository.
Note: While Bazel supports downloading and publishing Maven artifacts with
[rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external)
, it does not directly support Maven-based plugins. Maven plugins can't be
directly run by Bazel since there's no Maven compatibility layer.
## Before you begin
* [Install Bazel](/install) if it's not yet installed.
* If you're new to Bazel, go through the tutorial [Introduction to Bazel: Build Java](/start/java) before you start migrating. The tutorial explains
Bazel's concepts, structure, and label syntax.
## Differences between Maven and Bazel
* Maven uses top-level `pom.xml` file(s). Bazel supports multiple build files
and multiple targets per `BUILD` file, allowing for builds that are more
incremental than Maven's.
* Maven takes charge of steps for the deployment process. Bazel does not
automate deployment.
* Bazel enables you to express dependencies between languages.
* As you add new sections to the project, with Bazel you may need to add new
`BUILD` files. Best practice is to add a `BUILD` file to each new Java
package.
## Migrate from Maven to Bazel
The steps below describe how to migrate your project to Bazel:
1. [Create the MODULE.bazel file](#1-build)
2. [Create one BUILD file](#2-build)
3. [Create more BUILD files](#3-build)
4. [Build using Bazel](#4-build)
Examples below come from a migration of the [Guava project](https://github.com/google/guava) from Maven to Bazel. The
Guava project used is release `v31.1`. The examples using Guava do not walk
through each step in the migration, but they do show the files and contents that
are generated or added manually for the migration.
```
$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1
```
### Create the MODULE.bazel file
Create a file named `MODULE.bazel` at the root of your project. If your project
has no external dependencies, this file can be empty.
If your project depends on files or packages that are not in one of the
project's directories, specify these external dependencies in the MODULE.bazel
file. You can use `rules_jvm_external` to manage dependencies from Maven. For
instructions about using this ruleset, see [the README](https://github.com/bazelbuild/rules_jvm_external/#rules_jvm_external)
.
#### Guava project example: external dependencies
You can list the external dependencies of the [Guava project](https://github.com/google/guava) with the
[`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external)
ruleset.
Add the following snippet to the `MODULE.bazel` file:
```python theme={null}
bazel_dep(name = "rules_jvm_external", version = "6.2")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
artifacts = [
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.errorprone:error_prone_annotations:2.11.0",
"com.google.j2objc:j2objc-annotations:1.3",
"org.codehaus.mojo:animal-sniffer-annotations:1.20",
"org.checkerframework:checker-qual:3.12.0",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
use_repo(maven, "maven")
```
### Create one BUILD file
Now that you have your workspace defined and external dependencies (if
applicable) listed, you need to create `BUILD` files to describe how your
project should be built. Unlike Maven with its one `pom.xml` file, Bazel can use
many `BUILD` files to build a project. These files specify multiple build
targets, which allow Bazel to produce incremental builds.
Add `BUILD` files in stages. Start with adding one `BUILD` file at the root of
your project and using it to do an initial build using Bazel. Then, you refine
your build by adding more `BUILD` files with more granular targets.
1. In the same directory as your `MODULE.bazel` file, create a text file and
name it `BUILD`.
2. In this `BUILD` file, use the appropriate rule to create one target to build
your project. Here are some tips:
* Use the appropriate rule:
* To build projects with a single Maven module, use the
`java_library` rule as follows:
```python theme={null}
java_library(
name = "everything",
srcs = glob(["src/main/java/**/*.java"]),
resources = glob(["src/main/resources/**"]),
deps = ["//:all-external-targets"],
)
```
* To build projects with multiple Maven modules, use the
`java_library` rule as follows:
```python theme={null}
java_library(
name = "everything",
srcs = glob([
"Module1/src/main/java/**/*.java",
"Module2/src/main/java/**/*.java",
...
]),
resources = glob([
"Module1/src/main/resources/**",
"Module2/src/main/resources/**",
...
]),
deps = ["//:all-external-targets"],
)
```
* To build binaries, use the `java_binary` rule:
```python theme={null}
java_binary(
name = "everything",
srcs = glob(["src/main/java/**/*.java"]),
resources = glob(["src/main/resources/**"]),
deps = ["//:all-external-targets"],
main_class = "com.example.Main"
)
```
* Specify the attributes:
* `name`: Give the target a meaningful name. In the examples
above, the target is called "everything."
* `srcs`: Use globbing to list all .java files in your project.
* `resources`: Use globbing to list all resources in your project.
* `deps`: You need to determine which external dependencies your
project needs.
* Take a look at the [example below of this top-level BUILD file](#guava-2) from the migration of the Guava project.
3. Now that you have a `BUILD` file at the root of your project, build your
project to ensure that it works. On the command line, from your workspace
directory, use `bazel build //:everything` to build your project with Bazel.
The project has now been successfully built with Bazel. You will need to add
more `BUILD` files to allow incremental builds of the project.
#### Guava project example: start with one BUILD file
When migrating the Guava project to Bazel, initially one `BUILD` file is used to
build the entire project. Here are the contents of this initial `BUILD` file in
the workspace directory:
```python theme={null}
java_library(
name = "everything",
srcs = glob([
"guava/src/**/*.java",
"futures/failureaccess/src/**/*.java",
]),
javacopts = ["-XepDisableAllChecks"],
deps = [
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_j2objc_j2objc_annotations",
"@maven//:org_checkerframework_checker_qual",
"@maven//:org_codehaus_mojo_animal_sniffer_annotations",
],
)
```
### Create more BUILD files (optional)
Bazel does work with just one `BUILD file`, as you saw after completing your
first build. You should still consider breaking the build into smaller chunks by
adding more `BUILD` files with granular targets.
Multiple `BUILD` files with multiple targets will give the build increased
granularity, allowing:
* increased incremental builds of the project,
* increased parallel execution of the build,
* better maintainability of the build for future users, and
* control over visibility of targets between packages, which can prevent
issues such as libraries containing implementation details leaking into
public APIs.
Tips for adding more `BUILD` files:
* You can start by adding a `BUILD` file to each Java package. Start with Java
packages that have the fewest dependencies and work you way up to packages
with the most dependencies.
* As you add `BUILD` files and specify targets, add these new targets to the
`deps` sections of targets that depend on them. Note that the `glob()`
function does not cross package boundaries, so as the number of packages
grows the files matched by `glob()` will shrink.
* Any time you add a `BUILD` file to a `main` directory, ensure that you add a
`BUILD` file to the corresponding `test` directory.
* Take care to limit visibility properly between packages.
* To simplify troubleshooting errors in your setup of `BUILD` files, ensure
that the project continues to build with Bazel as you add each build file.
Run `bazel build //...` to ensure all of your targets still build.
### Build using Bazel
You've been building using Bazel as you add `BUILD` files to validate the setup
of the build.
When you have `BUILD` files at the desired granularity, you can use Bazel to
produce all of your builds.
# Migrating from Xcode to Bazel
Source: https://bazel.build/migrate/xcode
This page describes how to build or test an Xcode project with Bazel. It
describes the differences between Xcode and Bazel, and provides the steps for
converting an Xcode project to a Bazel project. It also provides troubleshooting
solutions to address common errors.
## Differences between Xcode and Bazel
* Bazel requires you to explicitly specify every build target and its
dependencies, plus the corresponding build settings via build rules.
* Bazel requires all files on which the project depends to be present within
the workspace directory or specified as dependencies in the `MODULE.bazel`
file.
* When building Xcode projects with Bazel, the `BUILD` file(s) become the
source of truth. If you work on the project in Xcode, you must generate a
new version of the Xcode project that matches the `BUILD` files using
[rules\_xcodeproj](https://github.com/buildbuddy-io/rules_xcodeproj/)
whenever you update the `BUILD` files. Certain changes to the `BUILD` files
such as adding dependencies to a target don't require regenerating the
project which can speed up development. If you're not using Xcode, the
`bazel build` and `bazel test` commands provide build and test capabilities
with certain limitations described later in this guide.
## Before you begin
Before you begin, do the following:
1. [Install Bazel](/install) if you have not already done so.
2. If you're not familiar with Bazel and its concepts, complete the [iOS app tutorial](/start/ios-app)). You should understand the Bazel workspace,
including the `MODULE.bazel` and `BUILD` files, as well as the concepts of
targets, build rules, and Bazel packages.
3. Analyze and understand the project's dependencies.
### Analyze project dependencies
Unlike Xcode, Bazel requires you to explicitly declare all dependencies for
every target in the `BUILD` file.
For more information on external dependencies, see [Working with external dependencies](/docs/external).
## Build or test an Xcode project with Bazel
To build or test an Xcode project with Bazel, do the following:
1. [Create the `MODULE.bazel` file](#create-workspace)
2. [Integrate Swift package dependencies](#integrate-swiftpm)
3. [Create a `BUILD` file:](#create-build-file)
a. [Add the application target](#add-app-target)
b. [(Optional) Add the test target(s)](#add-test-target)
c. [Add the library target(s)](#add-library-target)
4. [(Optional) Granularize the build](#granularize-build)
5. [Run the build](#run-build)
6. [Generate the Xcode project with rules\_xcodeproj](#generate-the-xcode-project-with-rules_xcodeproj)
### Step 1: Create the `MODULE.bazel` file
Create a `MODULE.bazel` file in a new directory. This directory becomes the
Bazel workspace root. If the project uses no external dependencies, this file
can be empty. If the project depends on files or packages that are not in one of
the project's directories, specify these external dependencies in the
`MODULE.bazel` file.
Note: Place the project source code within the directory tree containing the
`MODULE.bazel` file.
### Step 2: Integrate Swift package dependencies
If the Xcode project depends on Swift packages, use [rules\_swift\_package\_manager](https://github.com/cgrindel/rules_swift_package_manager)
to make them available as Bazel targets. It reads the `Package.swift` and
`Package.resolved` files you already know from Swift Package Manager, so you
keep declaring dependencies the same way.
First, add the ruleset and the Swift package extension to your `MODULE.bazel`
file:
```python theme={null}
bazel_dep(name = "rules_swift", version = "4.0.1")
bazel_dep(name = "rules_swift_package_manager", version = "1.23.0")
swift_deps = use_extension(
"@rules_swift_package_manager//:extensions.bzl",
"swift_deps",
)
swift_deps.from_package(
resolved = "//:Package.resolved",
swift = "//:Package.swift",
)
use_repo(swift_deps, "swift_package")
```
Next, create a `Package.swift` file at the workspace root listing only the
packages your Bazel targets depend on directly:
```swift theme={null}
// swift-tools-version: 5.7
import PackageDescription
let package = Package(
name: "my-project",
dependencies: [
.package(url: "https://github.com/apple/swift-log", from: "1.4.4"),
]
)
```
Then resolve the packages and let Bazel record the resulting repositories:
```posix-terminal theme={null}
swift package update
bazel mod tidy
```
`swift package update` writes `Package.resolved`, and `bazel mod tidy` adds each
resolved package to the `use_repo` call in `MODULE.bazel`. Each package becomes
an external repository named `swiftpkg_` plus the package identity, lowercased
with punctuation replaced by underscores, and each product in the package
becomes a target in it. Depend on those targets like any other:
```python theme={null}
load("@rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "AppLib",
srcs = glob(["Sources/*.swift"]),
deps = ["@swiftpkg_swift_log//:Logging"],
)
```
Check `Package.swift`, `Package.resolved`, and `MODULE.bazel` into version
control. Re-run both commands above whenever you change `Package.swift`.
Once `Package.resolved` exists, `bazel run @swift_package//:update` and
`bazel run @swift_package//:resolve` replace `swift package update` and
`swift package resolve`, using the Swift toolchain Bazel is configured with.
For more examples, check `rules_swift_package_manager`'s [examples](https://github.com/cgrindel/rules_swift_package_manager/tree/main/examples)
### Step 3: Create a `BUILD` file
Once you have defined the workspace and external dependencies, you need to
create a `BUILD` file that tells Bazel how the project is structured. Create the
`BUILD` file at the root of the Bazel workspace and configure it to do an
initial build of the project as follows:
* [Step 3a: Add the application target](#step-3a-add-the-application-target)
* [Step 3b: (Optional) Add the test target(s)](#step-3b-optional-add-the-test-target-s)
* [Step 3c: Add the library target(s)](#step-3c-add-the-library-target-s)
**Tip:** To learn more about packages and other Bazel concepts, see [Workspaces, packages, and targets](/concepts/build-ref).
#### Step 3a: Add the application target
Add a
[`macos_application`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-macos.md#macos_application)
or an
[`ios_application`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_application)
rule target. This target builds a macOS or iOS application bundle, respectively.
In the target, specify the following at the minimum:
* `bundle_id` - the bundle ID (reverse-DNS path followed by app name) of the
binary.
* `provisioning_profile` - provisioning profile from your Apple Developer
account (if building for an iOS device).
* `families` (iOS only) - whether to build the application for iPhone, iPad,
or both.
* `infoplists` - list of .plist files to merge into the final Info.plist file.
* `minimum_os_version` - the minimum version of macOS or iOS that the
application supports. This ensures Bazel builds the application with the
correct API levels.
#### Step 3b: (Optional) Add the test target(s)
Bazel's [Apple build rules](https://github.com/bazelbuild/rules_apple) support running
unit and UI tests on all Apple platforms. Add test targets as follows:
* [`macos_unit_test`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-macos.md#macos_unit_test)
to run library-based and application-based unit tests on a macOS.
* [`ios_unit_test`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_unit_test)
to build and run library-based unit tests on iOS.
* [`ios_ui_test`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_ui_test)
to build and run user interface tests in the iOS simulator.
* Similar test rules exist for
[tvOS](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-tvos.md),
[watchOS](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-watchos.md)
and
[visionOS](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-visionos.md).
At the minimum, specify a value for the `minimum_os_version` attribute. While
other packaging attributes, such as `bundle_identifier` and `infoplists`,
default to most commonly used values, ensure that those defaults are compatible
with the project and adjust them as necessary. For tests that require the iOS
simulator, also specify the `ios_application` target name as the value of the
`test_host` attribute.
#### Step 3c: Add the library target(s)
Add an [`objc_library`](/reference/be/objective-c#objc_library) target for each
Objective-C library and a
[`swift_library`](https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_library)
target for each Swift library on which the application and/or tests depend.
Add the library targets as follows:
* Add the application library targets as dependencies to the application
targets.
* Add the test library targets as dependencies to the test targets.
* List the implementation sources in the `srcs` attribute.
* List the headers in the `hdrs` attribute.
Note: You can use the [`glob`](/reference/be/functions#glob) function to include
all sources and/or headers of a certain type. Use it carefully as it might
include files you do not want Bazel to build.
You can browse existing examples for various types of applications directly in
the [rules\_apple examples directory](https://github.com/bazelbuild/rules_apple/tree/master/examples/). For
example:
* [macOS application targets](https://github.com/bazelbuild/rules_apple/tree/master/examples/macos)
* [iOS applications targets](https://github.com/bazelbuild/rules_apple/tree/master/examples/ios)
* [Multi platform applications (macOS, iOS, watchOS, tvOS)](https://github.com/bazelbuild/rules_apple/tree/master/examples/multi_platform)
For more information on build rules, see [Apple Rules for Bazel](https://github.com/bazelbuild/rules_apple).
At this point, it is a good idea to test the build:
`bazel build //:`
### Step 4: (Optional) Granularize the build
If the project is large, or as it grows, consider chunking it into multiple
Bazel packages. This increased granularity provides:
* Increased incrementality of builds,
* Increased parallelization of build tasks,
* Better maintainability for future users,
* Better control over source code visibility across targets and packages. This
prevents issues such as libraries containing implementation details leaking
into public APIs.
Tips for granularizing the project:
* Put each library in its own Bazel package. Start with those requiring the
fewest dependencies and work your way up the dependency tree.
* As you add `BUILD` files and specify targets, add these new targets to the
`deps` attributes of targets that depend on them.
* The `glob()` function does not cross package boundaries, so as the number of
packages grows the files matched by `glob()` will shrink.
* When adding a `BUILD` file to a `main` directory, also add a `BUILD` file to
the corresponding `test` directory.
* Enforce healthy visibility limits across packages.
* Build the project after each major change to the `BUILD` files and fix build
errors as you encounter them.
### Step 5: Run the build
Run the fully migrated build to ensure it completes with no errors or warnings.
Run every application and test target individually to more easily find sources
of any errors that occur.
For example:
```posix-terminal theme={null}
bazel build //:my-target
```
### Step 6: Generate the Xcode project with rules\_xcodeproj
When building with Bazel, the `MODULE.bazel` and `BUILD` files become the source
of truth about the build. To make Xcode aware of this, you must generate a
Bazel-compatible Xcode project using
[rules\_xcodeproj](https://github.com/buildbuddy-io/rules_xcodeproj#features)
.
### Troubleshooting
Bazel errors can arise when it gets out of sync with the selected Xcode version,
like when you apply an update. Here are some things to try if you're
experiencing errors with Xcode, for example "Xcode version must be specified to
use an Apple CROSSTOOL".
* Manually run Xcode and accept any terms and conditions.
* Use Xcode select to indicate the correct version, accept the license, and
clear Bazel's state.
```posix-terminal theme={null}
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
bazel sync --configure
```
* If this does not work, you may also try running `bazel clean --expunge`.
Note: If you've saved your Xcode to a different path, you can use `xcode-select
-s` to point to that path.
# Query guide
Source: https://bazel.build/query/guide
This page covers how to get started using Bazel's query language to trace
dependencies in your code.
For a language details and `--output` flag details, please see the
reference manuals, [Bazel query reference](/query/language)
and [Bazel cquery reference](/query/cquery). You can get help by
typing `bazel help query` or `bazel help cquery` on the
command line.
To execute a query while ignoring errors such as missing targets, use the
`--keep_going` flag.
## Finding the dependencies of a rule
To see the dependencies of `//foo`, use the
`deps` function in bazel query:
```
$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...
```
This is the set of all targets required to build `//foo`.
## Tracing the dependency chain between two packages
The library `//third_party/zlib:zlibonly` isn't in the BUILD file for
`//foo`, but it is an indirect dependency. How can
we trace this dependency path? There are two useful functions here:
`allpaths` and `somepath`. You may also want to exclude
tooling dependencies with `--notool_deps` if you care only about
what is included in the artifact you built, and not every possible job.
To visualize the graph of all dependencies, pipe the bazel query output through
the `dot` command-line tool:
```
$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg
```
Note: `dot` supports other image formats, just replace `svg` with the
format identifier, for example, `png`.
When a dependency graph is big and complicated, it can be helpful start with a single path:
```
$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)"
//foo:foo
//translations/tools:translator
//translations/base:base
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/zlib:zlibonly
```
If you do not specify `--output graph` with `allpaths`,
you will get a flattened list of the dependency graph.
```
$ bazel query "allpaths(//foo, third_party/...)"
...many errors detected in BUILD files...
//foo:foo
//translations/tools:translator
//translations/tools:aggregator
//translations/base:base
//tools/pkg:pex
//tools/pkg:pex_phase_one
//tools/pkg:pex_lib
//third_party/python:python_lib
//translations/tools:messages
//third_party/py/xml:xml
//third_party/py/xml:utils/boolean.so
//third_party/py/xml:parsers/sgmlop.so
//third_party/py/xml:parsers/pyexpat.so
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/openssl:openssl
//third_party/zlib:zlibonly
//third_party/zlib:zlibonly_v1_2_3
//third_party/python:headers
//third_party/openssl:crypto
```
### Aside: implicit dependencies
The BUILD file for `//foo` never references
`//translations/tools:aggregator`. So, where's the direct dependency?
Certain rules include implicit dependencies on additional libraries or tools.
For example, to build a `genproto` rule, you need first to build the Protocol
Compiler, so every `genproto` rule carries an implicit dependency on the
protocol compiler. These dependencies are not mentioned in the build file,
but added in by the build tool. The full set of implicit dependencies is
currently undocumented. Using `--noimplicit_deps` allows you to filter out
these deps from your query results. For cquery, this will include resolved toolchains.
## Reverse dependencies
You might want to know the set of targets that depends on some target. For instance,
if you're going to change some code, you might want to know what other code
you're about to break. You can use `rdeps(u, x)` to find the reverse
dependencies of the targets in `x` within the transitive closure of `u`.
Bazel's [Sky Query](/query/language#sky-query)
supports the `allrdeps` function which allows you to query reverse dependencies
in a universe you specify.
## Miscellaneous uses
You can use `bazel query` to analyze many dependency relationships.
### What exists ...
#### What packages exist beneath `foo`?
```
bazel query 'foo/...' --output package
```
#### What rules are defined in the `foo` package?
```
bazel query 'kind(rule, foo:*)' --output label_kind
```
#### What files are generated by rules in the `foo` package?
```
bazel query 'kind("generated file", //foo:*)'
```
#### What targets are generated by starlark macro `foo`?
```
bazel query 'attr(generator_function, foo, //path/to/search/...)'
```
#### What's the set of BUILD files needed to build `//foo`?
```
bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:
```
#### What are the individual tests that a `test_suite` expands to?
```
bazel query 'tests(//foo:smoke_tests)'
```
#### Which of those are C++ tests?
```
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
```
#### Which of those are small? Medium? Large?
```
bazel query 'attr(size, small, tests(//foo:smoke_tests))'
bazel query 'attr(size, medium, tests(//foo:smoke_tests))'
bazel query 'attr(size, large, tests(//foo:smoke_tests))'
```
#### What are the tests beneath `foo` that match a pattern?
```
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
```
The pattern is a regex and is applied to the full name of the rule. It's similar to doing
```
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
```
#### What package contains file `path/to/file/bar.java`?
```
bazel query path/to/file/bar.java --output=package
```
#### What is the build label for `path/to/file/bar.java?`
```
bazel query path/to/file/bar.java
```
#### What rule target(s) contain file `path/to/file/bar.java` as a source?
```
fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
```
### What package dependencies exist ...
#### What packages does `foo` depend on? (What do I need to check out to build `foo`)
```
bazel query 'buildfiles(deps(//foo:foo))' --output package
```
Note: `buildfiles` is required in order to correctly obtain all files
referenced by `subinclude`; see the reference manual for details.
#### What packages does the `foo` tree depend on, excluding `foo/contrib`?
```
bazel query 'deps(foo/... except foo/contrib/...)' --output package
```
### What rule dependencies exist ...
#### What genproto rules does bar depend upon?
```
bazel query 'kind(genproto, deps(bar/...))'
```
#### Find the definition of some JNI (C++) library that is transitively depended upon by a Java binary rule in the servlet tree.
```
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
```
##### ...Now find the definitions of all the Java binaries that depend on them
```
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in
let cls = kind(cc_.*library, deps($jbs)) in
$jbs intersect allpaths($jbs, $cls)'
```
### What file dependencies exist ...
#### What's the complete set of Java source files required to build foo?
Source files:
```
bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$
```
Generated files:
```
bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$
```
#### What is the complete set of Java source files required to build QUX's tests?
Source files:
```
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
```
Generated files:
```
bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
```
### What differences in dependencies between X and Y exist ...
#### What targets does `//foo` depend on that `//foo:foolib` does not?
```
bazel query 'deps(//foo) except deps(//foo:foolib)'
```
#### What C++ libraries do the `foo` tests depend on that the `//foo` production binary does *not* depend on?
```
bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
```
### Why does this dependency exist ...
#### Why does `bar` depend on `groups2`?
```
bazel query 'somepath(bar/...,groups2/...:*)'
```
Once you have the results of this query, you will often find that a single
target stands out as being an unexpected or egregious and undesirable
dependency of `bar`. The query can then be further refined to:
#### Show me a path from `docker/updater:updater_systest` (a `py_test`) to some `cc_library` that it depends upon:
```
bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
somepath(docker/updater:updater_systest, $cc)'
```
#### Why does library `//photos/frontend:lib` depend on two variants of the same library `//third_party/jpeglib` and `//third_party/jpeg`?
This query boils down to: "show me the subgraph of `//photos/frontend:lib` that
depends on both libraries". When shown in topological order, the last element
of the result is the most likely culprit.
```
bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib)
intersect
allpaths(//photos/frontend:lib, //third_party/jpeg)'
//photos/frontend:lib
//photos/frontend:lib_impl
//photos/frontend:lib_dispatcher
//photos/frontend:icons
//photos/frontend/modules/gadgets:gadget_icon
//photos/thumbnailer:thumbnail_lib
//third_party/jpeg/img:renderer
```
### What depends on ...
#### What rules under bar depend on Y?
```
bazel query 'bar/... intersect allpaths(bar/..., Y)'
```
Note: `X intersect allpaths(X, Y)` is the general idiom for the query "which X
depend on Y?" If expression X is non-trivial, it may be convenient to bind a
name to it using `let` to avoid duplication.
#### What targets directly depend on T, in T's package?
```
bazel query 'same_pkg_direct_rdeps(T)'
```
### How do I break a dependency ...
#### What dependency paths do I have to break to make `bar` no longer depend on X?
To output the graph to a `svg` file:
```
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg
```
### Misc
#### How many sequential steps are there in the `//foo-tests` build?
Unfortunately, the query language can't currently give you the longest path
from x to y, but it can find the (or rather *a*) most distant node from the
starting point, or show you the *lengths* of the longest path from x to every
y that it depends on. Use `maxrank`:
```
bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c
```
The result indicates that there exist paths of length 85 that must occur in
order in this build.
# The Bazel Query Reference
Source: https://bazel.build/query/language
This page is the reference manual for the *Bazel Query Language* used
when you use `bazel query` to analyze build dependencies. It also
describes the output formats `bazel query` supports.
For practical use cases, see the [Bazel Query How-To](/query/guide).
## Additional query reference
In addition to `query`, which runs on the post-loading phase target graph,
Bazel includes *action graph query* and *configurable query*.
### Action graph query
The action graph query (`aquery`) operates on the post-analysis Configured
Target Graph and exposes information about **Actions**, **Artifacts**, and
their relationships. `aquery` is useful when you are interested in the
properties of the Actions/Artifacts generated from the Configured Target Graph.
For example, the actual commands run and their inputs, outputs, and mnemonics.
For more details, see the [aquery reference](/query/aquery).
### Configurable query
Traditional Bazel query runs on the post-loading phase target graph and
therefore has no concept of configurations and their related concepts. Notably,
it doesn't correctly resolve [select statements](/reference/be/functions#select)
and instead returns all possible resolutions of selects. However, the
configurable query environment, `cquery`, properly handles configurations but
doesn't provide all of the functionality of this original query.
For more details, see the [cquery reference](/query/cquery).
## Examples
How do people use `bazel query`? Here are typical examples:
Why does the `//foo` tree depend on `//bar/baz`?
Show a path:
```
somepath(foo/..., //bar/baz:all)
```
What C++ libraries do all the `foo` tests depend on that
the `foo_bin` target does not?
```
kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))
```
## Tokens: The lexical syntax
Expressions in the query language are composed of the following
tokens:
* **Keywords**, such as `let`. Keywords are the reserved words of the
language, and each of them is described below. The complete set
of keywords is:
* [`except`](#set-operations)
* [`in`](#variables)
* [`intersect`](#set-operations)
* [`let`](#variables)
* [`set`](#set)
* [`union`](#set-operations)
* **Words**, such as "`foo/...`" or "`.*test rule`" or "`//bar/baz:all`". If a
character sequence is "quoted" (begins and ends with a single-quote ' or
begins and ends with a double-quote "), it is a word. If a character sequence
is not quoted, it may still be parsed as a word. Unquoted words are sequences
of characters drawn from the alphabet characters A-Za-z, the numerals 0-9,
and the special characters `*/@.-_:$~[]` (asterisk, forward slash, at, period,
hyphen, underscore, colon, dollar sign, tilde, left square brace, right square
brace). However, unquoted words may not start with a hyphen `-` or asterisk `*`
even though relative [target names](/concepts/labels#target-names) may start
with those characters. As a special rule meant to simplify the handling of
labels referring to external repositories, unquoted words that start with
`@@` may contain `+` characters.
Unquoted words also may not include the characters plus sign `+` or equals
sign `=`, even though those characters are permitted in target names. When
writing code that generates query expressions, target names should be quoted.
Quoting *is* necessary when writing scripts that construct Bazel query
expressions from user-supplied values.
```
//foo:bar+wiz # WRONG: scanned as //foo:bar + wiz.
//foo:bar=wiz # WRONG: scanned as //foo:bar = wiz.
"//foo:bar+wiz" # OK.
"//foo:bar=wiz" # OK.
```
Note that this quoting is in addition to any quoting that may be required by
your shell, such as:
```posix-terminal theme={null}
bazel query ' "//foo:bar=wiz" ' # single-quotes for shell, double-quotes for Bazel.
```
Keywords and operators, when quoted, are treated as ordinary words. For example, `some` is a
keyword but "some" is a word. Both `foo` and "foo" are words.
However, be careful when using single or double quotes in target names. When
quoting one or more target names, use only one type of quotes (either all
single or all double quotes).
The following are examples of what the Java query string will be:
```
'a"'a' # WRONG: Error message: unclosed quotation.
"a'"a" # WRONG: Error message: unclosed quotation.
'"a" + 'a'' # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
"'a' + "a"" # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
"a'a" # OK.
'a"a' # OK.
'"a" + "a"' # OK
"'a' + 'a'" # OK
```
We chose this syntax so that quote marks aren't needed in most cases. The
(unusual) `".*test rule"` example needs quotes: it starts with a period and
contains a space. Quoting `"cc_library"` is unnecessary but harmless.
* **Punctuation**, such as parens `()`, period `.` and comma `,`. Words
containing punctuation (other than the exceptions listed above) must be quoted.
Whitespace characters outside of a quoted word are ignored.
## Bazel query language concepts
The Bazel query language is a language of expressions. Every
expression evaluates to a **partially-ordered set** of targets,
or equivalently, a **graph** (DAG) of targets. This is the only
datatype.
Set and graph refer to the same datatype, but emphasize different
aspects of it, for example:
* **Set:** The partial order of the targets is not interesting.
* **Graph:** The partial order of targets is significant.
### Cycles in the dependency graph
Build dependency graphs should be acyclic.
The algorithms used by the query language are robust against cycles, and will
not report cycles as errors.
Note that the post-loading phase unconfigured target graph that `bazel query`
operates over may contain cycles that do not exist in the configured target
graph. Cycles in the configured target graph are detected and reported as errors
by [`bazel cquery`](/query/cquery) and [`bazel aquery`](/query/aquery).
### Implicit dependencies
In addition to build dependencies that are defined explicitly in `BUILD` files,
Bazel adds additional *implicit* dependencies to rules. Implicit dependencies
may be defined by:
* [Private attributes](/extending/rules#private_attributes_and_implicit_dependencies)
* [Toolchain requirements](/extending/toolchains#writing-rules-toolchains)
By default, `bazel query` takes implicit dependencies into account
when computing the query result. This behavior can be changed with
the `--[no]implicit_deps` option.
Note that, as query does not consider configurations, potential toolchain
**implementations** are not considered dependencies, only the
required toolchain types. See
[toolchain documentation](/extending/toolchains#writing-rules-toolchains).
### Soundness
Bazel query language expressions operate over the build
dependency graph, which is the graph implicitly defined by all
rule declarations in all `BUILD` files. It is important to understand
that this graph is somewhat abstract, and does not constitute a
complete description of how to perform all the steps of a build. In
order to perform a build, a *configuration* is required too;
see the [configurations](/docs/user-manual#configurations)
section of the User's Guide for more detail.
The result of evaluating an expression in the Bazel query language
is true *for all configurations*, which means that it may be
a conservative over-approximation, and not exactly precise. If you
use the query tool to compute the set of all source files needed
during a build, it may report more than are actually necessary
because, for example, the query tool will include all the files
needed to support message translation, even though you don't intend
to use that feature in your build.
### On the preservation of graph order
Operations preserve any ordering
constraints inherited from their subexpressions. You can think of
this as "the law of conservation of partial order". Consider an
example: if you issue a query to determine the transitive closure of
dependencies of a particular target, the resulting set is ordered
according to the dependency graph. If you filter that set to
include only the targets of `file` kind, the same
*transitive* partial ordering relation holds between every
pair of targets in the resulting subset - even though none of
these pairs is actually directly connected in the original graph.
(There are no file-file edges in the build dependency graph).
However, while all operators *preserve* order, some
operations, such as the [set operations](#set-operations)
don't *introduce* any ordering constraints of their own.
Consider this expression:
```
deps(x) union y
```
The order of the final result set is guaranteed to preserve all the
ordering constraints of its subexpressions, namely, that all the
transitive dependencies of `x` are correctly ordered with
respect to each other. However, the query guarantees nothing about
the ordering of the targets in `y`, nor about the
ordering of the targets in `deps(x)` relative to those in
`y` (except for those targets in
`y` that also happen to be in `deps(x)`).
Operators that introduce ordering constraints include:
`allpaths`, `deps`, `rdeps`, `somepath`, and the target pattern wildcards
`package:*`, `dir/...`, etc.
### Sky query
*Sky Query* is a mode of query that operates over a specified *universe scope*.
#### Special functions available only in SkyQuery
Sky Query mode has the additional query functions `allrdeps` and
`rbuildfiles`. These functions operate over the entire
universe scope (which is why they don't make sense for normal Query).
#### Specifying a universe scope
Sky Query mode is activated by passing the following two flags:
(`--universe_scope` or `--infer_universe_scope`) and
`--order_output=no`.
`--universe_scope=,...,` tells query to
preload the transitive closure of the target pattern specified by the target patterns, which can
be both additive and subtractive. All queries are then evaluated in this "scope". In particular,
the [`allrdeps`](#allrdeps) and
[`rbuildfiles`](#rbuildfiles) operators only return results from this scope.
`--infer_universe_scope` tells Bazel to infer a value for `--universe_scope`
from the query expression. This inferred value is the list of unique target patterns in the
query expression, but this might not be what you want. For example:
```posix-terminal theme={null}
bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"
```
The list of unique target patterns in this query expression is `["//my:target"]`, so
Bazel treats this the same as the invocation:
```posix-terminal theme={null}
bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"
```
But the result of that query with `--universe_scope` is only `//my:target`;
none of the reverse dependencies of `//my:target` are in the universe, by
construction! On the other hand, consider:
```posix-terminal theme={null}
bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"
```
This is a meaningful query invocation that is trying to compute the test targets in the
[`tests`](#tests) expansion of the targets under some directories that
transitively depend on targets whose definition uses a certain `.bzl` file. Here,
`--infer_universe_scope` is a convenience, especially in the case where the choice of
`--universe_scope` would otherwise require you to parse the query expression yourself.
So, for query expressions that use universe-scoped operators like
[`allrdeps`](#allrdeps) and
[`rbuildfiles`](#rbuildfiles) be sure to use
`--infer_universe_scope` only if its behavior is what you want.
Sky Query has some advantages and disadvantages compared to the default query. The main
disadvantage is that it cannot order its output according to graph order, and thus certain
[output formats](#output-formats) are forbidden. Its advantages are that it provides
two operators ([`allrdeps`](#allrdeps) and
[`rbuildfiles`](#rbuildfiles)) that are not available in the default query.
As well, Sky Query does its work by introspecting the
[Skyframe](/reference/skyframe) graph, rather than creating a new
graph, which is what the default implementation does. Thus, there are some circumstances in which
it is faster and uses less memory.
## Expressions: Syntax and semantics of the grammar
This is the grammar of the Bazel query language, expressed in EBNF notation:
```none theme={null}
expr ::= word
| let name = expr in expr
| (expr)
| expr intersect expr
| expr ^ expr
| expr union expr
| expr + expr
| expr except expr
| expr - expr
| set(word *)
| word '(' int | word | expr ... ')'
```
The following sections describe each of the productions of this grammar in order.
### Target patterns
```
expr ::= word
```
Syntactically, a *target pattern* is just a word. It's interpreted as an
(unordered) set of targets. The simplest target pattern is a label, which
identifies a single target (file or rule). For example, the target pattern
`//foo:bar` evaluates to a set containing one element, the target, the `bar`
rule.
Target patterns generalize labels to include wildcards over packages and
targets. For example, `foo/...:all` (or just `foo/...`) is a target pattern
that evaluates to a set containing all *rules* in every package recursively
beneath the `foo` directory; `bar/baz:all` is a target pattern that evaluates
to a set containing all the rules in the `bar/baz` package, but not its
subpackages.
Similarly, `foo/...:*` is a target pattern that evaluates to a set containing
all *targets* (rules *and* files) in every package recursively beneath the
`foo` directory; `bar/baz:*` evaluates to a set containing all the targets in
the `bar/baz` package, but not its subpackages.
Because the `:*` wildcard matches files as well as rules, it's often more
useful than `:all` for queries. Conversely, the `:all` wildcard (implicit in
target patterns like `foo/...`) is typically more useful for builds.
`bazel query` target patterns work the same as `bazel build` build targets do.
For more details, see [Target Patterns](/docs/user-manual#target-patterns), or
type `bazel help target-syntax`.
Target patterns may evaluate to a singleton set (in the case of a label), to a
set containing many elements (as in the case of `foo/...`, which has thousands
of elements) or to the empty set, if the target pattern matches no targets.
All nodes in the result of a target pattern expression are correctly ordered
relative to each other according to the dependency relation. So, the result of
`foo:*` is not just the set of targets in package `foo`, it is also the
*graph* over those targets. (No guarantees are made about the relative ordering
of the result nodes against other nodes.) For more details, see the
[graph order](#graph-order) section.
### Variables
```none theme={null}
expr ::= let name = expr{{ '' }}1{{ '' }} in expr{{ '' }}2{{ '' }}
| $name
```
The Bazel query language allows definitions of and references to
variables. The result of evaluation of a `let` expression is the same as
that of expr2, with all free occurrences
of variable name replaced by the value of
expr1.
For example, `let v = foo/... in allpaths($v, //common) intersect $v` is
equivalent to the `allpaths(foo/...,//common) intersect foo/...`.
An occurrence of a variable reference `name` other than in
an enclosing `let name = ...` expression is an
error. In other words, top-level query expressions cannot have free
variables.
In the above grammar productions, `name` is like *word*, but with the
additional constraint that it be a legal identifier in the C programming
language. References to the variable must be prepended with the "\$" character.
Each `let` expression defines only a single variable, but you can nest them.
Both [target patterns](#target-patterns) and variable references consist of
just a single token, a word, creating a syntactic ambiguity. However, there is
no semantic ambiguity, because the subset of words that are legal variable
names is disjoint from the subset of words that are legal target patterns.
Technically speaking, `let` expressions do not increase
the expressiveness of the query language: any query expressible in
the language can also be expressed without them. However, they
improve the conciseness of many queries, and may also lead to more
efficient query evaluation.
### Parenthesized expressions
```none theme={null}
expr ::= (expr)
```
Parentheses associate subexpressions to force an order of evaluation.
A parenthesized expression evaluates to the value of its argument.
### Algebraic set operations: intersection, union, set difference
```none theme={null}
expr ::= expr intersect expr
| expr ^ expr
| expr union expr
| expr + expr
| expr except expr
| expr - expr
```
These three operators compute the usual set operations over their arguments.
Each operator has two forms, a nominal form, such as `intersect`, and a
symbolic form, such as `^`. Both forms are equivalent; the symbolic forms are
quicker to type. (For clarity, the rest of this page uses the nominal forms.)
For example,
```
foo/... except foo/bar/...
```
evaluates to the set of targets that match `foo/...` but not `foo/bar/...`.
You can write the same query as:
```
foo/... - foo/bar/...
```
The `intersect` (`^`) and `union` (`+`) operations are commutative (symmetric);
`except` (`-`) is asymmetric. The parser treats all three operators as
left-associative and of equal precedence, so you might want parentheses. For
example, the first two of these expressions are equivalent, but the third is not:
```
x intersect y union z
(x intersect y) union z
x intersect (y union z)
```
Important: Use parentheses where there is any danger of ambiguity in reading a
query expression.
### Read targets from an external source: set
```none theme={null}
expr ::= set(word *)
```
The `set(abc ...)`
operator computes the union of a set of zero or more
[target patterns](#target-patterns), separated by whitespace (no commas).
In conjunction with the Bourne shell's `$(...)` feature, `set()` provides a
means of saving the results of one query in a regular text file, manipulating
that text file using other programs (such as standard UNIX shell tools), and then
introducing the result back into the query tool as a value for further
processing. For example:
```posix-terminal theme={null}
bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($( foo
bazel query "kind(cc_library, set($(word '(' int | word | expr ... ')'
```
The query language defines several functions. The name of the function
determines the number and type of arguments it requires. The following
functions are available:
* [`allpaths`](#somepath-allpaths)
* [`attr`](#attr)
* [`buildfiles`](#buildfiles)
* [`rbuildfiles`](#rbuildfiles)
* [`deps`](#deps)
* [`executables`](#executables)
* [`filter`](#filter)
* [`kind`](#kind)
* [`labels`](#labels)
* [`loadfiles`](#loadfiles)
* [`rdeps`](#rdeps)
* [`allrdeps`](#allrdeps)
* [`same_pkg_direct_rdeps`](#same_pkg_direct_rdeps)
* [`siblings`](#siblings)
* [`some`](#some)
* [`somepath`](#somepath-allpaths)
* [`tests`](#tests)
* [`visible`](#visible)
### Transitive closure of dependencies: deps
```none theme={null}
expr ::= deps(expr)
| deps(expr, depth)
```
The `deps(x)` operator evaluates to the graph formed
by the transitive closure of dependencies of its argument set
x. For example, the value of `deps(//foo)` is the
dependency graph rooted at the single node `foo`, including all its
dependencies. The value of `deps(foo/...)` is the dependency graphs whose roots
are all rules in every package beneath the `foo` directory. In this context,
'dependencies' means only rule and file targets, therefore the `BUILD` and
Starlark files needed to create these targets are not included here. For that
you should use the [`buildfiles`](#buildfiles) operator.
The resulting graph is ordered according to the dependency relation. For more
details, see the section on [graph order](#graph-order).
The `deps` operator accepts an optional second argument, which is an integer
literal specifying an upper bound on the depth of the search. So
`deps(foo:*, 0)` returns all targets in the `foo` package, while
`deps(foo:*, 1)` further includes the direct prerequisites of any target in the
`foo` package, and `deps(foo:*, 2)` further includes the nodes directly
reachable from the nodes in `deps(foo:*, 1)`, and so on. (These numbers
correspond to the ranks shown in the [`minrank`](#output-ranked) output format.)
If the depth parameter is omitted, the search is
unbounded: it computes the reflexive transitive closure of prerequisites.
### Transitive closure of reverse dependencies: rdeps
```none theme={null}
expr ::= rdeps(expr, expr)
| rdeps(expr, expr, depth)
```
The `rdeps(u, x)`
operator evaluates to the reverse dependencies of the argument set
x within the transitive closure of the universe set
u.
The resulting graph is ordered according to the dependency relation. See the
section on [graph order](#graph-order) for more details.
The `rdeps` operator accepts an optional third argument, which is an integer
literal specifying an upper bound on the depth of the search. The resulting
graph only includes nodes within a distance of the specified depth from any
node in the argument set. So `rdeps(//foo, //common, 1)` evaluates to all nodes
in the transitive closure of `//foo` that directly depend on `//common`. (These
numbers correspond to the ranks shown in the [`minrank`](#output-ranked) output
format.) If the depth parameter is omitted, the
search is unbounded.
### Transitive closure of all reverse dependencies: allrdeps
```
expr ::= allrdeps(expr)
| allrdeps(expr, depth)
```
Note: Only available with [Sky Query](#sky-query)
The `allrdeps` operator behaves just like the [`rdeps`](#rdeps)
operator, except that the "universe set" is whatever the `--universe_scope` flag
evaluated to, instead of being separately specified. Thus, if
`--universe_scope=//foo/...` was passed, then `allrdeps(//bar)` is
equivalent to `rdeps(//foo/..., //bar)`.
### Direct reverse dependencies in the same package: same\_pkg\_direct\_rdeps
```
expr ::= same_pkg_direct_rdeps(expr)
```
The `same_pkg_direct_rdeps(x)` operator evaluates to the full set of targets
that are in the same package as a target in the argument set, and which directly depend on it.
### Dealing with a target's package: siblings
```
expr ::= siblings(expr)
```
The `siblings(x)` operator evaluates to the full set of targets that are in
the same package as a target in the argument set.
### Arbitrary choice: some
```
expr ::= some(expr)
| some(expr, count{{ ' '}})
```
The `some(x, k)` operator
selects at most k targets arbitrarily from its
argument set x, and evaluates to a set containing
only those targets. Parameter k is optional; if
missing, the result will be a singleton set containing only one target
arbitrarily selected. If the size of argument set x is
smaller than k, the whole argument set
x will be returned.
For example, the expression `some(//foo:main union //bar:baz)` evaluates to a
singleton set containing either `//foo:main` or `//bar:baz`—though which
one is not defined. The expression `some(//foo:main union //bar:baz, 2)` or
`some(//foo:main union //bar:baz, 3)` returns both `//foo:main` and
`//bar:baz`.
If the argument is a singleton, then `some`
computes the identity function: `some(//foo:main)` is
equivalent to `//foo:main`.
It is an error if the specified argument set is empty, as in the
expression `some(//foo:main intersect //bar:baz)`.
### Path operators: somepath, allpaths
```
expr ::= somepath(expr, expr)
| allpaths(expr, expr)
```
The `somepath(S, E)` and
`allpaths(S, E)` operators compute
paths between two sets of targets. Both queries accept two
arguments, a set S of starting points and a set
E of ending points. `somepath` returns the
graph of nodes on *some* arbitrary path from a target in
S to a target in E; `allpaths`
returns the graph of nodes on *all* paths from any target in
S to any target in E.
The resulting graphs are ordered according to the dependency relation.
See the section on [graph order](#graph-order) for more details.

`somepath(S1 + S2, E)`, one possible result.

`somepath(S1 + S2, E)`, another possible result.
### Target kind filtering: kind
```
expr ::= kind(word, expr)
```
The `kind(pattern, input)`
operator applies a filter to a set of targets, and discards those targets
that are not of the expected kind. The pattern
parameter specifies what kind of target to match.
For example, the kinds for the four targets defined by the `BUILD` file
(for package `p`) shown below are illustrated in the table:
```starlark theme={null}
genrule(
name = "a",
srcs = ["a.in"],
outs = ["a.out"],
cmd = "...",
)
```
This `BUILD` file defines four targets:
* `//p:a` — a `genrule` rule
* `//p:a.in` — a source file
* `//p:a.out` — a generated file
* `//p:BUILD` — a source file
Thus, `kind("cc_.* rule", foo/...)` evaluates to the set
of all `cc_library`, `cc_binary`, etc,
rule targets beneath `foo`, and `kind("source file", deps(//foo))`
evaluates to the set of all source files in the transitive closure
of dependencies of the `//foo` target.
Quotation of the pattern argument is often required
because without it, many [regular expressions](#regex), such as `source
file` and `.*_test`, are not considered words by the parser.
When matching for `package group`, targets ending in
`:all` may not yield any results. Use `:all-targets` instead.
### Target name filtering: filter
```
expr ::= filter(word, expr)
```
The `filter(pattern, input)`
operator applies a filter to a set of targets, and discards targets whose
labels (in absolute form) do not match the pattern; it
evaluates to a subset of its input.
The first argument, pattern is a word containing a
[regular expression](#regex) over target names. A `filter` expression
evaluates to the set containing all targets x such that
x is a member of the set input and the
label (in absolute form, such as `//foo:bar`)
of x contains an (unanchored) match
for the regular expression pattern. Since all
target names start with `//`, it may be used as an alternative
to the `^` regular expression anchor.
This operator often provides a much faster and more robust alternative to the
`intersect` operator. For example, in order to see all
`bar` dependencies of the `//foo:foo` target, one could
evaluate
```
deps(//foo) intersect //bar/...
```
This statement, however, will require parsing of all `BUILD` files in the
`bar` tree, which will be slow and prone to errors in
irrelevant `BUILD` files. An alternative would be:
```
filter(//bar, deps(//foo))
```
which would first calculate the set of `//foo` dependencies and
then would filter only targets matching the provided pattern—in other
words, targets with names containing `//bar` as a substring.
Another common use of the `filter(pattern, expr)` operator is to filter specific files by their
name or extension. For example,
```
filter("\.cc$", deps(//foo))
```
will provide a list of all `.cc` files used to build `//foo`.
### Rule attribute filtering: attr
```
expr ::= attr(word, word, expr)
```
The
`attr(name, pattern, input)`
operator applies a filter to a set of targets, and discards targets that aren't
rules, rule targets that do not have attribute name
defined or rule targets where the attribute value does not match the provided
[regular expression](#regex) pattern; it evaluates
to a subset of its input.
The first argument, name is the name of the rule
attribute that should be matched against the provided
[regular expression](#regex) pattern. The second argument,
pattern is a regular expression over the attribute
values. An `attr` expression evaluates to the set containing all targets
x such that x is a
member of the set input, is a rule with the defined
attribute name and the attribute value contains an
(unanchored) match for the regular expression
pattern. If name is an
optional attribute and rule does not specify it explicitly then default
attribute value will be used for comparison. For example,
```
attr(linkshared, 0, deps(//foo))
```
will select all `//foo` dependencies that are allowed to have a
linkshared attribute (such as, `cc_binary` rule) and have it either
explicitly set to 0 or do not set it at all but default value is 0 (such as for
`cc_binary` rules).
List-type attributes (such as `srcs`, `data`, etc) are
converted to strings of the form `[value1, ..., valuen]`,
starting with a `[` bracket, ending with a `]` bracket
and using "`, `" (comma, space) to delimit multiple values.
Labels are converted to strings by using the absolute form of the
label. For example, an attribute `deps=[":foo",
"//otherpkg:bar", "wiz"]` would be converted to the
string `[//thispkg:foo, //otherpkg:bar, //thispkg:wiz]`.
Brackets are always present, so the empty list would use string value `[]`
for matching purposes. For example,
```
attr("srcs", "\[\]", deps(//foo))
```
will select all rules among `//foo` dependencies that have an
empty `srcs` attribute, while
```
attr("data", ".{3,}", deps(//foo))
```
will select all rules among `//foo` dependencies that specify at
least one value in the `data` attribute (every label is at least
3 characters long due to the `//` and `:`).
To select all rules among `//foo` dependencies with a particular `value` in a
list-type attribute, use
```
attr("tags", "[\[ ]value[,\]]", deps(//foo))
```
This works because the character before `value` will be `[` or a space and the
character after `value` will be a comma or `]`.
To select all rules among `//foo` dependencies with a particular `key` and
`value` in a dict-type attribute, use
```
attr("some_dict_attribute", "[\{ ]key=value[,\}]", deps(//foo))
```
This would select `//foo` if `//foo` is defined as
```
some_rule(
name = "foo",
some_dict_attribute = {
"key": "value",
},
)
```
This works because the character before `key=value` will be `{` or a space and
the character after `key=value` will be a comma or `}`.
### Rule visibility filtering: visible
```
expr ::= visible(expr, expr)
```
The `visible(predicate, input)` operator
applies a filter to a set of targets, and discards targets without the
required visibility.
The first argument, predicate, is a set of targets that all targets
in the output must be visible to. A visible expression
evaluates to the set containing all targets x such that x
is a member of the set input, and for all targets y in
predicatex is visible to y. For example:
```
visible(//foo, //bar:*)
```
will select all targets in the package `//bar` that `//foo`
can depend on without violating visibility restrictions.
### Evaluation of rule attributes of type label: labels
```
expr ::= labels(word, expr)
```
The `labels(attr_name, inputs)`
operator returns the set of targets specified in the
attribute attr\_name of type "label" or "list of label" in
some rule in set inputs.
For example, `labels(srcs, //foo)` returns the set of
targets appearing in the `srcs` attribute of
the `//foo` rule. If there are multiple rules
with `srcs` attributes in the inputs set, the
union of their `srcs` is returned.
### Expand and filter test\_suites: tests
```
expr ::= tests(expr)
```
The `tests(x)` operator returns the set of all test
rules in set x, expanding any `test_suite` rules into
the set of individual tests that they refer to, and applying filtering by
`tag` and `size`.
By default, query evaluation
ignores any non-test targets in all `test_suite` rules. This can be
changed to errors with the `--strict_test_suite` option.
For example, the query `kind(test, foo:*)` lists all
the `*_test` and `test_suite` rules
in the `foo` package. All the results are (by
definition) members of the `foo` package. In contrast,
the query `tests(foo:*)` will return all of the
individual tests that would be executed by `bazel test
foo:*`: this may include tests belonging to other packages,
that are referenced directly or indirectly
via `test_suite` rules.
### Executable targets: executables
```
expr ::= executables(expr)
```
The `executables(x)` operator returns the set of all
executable targets in set x. These targets
are of rule types that can be run with `bazel run`, such as `cc_binary`,
or any other rule that sets `executable = True` in its definition.
This doesn't include test targets, which can be added to the result with
the [`tests`](#tests) operator.
### Package definition files: buildfiles
```
expr ::= buildfiles(expr)
```
The `buildfiles(x)` operator returns the set
of files that define the packages of each target in
set x; in other words, for each package, its `BUILD` file,
plus any .bzl files it references via `load`. Note that this
also returns the `BUILD` files of the packages containing these
`load`ed files.
This operator is typically used when determining what files or
packages are required to build a specified target, often in conjunction with
the [`--output package`](#output-package) option, below). For example,
```posix-terminal theme={null}
bazel query 'buildfiles(deps(//foo))' --output package
```
returns the set of all packages on which `//foo` transitively depends.
Note: A naive attempt at the above query would omit
the `buildfiles` operator and use only `deps`,
but this yields an incorrect result: while the result contains the
majority of needed packages, those packages that contain only files
that are `load()`'ed will be missing.
Warning: Bazel pretends each `.bzl` file produced by
`buildfiles` has a corresponding target (for example, file `a/b.bzl` =>
target `//a:b.bzl`), but this isn't necessarily the case. Therefore,
`buildfiles` doesn't compose well with other query operators and its results can be
misleading when formatted in a structured way, such as
[`--output=xml`](#xml).
### Package definition files: rbuildfiles
```
expr ::= rbuildfiles(word, ...)
```
Note: Only available with [Sky Query](#sky-query).
The `rbuildfiles` operator takes a comma-separated list of path fragments and returns
the set of `BUILD` files that transitively depend on these path fragments. For instance, if
`//foo` is a package, then `rbuildfiles(foo/BUILD)` will return the
`//foo:BUILD` target. If the `foo/BUILD` file has
`load('//bar:file.bzl'...` in it, then `rbuildfiles(bar/file.bzl)` will
return the `//foo:BUILD` target, as well as the targets for any other `BUILD` files that
load `//bar:file.bzl`
The scope of the rbuildfiles operator is the universe specified by the
`--universe_scope` flag. Files that do not correspond directly to `BUILD` files and `.bzl`
files do not affect the results. For instance, source files (like `foo.cc`) are ignored,
even if they are explicitly mentioned in the `BUILD` file. Symlinks, however, are respected, so that
if `foo/BUILD` is a symlink to `bar/BUILD`, then
`rbuildfiles(bar/BUILD)` will include `//foo:BUILD` in its results.
The `rbuildfiles` operator is almost morally the inverse of the
[`buildfiles`](#buildfiles) operator. However, this moral inversion
holds more strongly in one direction: the outputs of `rbuildfiles` are just like the
inputs of `buildfiles`; the former will only contain `BUILD` file targets in packages,
and the latter may contain such targets. In the other direction, the correspondence is weaker. The
outputs of the `buildfiles` operator are targets corresponding to all packages and .`bzl`
files needed by a given input. However, the inputs of the `rbuildfiles` operator are
not those targets, but rather the path fragments that correspond to those targets.
### Package definition files: loadfiles
```
expr ::= loadfiles(expr)
```
The `loadfiles(x)` operator returns the set of
Starlark files that are needed to load the packages of each target in
set x. In other words, for each package, it returns the
.bzl files that are referenced from its `BUILD` files.
Warning: Bazel pretends each of these .bzl files has a corresponding target
(for example, file `a/b.bzl` => target `//a:b.bzl`), but this isn't
necessarily the case. Therefore, `loadfiles` doesn't compose well with other query
operators and its results can be misleading when formatted in a structured way, such as
[`--output=xml`](#xml).
## Output formats
`bazel query` generates a graph.
You specify the content, format, and ordering by which
`bazel query` presents this graph
by means of the `--output` command-line option.
When running with [Sky Query](#sky-query), only output formats that are compatible with
unordered output are allowed. Specifically, `graph`, `minrank`, and
`maxrank` output formats are forbidden.
Some of the output formats accept additional options. The name of
each output option is prefixed with the output format to which it
applies, so `--graph:factored` applies only
when `--output=graph` is being used; it has no effect if
an output format other than `graph` is used. Similarly,
`--xml:line_numbers` applies only when `--output=xml`
is being used.
### On the ordering of results
Although query expressions always follow the "[law of conservation of graph order](#graph-order)", *presenting* the results may be done
in either a dependency-ordered or unordered manner. This does **not**
influence the targets in the result set or how the query is computed. It only
affects how the results are printed to stdout. Moreover, nodes that are
equivalent in the dependency order may or may not be ordered alphabetically.
The `--order_output` flag can be used to control this behavior.
(The `--[no]order_results` flag has a subset of the functionality
of the `--order_output` flag and is deprecated.)
The default value of this flag is `auto`, which prints results in **lexicographical
order**. However, when `somepath(a,b)` is used, the results will be printed in
`deps` order instead.
When this flag is `no` and `--output` is one of
`build`, `label`, `label_kind`, `location`, `package`, `proto`, or
`xml`, the outputs will be printed in arbitrary order. **This is
generally the fastest option**. It is not supported though when
`--output` is one of `graph`, `minrank` or
`maxrank`: with these formats, Bazel always prints results
ordered by the dependency order or rank.
When this flag is `deps`, Bazel prints results in some topological order—that is,
dependents first and dependencies after. However, nodes that are unordered by the
dependency order (because there is no path from either one to the other) may be
printed in any order.
When this flag is `full`, Bazel prints nodes in a fully deterministic (total) order.
First, all nodes are sorted alphabetically. Then, each node in the list is used as the start of a
post-order depth-first search in which outgoing edges to unvisited nodes are traversed in
alphabetical order of the successor nodes. Finally, nodes are printed in the reverse of the order
in which they were visited.
Printing nodes in this order may be slower, so it should be used only when determinism is
important.
### Print the source form of targets as they would appear in BUILD
```
--output build
```
With this option, the representation of each target is as if it were
hand-written in the BUILD language. All variables and function calls
(such as glob, macros) are expanded, which is useful for seeing the effect
of Starlark macros. Additionally, each effective rule reports a
`generator_name` and/or `generator_function`) value,
giving the name of the macro that was evaluated to produce the effective rule.
Although the output uses the same syntax as `BUILD` files, it is not
guaranteed to produce a valid `BUILD` file.
### Print the label of each target
```
--output label
```
With this option, the set of names (or *labels*) of each target
in the resulting graph is printed, one label per line, in
topological order (unless `--noorder_results` is specified, see
[notes on the ordering of results](#result-order)).
(A topological ordering is one in which a graph
node appears earlier than all of its successors.) Of course there
are many possible topological orderings of a graph (*reverse
postorder* is just one); which one is chosen is not specified.
When printing the output of a `somepath` query, the order
in which the nodes are printed is the order of the path.
Caveat: in some corner cases, there may be two distinct targets with
the same label; for example, a `sh_binary` rule and its
sole (implicit) `srcs` file may both be called
`foo.sh`. If the result of a query contains both of
these targets, the output (in `label` format) will appear
to contain a duplicate. When using the `label_kind` (see
below) format, the distinction becomes clear: the two targets have
the same name, but one has kind `sh_binary rule` and the
other kind `source file`.
### Print the label and kind of each target
```
--output label_kind
```
Like `label`, this output format prints the labels of
each target in the resulting graph, in topological order, but it
additionally precedes the label by the [*kind*](#kind) of the target.
### Print targets in protocol buffer format
```
--output proto
```
Prints the query output as a
[`QueryResult`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffer.
### Print targets in length-delimited protocol buffer format
```
--output streamed_proto
```
Prints a
[length-delimited](https://protobuf.dev/programming-guides/encoding/#size-limit)
stream of
[`Target`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffers. This is useful to *(i)* get around
[size limitations](https://protobuf.dev/programming-guides/encoding/#size-limit)
of protocol buffers when there are too many targets to fit in a single
`QueryResult` or *(ii)* to start processing while Bazel is still outputting.
### Print targets in text proto format
```
--output textproto
```
Similar to `--output proto`, prints the
[`QueryResult`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffer but in
[text format](https://protobuf.dev/reference/protobuf/textformat-spec/).
### Print targets in ndjson format
```
--output streamed_jsonproto
```
Similar to `--output streamed_proto`, prints a stream of
[`Target`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffers but in [ndjson](https://github.com/ndjson/ndjson-spec) format.
### Print the label of each target, in rank order
```
--output minrank --output maxrank
```
Like `label`, the `minrank`
and `maxrank` output formats print the labels of each
target in the resulting graph, but instead of appearing in
topological order, they appear in rank order, preceded by their
rank number. These are unaffected by the result ordering
`--[no]order_results` flag (see [notes on the ordering of results](#result-order)).
There are two variants of this format: `minrank` ranks
each node by the length of the shortest path from a root node to it.
"Root" nodes (those which have no incoming edges) are of rank 0,
their successors are of rank 1, etc. (As always, edges point from a
target to its prerequisites: the targets it depends upon.)
`maxrank` ranks each node by the length of the longest
path from a root node to it. Again, "roots" have rank 0, all other
nodes have a rank which is one greater than the maximum rank of all
their predecessors.
All nodes in a cycle are considered of equal rank. (Most graphs are
acyclic, but cycles do occur
simply because `BUILD` files contain erroneous cycles.)
These output formats are useful for discovering how deep a graph is.
If used for the result of a `deps(x)`, `rdeps(x)`,
or `allpaths` query, then the rank number is equal to the
length of the shortest (with `minrank`) or longest
(with `maxrank`) path from `x` to a node in
that rank. `maxrank` can be used to determine the
longest sequence of build steps required to build a target.
Note: The ranked output of a `somepath` query is
basically meaningless because `somepath` doesn't
guarantee to return either a shortest or a longest path, and it may
include "transitive" edges from one path node to another that are
not direct edges in original graph.
For example, the graph on the left yields the outputs on the right
when `--output minrank` and `--output maxrank`
are specified, respectively.
### Print the location of each target
```
--output location
```
Like `label_kind`, this option prints out, for each
target in the result, the target's kind and label, but it is
prefixed by a string describing the location of that target, as a
filename and line number. The format resembles the output of
`grep`. Thus, tools that can parse the latter (such as Emacs
or vi) can also use the query output to step through a series of
matches, allowing the Bazel query tool to be used as a
dependency-graph-aware "grep for BUILD files".
The location information varies by target kind (see the [kind](#kind) operator). For rules, the
location of the rule's declaration within the `BUILD` file is printed.
For source files, the location of line 1 of the actual file is
printed. For a generated file, the location of the rule that
generates it is printed. (The query tool does not have sufficient
information to find the actual location of the generated file, and
in any case, it might not exist if a build has not yet been performed.)
### Print the set of packages
```
--output package
```
This option prints the name of all packages to which
some target in the result set belongs. The names are printed in
lexicographical order; duplicates are excluded. Formally, this
is a *projection* from the set of labels (package, target) onto
packages.
Packages in external repositories are formatted as
`@repo//foo/bar` while packages in the main repository are
formatted as `foo/bar`.
In conjunction with the `deps(...)` query, this output
option can be used to find the set of packages that must be checked
out in order to build a given set of targets.
### Display a graph of the result
```
--output graph
```
This option causes the query result to be printed as a directed
graph in the popular AT\&T GraphViz format. Typically the
result is saved to a file, such as `.png` or `.svg`.
(If the `dot` program is not installed on your workstation, you
can install it using the command `sudo apt-get install graphviz`.)
See the example section below for a sample invocation.
This output format is particularly useful for `allpaths`,
`deps`, or `rdeps` queries, where the result
includes a *set of paths* that cannot be easily visualized when
rendered in a linear form, such as with `--output label`.
By default, the graph is rendered in a *factored* form. That is,
topologically-equivalent nodes are merged together into a single
node with multiple labels. This makes the graph more compact
and readable, because typical result graphs contain highly
repetitive patterns. For example, a `java_library` rule
may depend on hundreds of Java source files all generated by the
same `genrule`; in the factored graph, all these files
are represented by a single node. This behavior may be disabled
with the `--nograph:factored` option.
#### `--graph:node_limit n`
The option specifies the maximum length of the label string for a
graph node in the output. Longer labels will be truncated; -1
disables truncation. Due to the factored form in which graphs are
usually printed, the node labels may be very long. GraphViz cannot
handle labels exceeding 1024 characters, which is the default value
of this option. This option has no effect unless
`--output=graph` is being used.
#### `--[no]graph:factored`
By default, graphs are displayed in factored form, as explained
[above](#output-graph).
When `--nograph:factored` is specified, graphs are
printed without factoring. This makes visualization using GraphViz
impractical, but the simpler format may ease processing by other
tools (such as grep). This option has no effect
unless `--output=graph` is being used.
### XML
```
--output xml
```
This option causes the resulting targets to be printed in an XML
form. The output starts with an XML header such as this
```
```
and then continues with an XML element for each target
in the result graph, in topological order (unless
[unordered results](#result-order) are requested),
and then finishes with a terminating
```
```
Simple entries are emitted for targets of `file` kind:
```
```
But for rules, the XML is structured and contains definitions of all
the attributes of the rule, including those whose value was not
explicitly specified in the rule's `BUILD` file.
Additionally, the result includes `rule-input` and
`rule-output` elements so that the topology of the
dependency graph can be reconstructed without having to know that,
for example, the elements of the `srcs` attribute are
forward dependencies (prerequisites) and the contents of the
`outs` attribute are backward dependencies (consumers).
`rule-input` elements for [implicit dependencies](#implicit_deps) are suppressed if
`--noimplicit_deps` is specified.
```
...
...
...
...
```
Every XML element for a target contains a `name`
attribute, whose value is the target's label, and
a `location` attribute, whose value is the target's
location as printed by the [`--output location`](#print-target-location).
#### `--[no]xml:line_numbers`
By default, the locations displayed in the XML output contain line numbers.
When `--noxml:line_numbers` is specified, line numbers are not printed.
#### `--[no]xml:default_values`
By default, XML output does not include rule attribute whose value
is the default value for that kind of attribute (for example, if it
were not specified in the `BUILD` file, or the default value was
provided explicitly). This option causes such attribute values to
be included in the XML output.
### Regular expressions
Regular expressions in the query language use the Java regex library, so you can use the
full syntax for
[`java.util.regex.Pattern`](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html).
### Querying with external repositories
If the build depends on rules from [external repositories](/external/overview)
then query results will include these dependencies. For
example, if `//foo:bar` depends on `@other-repo//baz:lib`, then
`bazel query 'deps(//foo:bar)'` will list `@other-repo//baz:lib` as a
dependency.
# Query quickstart
Source: https://bazel.build/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](/query/language) and [Bazel cquery reference](/query/cquery) 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](https://bazel.build/install), if you haven’t already. This tutorial uses Git for source control, so for best results, install [Git](https://github.com/git-guides/install-git) as well.
To visualize dependency graphs, the tool called Graphviz is used, which you can [download](https://graphviz.org/download/) in order to follow along.
### Get the sample project
Next, retrieve the sample app from [Bazel's Examples repository](https://github.com/bazelbuild/examples) by running the following in your command-line tool of choice:
```posix-terminal theme={null}
git clone https://github.com/bazelbuild/examples.git
```
The 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](https://bazel.build/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:
```posix-terminal theme={null}
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.bazel
```
Throughout 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 command
`bazel build` and use `:` to signal that the target is named `runner`. See
[target names](https://bazel.build/concepts/labels#target-names) to learn how to
reference targets.
To build this project, paste this command into a terminal:
```posix-terminal theme={null}
bazel build :runner
```
Your output should look something like this if the build is successful.
```bash theme={null}
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 actions
```
After it has built successfully, run the application by pasting this command:
```posix-terminal theme={null}
bazel-bin/runner
```
```bash theme={null}
--------------------- 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:
```posix-terminal theme={null}
bazel query //src/main/java/com/example/dishes/...
```
```posix-terminal theme={null}
bazel query //src/main/java/com/example/ingredients/...
```
If you query for the targets of the ingredients package, the output should look like:
```bash theme={null}
//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
```
## Finding 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:
```posix-terminal theme={null}
bazel query --noimplicit_deps "deps(target)"
```
```posix-terminal theme={null}
bazel query --noimplicit_deps "deps(:runner)"
```
```bash theme={null}
//: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:chef
```
Note: 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](https://graphviz.org/download/) to follow along.
The section describes how you can visualize the dependency paths for a specific query. [Graphviz](https://graphviz.org/) 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](https://bazel.build/query/language#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:
```posix-terminal theme={null}
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph.in
```
This creates a file called `graph.in`, which is a text representation of the build graph. Graphviz uses `dot `– a tool that processes text into a visualization — to create a png:
```posix-terminal theme={null}
dot -Tpng < graph.in > graph.png
```
If 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](https://bazel.build/concepts/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:
```posix-terminal theme={null}
bazel query "rdeps(universe_scope, target)"
```
```
ex) bazel query "rdeps(//... , //src/main/java/com/example/ingredients:cheese)"
```
```bash theme={null}
//: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:chef
```
The 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.
> **Answer**
>
> Mac and Cheese
## 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`**
```java theme={null}
package com.example.ingredients;
public class Strawberry {
}
```
**`src/main/java/com/example/ingredients/Banana.java`**
```java theme={null}
package com.example.ingredients;
public class Banana {
}
```
Next, add `Smoothie.java` to the appropriate directory: `dishes`.
**`src/main/java/com/example/dishes/Smoothie.java`**
```java theme={null}
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](https://bazel.build/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`.
```posix-terminal theme={null}
bazel query --noimplicit_deps 'deps(:runner)' --output graph > graph2.in
```
```posix-terminal theme={null}
dot -Tpng < graph2.in > graph2.png
```
[](/query/images/query_graph2.png)
Looking 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:
```posix-terminal theme={null}
bazel query "somepath(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"
```
```bash theme={null}
//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:cheese
```
The output follows the first path of Cafe → Chef → MacAndCheese → Cheese. If instead you use `allpaths()`, you get:
```posix-terminal theme={null}
bazel query "allpaths(//src/main/java/com/example/restaurant/..., //src/main/java/com/example/ingredients:cheese)"
```
```bash theme={null}
//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:chef
```

The 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:
```posix-terminal theme={null}
bazel build //src/main/java/com/example/reviews:review
```
```posix-terminal theme={null}
bazel-bin/src/main/java/com/example/reviews/review
```
Going off Bazel queries only, try to find out who wrote the review, and what dish they were describing.
> **Hint**
>
> Check the tags and dependencies for useful information.
> **Answer**
>
> This review was describing the Pizza and Amir was the reviewer. If you look at what dependencies that this rule had using
> `bazel query --noimplicit_deps 'deps(//src/main/java/com/example/reviews:review)'`
> The result of this command reveals that Amir is the reviewer!
> Next, since you know the reviewer is Amir, you can use the query function to seek which tag Amir has in the `BUILD` file to see what dish is there.
> The command `bazel query 'attr(tags, "pizza", //src/main/java/com/example/customers/...)'` output that Amir is the only customer that ordered a pizza and is the reviewer which gives us the answer.
## 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](https://bazel.build/query/language). Want more advanced queries? The [Query guide](https://bazel.build/query/guide) showcases an in-depth list of more use cases than are covered in this guide.
# Common definitions
Source: https://bazel.build/reference/be/common-definitions
This section defines various terms and concepts that are common to
many functions or build rules.
## Contents
* [Bourne shell tokenization](#sh-tokenization)
* [Label Expansion](#label-expansion)
* [Typical attributes defined by most build rules](#typical-attributes)
* [Attributes common to all build rules](#common-attributes)
* [Attributes common to all test rules (\*\_test)](#common-attributes-tests)
* [Attributes common to all binary rules (\*\_binary)](#common-attributes-binaries)
* [Configurable attributes](#configurable-attributes)
* [Implicit output targets](#implicit-outputs)
## Bourne shell tokenization
Certain string attributes of some rules are split into multiple
words according to the tokenization rules of the Bourne shell:
unquoted spaces delimit separate words, and single- and
double-quotes characters and backslashes are used to prevent
tokenization.
Those attributes that are subject to this tokenization are
explicitly indicated as such in their definitions in this document.
Attributes subject to "Make" variable expansion and Bourne shell
tokenization are typically used for passing arbitrary options to
compilers and other tools. Examples of such attributes are
`cc_library.copts` and `java_library.javacopts`.
Together these substitutions allow a
single string variable to expand into a configuration-specific list
of option words.
## Label expansion
Some string attributes of a very few rules are subject to label
expansion: if those strings contain a valid label as a
substring, such as `//mypkg:target`, and that label is a
declared prerequisite of the current rule, it is expanded into the
pathname of the file represented by the
[target](https://bazel.build/reference/glossary#target)
`//mypkg:target`.
Example attributes include `genrule.cmd` and
`cc_binary.linkopts`. The details may vary significantly in
each case, over such issues as: whether relative labels are
expanded; how labels that expand to multiple files are
treated, etc. Consult the rule attribute documentation for
specifics.
## Typical attributes defined by most build rules
This section describes attributes that are defined by many build rules,
but not all.
| Attribute | Description |
| - | - |
| `data` | List of [labels](/concepts/labels); default is `[]` Files needed by this rule at runtime. May list file or rule targets. Generally allows any target. The `runfiles` of targets in the `data` attribute appear in the `*.runfiles` area of any executable which is output by or has a runtime dependency on this target. This may include data files or binaries used when this target's [`srcs`](#typical.srcs) are executed. Typically, this includes the targets' default outputs and their transitive runfiles, but this depends on the implementation of the rules for those targets; most rules include their default outputs in their `runfiles`. See the [data dependencies](/concepts/dependencies#data-dependencies) section for more information about how to depend on and use data files. New rules should define a `data` attribute if they process inputs which might use other inputs at runtime. Rules' implementation functions must also [populate the target's runfiles](https://bazel.build/rules/rules#runfiles) from the outputs and runfiles of any `data` attribute, as well as runfiles from any dependency attribute which provides either source code or runtime dependencies. |
| `deps` | List of [labels](/concepts/labels); default is `[]` Dependencies for this target. Generally should only list rule targets. (Though some rules permit files to be listed directly in `deps`, this should be avoided when possible.) Language-specific rules generally limit the listed targets to those with specific [providers](https://bazel.build/extending/rules#providers). The precise semantics of what it means for a target to depend on another using `deps` are specific to the kind of rule, and the rule-specific documentation goes into more detail. For rules which process source code, `deps` generally specifies code dependencies used by the code in [`srcs`](#typical.srcs). Most often, a `deps` dependency is used to allow one module to use symbols defined in another module written in the same programming language and separately compiled. Cross-language dependencies are also permitted in many cases: For example, a `java_library` target may depend on C++ code in a `cc_library` target, by listing the latter in the `deps` attribute. See the definition of [dependencies](/concepts/build-ref#deps) for more information. |
| `licenses` | List of strings; [nonconfigurable](#configurable-attributes); default is `["none"]` A list of license-type strings to be used for this particular target. This is part of a deprecated licensing API that Bazel no longer uses. Don't use this. |
| `srcs` | List of [labels](/concepts/labels); default is `[]` Files processed or included by this rule. Generally lists files directly, but may list rule targets (like `filegroup` or `genrule`) to include their default outputs. Language-specific rules often require that the listed files have particular file extensions. |
## Attributes common to all build rules
This section describes attributes that are implicitly added to all build
rules.
| Attribute | Description |
| - | - |
| `aspect_hints` | List of [labels](/concepts/labels); default is `[]` A list of arbitrary labels which is exposed to [aspects](/extending/aspects) (in particular - aspects invoked by this rule's reverse dependencies), but isn't exposed to this rule's own implementation. Consult documentation for language-specific rule sets for details about what effect a particular aspect hint would have. You could think of an aspect hint as a richer alternative to a [tag](#common.tags): while a tag conveys only a boolean state (the tag is either present or absent in the `tags` list), an aspect hint can convey arbitrary structured information in its [providers](/extending/rules#providers). In practice, aspect hints are used for interoperability between different language-specific rule sets. For example, imagine you have a `mylang_binary` target which needs to depend on an `otherlang_library` target. The MyLang-specific logic needs some additional information about the OtherLang target in order to use it, but `otherlang_library` doesn't provide this information because it knows nothing about MyLang. One solution might be for the MyLang rule set to define a `mylang_hint` rule which can be used to encode that additional information; the user can add the hint to their `otherlang_library`'s `aspect_hints`, and `mylang_binary` can use an aspect to collect the additional information from a MyLang-specific provider in the `mylang_hint`. For a concrete example, see [`swift_interop_hint`](https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_interop_hint) and [`swift_overlay`](https://github.com/bazelbuild/rules_swift/blob/master/doc/rules.md#swift_overlay) in `rules_swift`. Best practices:
Targets listed in `aspect_hints` should be lightweight and minimal.
Language-specific logic should consider only aspect hints having providers relevant to that language, and should ignore any other aspect hints.
|
| `compatible_with` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is `[]` The list of environments this target can be built for, in addition to default-supported environments. This is part of Bazel's constraint system, which lets users declare which targets can and cannot depend on each other. For example, externally deployable binaries shouldn't depend on libraries with company-secret code. See [ConstraintSemantics](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/analysis/constraints/ConstraintSemantics.java#L46) for details. |
| `deprecation` | String; [nonconfigurable](#configurable-attributes); default is `None` An explanatory warning message associated with this target. Typically this is used to notify users that a target has become obsolete, or has become superseded by another rule, is private to a package, or is perhaps considered harmful for some reason. It is a good idea to include some reference (like a webpage, a bug number or example migration CLs) so that one can easily find out what changes are required to avoid the message. If there is a new target that can be used as a drop in replacement, it is a good idea to just migrate all users of the old target. This attribute has no effect on the way things are built, but it may affect a build tool's diagnostic output. The build tool issues a warning when a rule with a `deprecation` attribute is depended upon by a target in another package. Intra-package dependencies are exempt from this warning, so that, for example, building the tests of a deprecated rule does not encounter a warning. If a deprecated target depends on another deprecated target, no warning message is issued. Once people have stopped using it, the target can be removed. |
| `exec_compatible_with` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is `[]` A list of `constraint_values` that must be present in the execution platform of this target's default exec group. This is in addition to any constraints already set by the rule type. Constraints are used to restrict the list of available execution platforms. For more details, see the description of [toolchain resolution](/docs/toolchains#toolchain-resolution). and [exec groups](/extending/exec-groups) |
| `exec_group_compatible_with` | Dictionary of strings to lists of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is `{}` A dictionary of exec group names to lists of `constraint_values` that must be present in the execution platform for the given exec group. This is in addition to any constraints already set on the exec group's definition. Constraints are used to restrict the list of available execution platforms. For more details, see the description of [toolchain resolution](/docs/toolchains#toolchain-resolution). and [exec groups](/extending/exec-groups) |
| `exec_properties` | Dictionary of strings; default is `{}` A dictionary of strings that will be added to the `exec_properties` of a platform selected for this target. See `exec_properties` of the [platform](platforms-and-toolchains#platform) rule. If a key is present in both the platform and target-level properties, the value will be taken from the target. Keys can be prefixed with the name of an execution group followed by a `.` to apply them only to that particular exec group. |
| `features` | List of *feature* strings; default is `[]` A feature is string tag that can be enabled or disabled on a target. The meaning of a feature depends on the rule itself. This `features` attribute is combined with the [package](/reference/be/functions#package) level `features` attribute. For example, if the features \["a", "b"] are enabled on the package level, and a target's `features` attribute contains \["-a", "c"], the features enabled for the rule will be "b" and "c". [See example](https://github.com/bazelbuild/examples/blob/main/rules/features/BUILD). |
| `package_metadata` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is the package's `default_package_metadata` A list of labels that are associated metadata about this target. Typically, the labels are simple rules that return a provider of constant values. Rules and aspects may use these labels to perform some additional analysis on the build graph. The canonical use case is that of [rules\_license](https://github.com/bazelbuild/rules_license). For that use case, `package_metadata` and `default_package_metadata` is used to attach information about a package's licence or version to targets. An aspect applied to a top-level binary can be used to gather those and produce compliance reports. |
| `restricted_to` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is `[]` The list of environments this target can be built for, *instead* of default-supported environments. This is part of Bazel's constraint system. See [`compatible_with`](#common.compatible_with) for details. |
| `tags` | List of strings; [nonconfigurable](#configurable-attributes); default is `[]` *Tags* can be used on any rule. *Tags* on test and `test_suite` rules are useful for categorizing the tests. *Tags* on non-test targets are used to control sandboxed execution of `genrule`s and [Starlark](/rules/concepts) actions, and for parsing by humans and/or external tools. Bazel modifies the behavior of its sandboxing code if it finds the following keywords in the `tags` attribute of any test or `genrule` target, or the keys of `execution_requirements` for any Starlark action.
`no-sandbox` keyword results in the action or test never being sandboxed; it can still be cached or run remotely - use `no-cache` or `no-remote` to prevent either or both of those.
`no-cache` keyword results in the action or test never being cached (locally or remotely). Note: for the purposes of this tag, the disk cache is considered a local cache, whereas the HTTP and gRPC caches are considered remote. Other caches, such as Skyframe or the persistent action cache, are not affected.
`no-remote-cache` keyword results in the action or test never being cached remotely (but it may be cached locally; it may also be executed remotely). Note: for the purposes of this tag, the disk cache is considered a local cache, whereas the HTTP and gRPC caches are considered remote. Other caches, such as Skyframe or the persistent action cache, are not affected. If a combination of local disk cache and remote cache are used (combined cache), it's treated as a remote cache and disabled entirely unless `--incompatible_remote_results_ignore_disk` is set in which case the local components will be used.
`no-remote-exec` keyword results in the action or test never being executed remotely (but it may be cached remotely).
`no-remote` keyword prevents the action or test from being executed remotely or cached remotely. This is equivalent to using both `no-remote-cache` and `no-remote-exec`.
`no-remote-cache-upload` keyword disables upload part of remote caching of a spawn. it does not disable remote execution.
`local` keyword precludes the action or test from being remotely cached, remotely executed, or run inside the sandbox. For genrules and tests, marking the rule with the `local = True` attribute has the same effect.
`requires-network` keyword allows access to the external network from inside the sandbox. This tag only has an effect if sandboxing is enabled.
`block-network` keyword blocks access to the external network from inside the sandbox. In this case, only communication with localhost is allowed. This tag only has an effect if sandboxing is enabled.
`requires-fakeroot` runs the test or action as uid and gid 0 (i.e., the root user). This is only supported on Linux. This tag takes precedence over the `--sandbox_fake_username` command-line option.
*Tags* on tests are generally used to annotate a test's role in your debug and release process. Typically, tags are most useful for C++ and Python tests, which lack any runtime annotation ability. The use of tags and size elements gives flexibility in assembling suites of tests based around codebase check-in policy. Bazel modifies test running behavior if it finds the following keywords in the `tags` attribute of the test rule:
`exclusive` will force the test to be run in the "exclusive" mode, ensuring that no other tests are running at the same time. Such tests will be executed in serial fashion after all build activity and non-exclusive tests have been completed. Remote execution is disabled for such tests because Bazel doesn't have control over what's running on a remote machine.
`exclusive-if-local` will force the test to be run in the "exclusive" mode if it is executed locally, but will run the test in parallel if it's executed remotely.
`manual` keyword will exclude the target from expansion of target pattern wildcards (`...`, `:*`, `:all`, etc.) and `test_suite` rules which do not list the test explicitly when computing the set of top-level targets to build/run for the `build`, `test`, and `coverage` commands. It does not affect target wildcard or test suite expansion in other contexts, including the `query` command. Note that `manual` does not imply that a target should not be built/run automatically by continuous build/test systems. For example, it may be desirable to exclude a target from `bazel test ...` because it requires specific Bazel flags, but still have it included in properly-configured presubmit or continuous test runs.
`external` keyword will force test to be unconditionally executed (regardless of `--cache_test_results` value).
See [Tag Conventions](/reference/test-encyclopedia#tag-conventions) in the Test Encyclopedia for more conventions on tags attached to test targets. |
| `target_compatible_with` | List of [labels](/concepts/labels); default is `[]` A list of `constraint_value`s that must be present in the target platform and `config_setting`s that must match the target configuration for this target to be considered *compatible*. This is in addition to any constraints already set by the rule type. If the target platform does not satisfy all listed constraints, or the target configuration does not match all listed config\_settings, then the target is considered *incompatible*. Incompatible targets are skipped for building and testing when the target pattern is expanded (e.g. `//...`, `:all`). When explicitly specified on the command line, incompatible targets cause Bazel to print an error and cause a build or test failure. Targets that transitively depend on incompatible targets are themselves considered incompatible. They are also skipped for building and testing. An empty list (which is the default) signifies that the target is compatible with all platforms. All rules support this attribute. For some rules this attribute has no effect. For example, specifying `target_compatible_with` for a `cc_toolchain` is not useful. See the [Platforms](/docs/platforms#skipping-incompatible-targets) page for more information about incompatible target skipping. |
| `testonly` | Boolean; [nonconfigurable](#configurable-attributes); default is `False` except for test and test suite targets If `True`, only testonly targets (such as tests) can depend on this target. Equivalently, a rule that is not `testonly` is not allowed to depend on any rule that is `testonly`. Tests (`*_test` rules) and test suites ([test\_suite](/reference/be/general#test_suite) rules) are `testonly` by default. This attribute is intended to mean that the target should not be contained in binaries that are released to production. Because testonly is enforced at build time, not run time, and propagates virally through the dependency tree, it should be applied judiciously. For example, stubs and fakes that are useful for unit tests may also be useful for integration tests involving the same binaries that will be released to production, and therefore should probably not be marked testonly. Conversely, rules that are dangerous to even link in, perhaps because they unconditionally override normal behavior, should definitely be marked testonly. |
| `toolchains` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default is `[]` The set of targets whose [Make variables](/reference/be/make-variables) this target is allowed to access. These targets are either instances of rules that provide `TemplateVariableInfo` or special targets for toolchain types built into Bazel. These include:
`@bazel_tools//tools/cpp:toolchain_type`
`@rules_java//toolchains:current_java_runtime`
Note that this is distinct from the concept of [toolchain resolution](/docs/toolchains#toolchain-resolution) that is used by rule implementations for platform-dependent configuration. You cannot use this attribute to determine which specific `cc_toolchain` or `java_toolchain` a target will use. |
| `visibility` | List of [labels](/concepts/labels); [nonconfigurable](#configurable-attributes); default varies The `visibility` attribute controls whether the target can be depended on by targets in other locations. See the documentation for [visibility](/concepts/visibility). For targets declared directly in a BUILD file or in legacy macros called from a BUILD file, the default value is the package's `default_visibility` if specified, or else `["//visibility:private"]`. For targets declared in one or more symbolic macros, the default value is always just `["//visibility:private"]` (which makes it useable only within the package containing the macro's code). |
## Attributes common to all test rules (\*\_test)
This section describes attributes that are common to all test rules.
| Attribute | Description |
| - | - |
| `args` | List of strings; subject to [\$(location)](/reference/be/make-variables#predefined_label_variables) and ["Make variable"](/reference/be/make-variables) substitution, and [Bourne shell tokenization](#sh-tokenization); default is `[]` Command line arguments that Bazel passes to the target when it is executed with `bazel test`. These arguments are passed before any `--test_arg` values specified on the `bazel test` command line. |
| `env` | Dictionary of strings; values are subject to [\$(location)](/reference/be/make-variables#predefined_label_variables) and ["Make variable"](/reference/be/make-variables) substitution; default is `{}` Specifies additional environment variables to set when the test is executed by `bazel test`. This attribute only applies to native rules, like `cc_test`, `py_test`, and `sh_test`. It does not apply to Starlark-defined test rules. For your own Starlark rules, you can add an "env" attribute and use it to populate a [RunEnvironmentInfo](/rules/lib/providers/RunEnvironmentInfo) Provider. [TestEnvironment](/rules/lib/toplevel/testing#TestEnvironment) Provider. |
| `env_inherit` | List of strings; default is `[]` Specifies additional environment variables to inherit from the external environment when the test is executed by `bazel test`. This attribute only applies to native rules, like `cc_test`, `py_test`, and `sh_test`. It does not apply to Starlark-defined test rules. |
| `size` | String `"enormous"`, `"large"`, `"medium"`, or `"small"`; [nonconfigurable](#configurable-attributes); default is `"medium"` Specifies a test target's "heaviness": how much time/resources it needs to run. Unit tests are considered "small", integration tests "medium", and end-to-end tests "large" or "enormous". Bazel uses the size to determine a default timeout, which can be overridden using the `timeout` attribute. The timeout is for all tests in the BUILD target, not for each individual test. When the test is run locally, the `size` is additionally used for scheduling purposes: Bazel tries to respect `--local_{ram,cpu}_resources` and not overwhelm the local machine by running lots of heavy tests at the same time. Test sizes correspond to the following default timeouts and assumed peak local resource usages:
Size
RAM (in MB)
CPU (in CPU cores)
Default timeout
small
20
1
short (1 minute)
medium
100
1
moderate (5 minutes)
large
300
1
long (15 minutes)
enormous
800
1
eternal (60 minutes)
The environment variable `TEST_SIZE` will be set to the value of this attribute when spawning the test. |
| `timeout` | String `"short"`, `"moderate"`, `"long"`, or `"eternal"`; [nonconfigurable](#configurable-attributes); default is derived from the test's `size` attribute How long the test is expected to run before returning. While a test's size attribute controls resource estimation, a test's timeout may be set independently. If not explicitly specified, the timeout is based on the [test's size](#test.size). The test timeout can be overridden with the `--test_timeout` flag, e.g. for running under certain conditions which are known to be slow. Test timeout values correspond to the following time periods:
Timeout Value
Time Period
short
1 minute
moderate
5 minutes
long
15 minutes
eternal
60 minutes
For times other than the above, the test timeout can be overridden with the `--test_timeout` bazel flag, e.g. for manually running under conditions which are known to be slow. The `--test_timeout` values are in seconds. For example `--test_timeout=120` will set the test timeout to two minutes. The environment variable `TEST_TIMEOUT` will be set to the test timeout (in seconds) when spawning the test. |
| `flaky` | Boolean; [nonconfigurable](#configurable-attributes); default is `False` Marks test as flaky. If set, executes the test up to three times, marking it as failed only if it fails each time. By default, this attribute is set to False and the test is executed only once. Note, that use of this attribute is generally discouraged - tests should pass reliably when their assertions are upheld. |
| `shard_count` | Non-negative integer less than or equal to 50; default is `-1` Specifies the number of parallel shards to use to run the test. If set, this value will override any heuristics used to determine the number of parallel shards with which to run the test. Note that for some test rules, this parameter may be required to enable sharding in the first place. Also see `--test_sharding_strategy`. If test sharding is enabled, the environment variable `TEST_TOTAL_SHARDS` will be set to this value when spawning the test. Sharding requires the test runner to support the test sharding protocol. If it does not, then it will most likely run every test in every shard, which is not what you want. See [Test Sharding](/reference/test-encyclopedia#test-sharding) in the Test Encyclopedia for details on sharding. |
| `local` | Boolean; [nonconfigurable](#configurable-attributes); default is `False` Forces the test to be run locally, without sandboxing. Setting this to True is equivalent to providing "local" as a tag (`tags=["local"]`). |
## Attributes common to all binary rules (\*\_binary)
This section describes attributes that are common to all binary rules.
| Attribute | Description |
| - | - |
| `args` | List of strings; subject to [\$(location)](/reference/be/make-variables#predefined_label_variables) and ["Make variable"](/reference/be/make-variables) substitution, and [Bourne shell tokenization](#sh-tokenization); [nonconfigurable](#configurable-attributes); default is `[]` Command line arguments that Bazel will pass to the target when it is executed either by the `run` command or as a test. These arguments are passed before the ones that are specified on the `bazel run` or `bazel test` command line. *NOTE: The arguments are not passed when you run the target outside of Bazel (for example, by manually executing the binary in `bazel-bin/`).* |
| `env` | Dictionary of strings; values are subject to [\$(location)](/reference/be/make-variables#predefined_label_variables) and ["Make variable"](/reference/be/make-variables) substitution; default is `{}` Specifies additional environment variables to set when the target is executed by `bazel run`. This attribute only applies to native rules, like `cc_binary`, `py_binary`, and `sh_binary`. It does not apply to Starlark-defined executable rules. For your own Starlark rules, you can add an "env" attribute and use it to populate a [RunEnvironmentInfo](/rules/lib/providers/RunEnvironmentInfo) Provider. *NOTE: The environment variables are not set when you run the target outside of Bazel (for example, by manually executing the binary in `bazel-bin/`).* |
| `output_licenses` | List of strings; default is `[]` The licenses of the output files that this binary generates. This is part of a deprecated licensing API that Bazel no longer uses. Don't use this. |
## Configurable attributes
Most attributes are "configurable", meaning that their values may change when
the target is built in different ways. Specifically, configurable attributes
may vary based on the flags passed to the Bazel command line, or what
downstream dependency is requesting the target. This can be used, for
instance, to customize the target for multiple platforms or compilation modes.
The following example declares different sources for different target
architectures. Running `bazel build :multiplatform_lib --cpu x86`
will build the target using `x86_impl.cc`, while substituting
`--cpu arm` will instead cause it to use `arm_impl.cc`.
```
cc_library(
name = "multiplatform_lib",
srcs = select({
":x86_mode": ["x86_impl.cc"],
":arm_mode": ["arm_impl.cc"]
})
)
config_setting(
name = "x86_mode",
values = { "cpu": "x86" }
)
config_setting(
name = "arm_mode",
values = { "cpu": "arm" }
)
```
The [`select()`](/reference/be/functions#select) function
chooses among different alternative values for a configurable attribute based
on which [`config_setting`](/reference/be/general#config_setting)
or [`constraint_value`](/reference/be/platforms-and-toolchains#constraint_value)
criteria the target's configuration satisfies.
Bazel evaluates configurable attributes after processing macros and before
processing rules (technically, between the
[loading and analysis phases](https://bazel.build/rules/concepts#evaluation-model)).
Any processing before `select()` evaluation doesn't know which
branch the `select()` chooses. Macros, for example, can't change
their behavior based on the chosen branch, and `bazel query` can
only make conservative guesses about a target's configurable dependencies. See
[this FAQ](https://bazel.build/docs/configurable-attributes#faq)
for more on using `select()` with rules and macros.
Attributes marked `nonconfigurable` in their documentation cannot
use this feature. Usually an attribute is nonconfigurable because Bazel
internally needs to know its value before it can determine how to resolve a
`select()`.
See [Configurable Build Attributes](https://bazel.build/docs/configurable-attributes) for a detailed overview.
## Implicit output targets
*Implicit outputs in C++ are deprecated. Please refrain from using it
in other languages where possible. We don't have a deprecation path yet
but they will eventually be deprecated too.*
When you define a build rule in a BUILD file, you are explicitly
declaring a new, named rule target in a package. Many build rule
functions also *implicitly* entail one or more output file
targets, whose contents and meaning are rule-specific.
For example, when you explicitly declare a
`java_binary(name='foo', ...)` rule, you are also
*implicitly* declaring an output file
target `foo_deploy.jar` as a member of the same package.
(This particular target is a self-contained Java archive suitable
for deployment.)
Implicit output targets are first-class members of the global
target graph. Just like other targets, they are built on demand,
either when specified in the top-level built command, or when they
are necessary prerequisites for other build targets. They can be
referenced as dependencies in BUILD files, and can be observed in
the output of analysis tools such as `bazel query`.
For each kind of build rule, the rule's documentation contains a
special section detailing the names and contents of any implicit
outputs entailed by a declaration of that kind of rule.
An important but somewhat subtle distinction between the
two namespaces used by the build system:
[labels](/concepts/labels) identify *targets*,
which may be rules or files, and file targets may be divided into
either source (or input) file targets and derived (or output) file
targets. These are the things you can mention in BUILD files,
build from the command-line, or examine using `bazel query`;
this is the *target namespace*. Each file target corresponds
to one actual file on disk (the "file system namespace"); each rule
target may correspond to zero, one or more actual files on disk.
There may be files on disk that have no corresponding target; for
example, `.o` object files produced during C++ compilation
cannot be referenced from within BUILD files or from the command line.
In this way, the build tool may hide certain implementation details of
how it does its job. This is explained more fully in
the [BUILD Concept Reference](/concepts/build-ref).
# Functions
Source: https://bazel.build/reference/be/functions
## Contents
* [package](#package)
* [package\_group](#package_group)
* [exports\_files](#exports_files)
* [glob](#glob)
* [select](#select)
* [subpackages](#subpackages)
## package
```
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
```
This function declares metadata that applies to every rule in the
package. It is used at most once within a package (BUILD file).
For the counterpart that declares metadata applying to every rule in the whole
*repository*, use the `repo()` function in the
[`REPO.bazel` file](/external/overview#repo.bazel) at the root of your repo.
The `repo()` function takes exactly the same arguments as `package()`.
The package() function should be called right after all the load() statements at the top of the
file, before any rule.
### Arguments
| Attribute | Description |
| - | - |
| `default_applicable_licenses` | Alias for [`default_package_metadata`](#package.default_package_metadata). |
| `default_visibility` | List of [labels](/concepts/labels); default is `[]` The default visibility of the top-level rule targets and symbolic macros in this package — that is, the targets and symbolic macros that are not themselves declared inside a symbolic macro. This attribute is ignored if the target or macro specifies a `visibility` value. For detailed information about the syntax of this attribute, see the documentation of [visibility](/concepts/visibility). The package default visibility does not apply to [exports\_files](#exports_files), which is public by default. |
| `default_deprecation` | String; default is `""` Sets the default [`deprecation`](common-definitions#common.deprecation) message for all rules in this package. |
| `default_package_metadata` | List of [labels](/concepts/labels); default is `[]` Sets a default list of metadata targets which apply to all other targets in the package. These are typically targets related to OSS package and license declarations. See [rules\_license](https://github.com/bazelbuild/rules_license) for examples. |
| `default_testonly` | Boolean; default is `False` except as noted Sets the default [`testonly`](common-definitions#common.testonly) property for all rules in this package. In packages under `javatests` the default value is `True`. |
| `features` | List strings; default is `[]` Sets various flags that affect the semantics of this BUILD file. This feature is mainly used by the people working on the build system to tag packages that need some kind of special handling. Do not use this unless explicitly requested by someone working on the build system. |
### Examples
The declaration below declares that the rules in this package are
visible only to members of package
group `//foo:target`. Individual visibility declarations
on a rule, if present, override this specification.
```
package(default_visibility = ["//foo:target"])
```
## package\_group
```
package_group(name, packages, includes)
```
This function defines a set of [packages](/concepts/build-ref#packages)
and associates a label with the set. The label can be referenced in
`visibility` attributes.
Package groups are primarily used for visibility control. A publicly visible
target can be referenced from every package in the source tree. A privately
visible target can only be referenced within its own package (not subpackages).
In between these extremes, a target may allow access to its own package plus any
of the packages described by one or more package groups. For a more detailed
explanation of the visibility system, see the
[visibility](common-definitions#common.visibility)
attribute.
A given package is considered to be in the group if it either matches the
`packages` attribute, or is already contained in one of the other
package groups mentioned in the `includes` attribute.
Package groups are technically targets, but are not created by rules, and do
not themselves have any visibility protection.
### Arguments
| Attribute | Description |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `packages` | List of strings; default is `[]` A list of zero or more package specifications. Each package specification string can have one of the following forms:
The full name of a package, without its repository, starting with a double slash. For example, `//foo/bar` specifies the package having that name and which lives in the same repository as the package group.
As above, but with a trailing `/...`. For example, ` //foo/...` specifies the set of `//foo` and all its subpackages. `//...` specifies all packages in the current repository. `//` is used to denote the root package.
The strings `public` or `private`, which respectively specify every package or no package. (This form requires the flag `--incompatible_package_group_has_public_syntax` to be set.)
In addition, the first two kinds of package specifications may also be prefixed with `-` to indicate that they are negated. The package group contains any package that matches at least one of its positive specifications and none of its negative specifications For instance, the value `[//foo/..., -//foo/tests/...]` includes all subpackages of `//foo` that are not also subpackages of `//foo/tests`. (`//foo` itself is included while //foo/tests itself is not.) Aside from public visibility, there is no way to directly specify packages outside the current repository. If this attribute is missing, it is the same as setting it to an empty list, which is also the same as setting it to a list containing only `private`. *Note:* Prior to Bazel 6.0, the specification `//...` had a legacy behavior of being the same as `public`. This behavior is fixed when `--incompatible_fix_package_group_reporoot_syntax` is enabled, which is the default after Bazel 6.0. *Note:* Prior to Bazel 6.0, when this attribute is serialized as part of `bazel query --output=proto` (or `--output=xml`), the leading slashes are omitted. For instance, `//pkg/foo/...` will output as `\"pkg/foo/...\"`. This behavior is fixed when `--incompatible_package_group_includes_double_slash` is enabled, which is the default after Bazel 6.0. |
| `includes` | List of [labels](/concepts/labels); default is `[]` Other package groups that are included in this one. The labels in this attribute must refer to other package groups. Packages in referenced package groups are taken to be part of this package group. This is transitive — if package group `a` includes package group `b`, and `b` includes package group `c`, then every package in `c` will also be a member of `a`. When used together with negated package specifications, note that the set of packages for each group is first computed independently and the results are then unioned together. This means that negated specifications in one group have no effect on the specifications in another group. |
### Examples
The following `package_group` declaration specifies a
package group called "tropical" that contains tropical fruits.
```
package_group(
name = "tropical",
packages = [
"//fruits/mango",
"//fruits/orange",
"//fruits/papaya/...",
],
)
```
The following declarations specify the package groups of a fictional
application:
```
package_group(
name = "fooapp",
includes = [
":controller",
":model",
":view",
],
)
package_group(
name = "model",
packages = ["//fooapp/database"],
)
package_group(
name = "view",
packages = [
"//fooapp/swingui",
"//fooapp/webui",
],
)
package_group(
name = "controller",
packages = ["//fooapp/algorithm"],
)
```
## exports\_files
```
exports_files([label, ...], visibility, licenses)
```
`exports_files()` specifies a list of files belonging to
this package that are exported to other packages.
The BUILD file for a package may only refer directly to source files belonging
to another package if they are explicitly exported with an
`exports_files()` statement. Read more about
[visibility of files](/concepts/visibility#source-file-target-visibility).
As a legacy behaviour, also files mentioned as input to a rule are exported
with the default visibility until the flag
[`--incompatible_no_implicit_file_export`](https://github.com/bazelbuild/bazel/issues/10225)
is flipped. However, this behavior should not be relied upon and actively
migrated away from.
### Arguments
The argument is a list of names of files within the current package. A
visibility declaration can also be specified; in this case, the files will be
visible to the targets specified. If no visibility is specified, the files
will be visible to every package, even if a package default visibility was
specified in the `package`
function. The [licenses](common-definitions#common.licenses)
can also be specified.
### Example
The following example exports `golden.txt`, a
text file from the `test_data` package, so that other
packages may use it, for example, in the `data` attribute
of tests.
```
# from //test_data/BUILD
exports_files(["golden.txt"])
```
## glob
```
glob(include, exclude=[], exclude_directories=1, allow_empty=True)
```
Glob is a helper function that finds all files that match certain path patterns,
and returns a new, mutable, sorted list of their paths. Glob only searches files
in its own package, and looks only for source files (not generated files nor
other targets).
A source file's Label is included in the result if the file's package-relative
path matches any of the `include` patterns and none of the
`exclude` patterns.
The `include` and `exclude` lists contain path patterns
that are relative to the current package. Every pattern may consist of one or
more path segments. As usual with Unix paths, these segments are separated by
`/`. The segments in the pattern are matched against the segments of
the path. Segments may contain the `*` wildcard: this matches
any substring in the path segment (even the empty substring), excluding the
directory separator `/`. This wildcard can be used multiple times
within one path segment. Additionally, the `**` wildcard can match
zero or more complete path segments, but it must be declared as a standalone
path segment.
Examples:
* `foo/bar.txt` matches exactly the `foo/bar.txt` file
in this package (unless `foo/` is a subpackage)
* `foo/*.txt` matches every file in the `foo/` directory
if the file ends with `.txt` (unless `foo/` is a
subpackage)
* `foo/a*.htm*` matches every file in the `foo/`
directory that starts with `a`, then has an arbitrary string (could
be empty), then has `.htm`, and ends with another arbitrary string
(unless `foo/` is a subpackage); such as `foo/axx.htm`
and `foo/a.html` or `foo/axxx.html`
* `foo/*` matches every file in the `foo/` directory,
(unless `foo/` is a subpackage); it does not match `foo`
directory itself even if `exclude_directories` is set to
0
* `foo/**` matches every file in every non-subpackage subdirectory
under package's first level subdirectory `foo/`; if
`exclude_directories` is set to 0, `foo`
directory itself also matches the pattern; in this case, `**` is
considered to match zero path segments
* `**/a.txt` matches `a.txt` files in this package's
directory plus non-subpackage subdirectories.
* `**/bar/**/*.txt` matches every `.txt` file in every
non-subpackage subdirectory of this package, if at least one directory on the
resulting path is called `bar`, such as
`xxx/bar/yyy/zzz/a.txt` or `bar/a.txt` (remember that
`**` also matches zero segments) or `bar/zzz/a.txt`
* `**` matches every file in every non-subpackage subdirectory of
this package
* `foo**/a.txt` is an invalid pattern, because `**` must
stand on its own as a segment
* `foo/` is an invalid pattern, because the second segment defined
after `/` is an empty string
If the `exclude_directories` argument is enabled (set to 1), files of
type directory will be omitted from the results (default 1).
If the `allow_empty` argument is set to `False`, the
`glob` function will error-out if the result would otherwise be the
empty list.
There are several important limitations and caveats:
1. Since `glob()` runs during BUILD file evaluation,
`glob()` matches files only in your source tree, never
generated files. If you are building a target that requires both
source and generated files, you must append an explicit list of generated
files to the glob. See the [example](#glob_example)
below with `:mylib` and `:gen_java_srcs`.
2. If a rule has the same name as a matched source file, the rule will
"shadow" the file.
To understand this, remember that `glob()` returns a list of
paths, so using `glob()` in other rules' attribute (e.g.
`srcs = glob(["*.cc"])`) has the same effect as listing the
matched paths explicitly. If for example `glob()` yields
`["Foo.java", "bar/Baz.java"]` but there's also a rule in the
package called "Foo.java" (which is allowed, though Bazel warns about it),
then the consumer of the `glob()` will use the "Foo.java" rule
(its outputs) instead of the "Foo.java" file. See
[GitHub
issue #10395](https://github.com/bazelbuild/bazel/issues/10395#issuecomment-583714657) for more details.
3. Globs may match files in subdirectories. And subdirectory names
may be wildcarded. However...
4. Labels are not allowed to cross the package boundary and glob does
not match files in subpackages.
For example, the glob expression `**/*.cc` in package
`x` does not include `x/y/z.cc` if
`x/y` exists as a package (either as
`x/y/BUILD`, or somewhere else on the package-path). This
means that the result of the glob expression actually depends on the
existence of BUILD files — that is, the same glob expression would
include `x/y/z.cc` if there was no package called
`x/y` or it was marked as deleted using the
[--deleted\_packages](/docs/user-manual#flag--deleted_packages)
flag.
5. The restriction above applies to all glob expressions,
no matter which wildcards they use.
6. A hidden file with filename starting with `.` is completely matched by
both the `**` and the `*` wildcards. If you want to match a hidden file
with a compound pattern, your pattern needs to begin with a `.`. For example,
`*` and `.*.txt` will match `.foo.txt`, but `*.txt`
will not.
Hidden directories are also matched in the same manner. Hidden directories
may include files that are not required as inputs, and can increase the
number of unnecessarily globbed files and memory consumption. To exclude
hidden directories, add them to the "exclude" list argument.
7. The "\*\*" wildcard has one corner case: the pattern
`"**"` doesn't match the package's directory path. That is to
say, `glob(["**"], exclude_directories = False)` matches all files
and directories transitively strictly under the current package's directory
(but of course not going into directories of subpackages - see the previous
note about that).
In general, you should **try to provide an appropriate extension (e.g. \*.html)
instead of using a bare '\*'** for a glob pattern. The more explicit name
is both self documenting and ensures that you don't accidentally match backup
files, or emacs/vi/... auto-save files.
When writing build rules you can enumerate the elements of the glob. This
enables generating individual rules for every input, for example. See the
[expanded glob example](#expanded_glob_example) section below.
### Glob Examples
Create a Java library built from all java files in this directory,
and all files generated by the `:gen_java_srcs` rule.
```
java_library(
name = "mylib",
srcs = glob(["*.java"]) + [":gen_java_srcs"],
deps = "...",
)
genrule(
name = "gen_java_srcs",
outs = [
"Foo.java",
"Bar.java",
],
...
)
```
Include all txt files in directory testdata except experimental.txt.
Note that files in subdirectories of testdata will not be included. If
you want those files to be included, use a recursive glob (\*\*).
```
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(
["testdata/*.txt"],
exclude = ["testdata/experimental.txt"],
),
)
```
### Recursive Glob Examples
Make the test depend on all txt files in the testdata directory and any
of its subdirectories (and their subdirectories, and so on).
Subdirectories containing a BUILD file are ignored. (See limitations
and caveats above.)
```
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(["testdata/**/*.txt"]),
)
```
Create a library built from all java files in this directory and all
subdirectories except those whose path includes a directory named testing.
**This pattern should be avoided if possible, as it can reduce build
incrementality and therefore increase build times.**
```
java_library(
name = "mylib",
srcs = glob(
["**/*.java"],
exclude = ["**/testing/**"],
),
)
```
### Expanded Glob Examples
Create an individual genrule for \*\_test.cc in the current directory
that counts the number of lines in the file.
```
# Conveniently, the build language supports list comprehensions.
[genrule(
name = "count_lines_" + f[:-3], # strip ".cc"
srcs = [f],
outs = ["%s-linecount.txt" % f[:-3]],
cmd = "wc -l $< >$@",
) for f in glob(["*_test.cc"])]
```
If the BUILD file above is in package //foo and the package contains three
matching files, a\_test.cc, b\_test.cc and c\_test.cc then running
`bazel query '//foo:all'` will list all rules that were generated:
```
$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test
```
## select
```
select(
{conditionA: valuesA, conditionB: valuesB, ...},
no_match_error = "custom message"
)
```
`select()` is the helper function that makes a rule attribute
[configurable](common-definitions#configurable-attributes).
It can replace the right-hand side of
*almost*
any attribute assignment so its value depends on command-line Bazel flags.
You can use this, for example, to define platform-specific dependencies or to
embed different resources depending on whether a rule is built in "developer"
vs. "release" mode.
Basic use is as follows:
```
sh_binary(
name = "mytarget",
srcs = select({
":conditionA": ["mytarget_a.sh"],
":conditionB": ["mytarget_b.sh"],
"//conditions:default": ["mytarget_default.sh"]
})
)
```
This makes the `srcs` attribute of
a `sh_binary` configurable by replacing its normal label
list assignment with a `select` call that maps
configuration conditions to matching values. Each condition is a label
reference to
a `config_setting` or
`constraint_value`,
which "matches" if the target's configuration matches an expected set of
values. The value of `mytarget#srcs` then becomes whichever
label list matches the current invocation.
Notes:
* Exactly one condition is selected on any invocation.
* If multiple conditions match and one is a specialization of the others,
the specialization takes precedence. Condition B is considered a
specialization of condition A if B has all the same flags and constraint
values as A plus some additional flags or constraint values. This also
means that specialization resolution is not designed to create an ordering as
demonstrated in Example 2 below.
* If multiple conditions match and one is not a specialization of all the
others, Bazel fails with an error, unless all conditions resolve to the same value.
* The special pseudo-label `//conditions:default` is
considered to match if no other condition matches. If this condition
is left out, some other rule must match to avoid an error.
* `select` can be embedded *inside* a larger
attribute assignment. So `srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})` and `srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})` are valid expressions.
* `select` works with most, but not all, attributes. Incompatible
attributes are marked `nonconfigurable` in their documentation.
## subpackages
```
subpackages(include, exclude=[], allow_empty=True)
```
`subpackages()` is a helper function, similar to `glob()`
that lists subpackages instead of files and directories. It uses the same
path patterns as `glob()` and can match any subpackage that is a
direct descendant of the currently loading BUILD file. See [glob](#glob) for a detailed explanation and examples of include and
exclude patterns.
The resulting list of subpackages returned is in sorted order and contains
paths relative to the current loading package that match the given patterns in
`include` and not those in `exclude`.
### Example
The following example lists all the direct subpackages for the package `foo/BUILD`
```
# The following BUILD files exist:
# foo/BUILD
# foo/bar/baz/BUILD
# foo/bar/but/bad/BUILD
# foo/sub/BUILD
# foo/sub/deeper/BUILD
#
# In foo/BUILD a call to
subs1 = subpackages(include = ["**"])
# results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
#
# 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
# 'foo'
subs2 = subpackages(include = ["bar/*"])
# results in subs2 = ["bar/baz"]
#
# Since 'bar' is not a subpackage itself, this looks for any subpackages under
# all first level subdirectories of 'bar'.
subs3 = subpackages(include = ["bar/**"])
# results in subs3 = ["bar/baz", "bar/but/bad"]
#
# Since bar is not a subpackage itself, this looks for any subpackages which are
# (1) under all subdirectories of 'bar' which can be at any level, (2) not a
# subpackage of another subpackages.
subs4 = subpackages(include = ["sub"])
subs5 = subpackages(include = ["sub/*"])
subs6 = subpackages(include = ["sub/**"])
# results in subs4 and subs6 being ["sub"]
# results in subs5 = [].
#
# In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
# subpackage of 'foo').
# In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
# 'foo/sub' is already a subpackage itself, the subdirectories will not be
# traversed anymore.
# In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
# is returned. But the subdirectories of 'foo/sub' will not be traversed
# anymore.
```
In general it is preferred that instead of calling this function directly
that users use the 'subpackages' module of
[skylib](https://github.com/bazelbuild/bazel-skylib).
# Make Variables
Source: https://bazel.build/reference/be/make-variables
* [Use](#use)
* [Predefined variables](#predefined_variables)
* [Predefined genrule variables](#predefined_genrule_variables)
* [Predefined source/output path variables](#predefined_label_variables)
* [Custom variables](#custom_variables)
"Make" variables are a special class of expandable string variables available
to attributes marked as *"Subject to 'Make variable' substitution"*.
These can be used, for example, to inject specific toolchain paths into
user-constructed build actions.
Bazel provides both *predefined* variables, which are available to all
targets, and *custom* variables, which are defined in dependency targets
and only available to targets that depend on them.
The reason for the term "Make" is historical: the syntax and semantics of
these variables were originally intended to match [GNU
Make](https://www.gnu.org/software/make/manual/html_node/Using-Variables.html).
## Use
Attributes marked as *"Subject to 'Make variable' substitution"* can
reference the "Make" variable `FOO` as follows:
`my_attr = "prefix $(FOO) suffix"`
In other words, any substring matching `$(FOO)` gets expanded
to `FOO`'s value. If that value is `"bar"`, the final
string becomes:
`my_attr = "prefix bar suffix"`
If `FOO` doesn't correspond to a variable known to the consuming
target, Bazel fails with an error.
"Make" variables whose names are non-letter symbols, such as
`@`, can also be referenced using only a dollar sign, without
the parentheses. For example:
`my_attr = "prefix $@ suffix"`
To write `$` as a string literal (i.e. to prevent variable
expansion), write `$$`.
## Predefined variables
Predefined "Make" variables can be referenced by any attribute marked as
*"Subject to 'Make variable' substitution"* on any target.
To see the list of these variables and their values for a given set of build
options, run
`bazel info --show_make_env [build options]`
and look at the top output lines with capital letters.
[See an example of predefined variables](https://github.com/bazelbuild/examples/tree/main/make-variables#predefined-variables).
**Toolchain option variables**
* `COMPILATION_MODE`:
`fastbuild`, `dbg`, or `opt`. ([more
details](https://bazel.build/docs/user-manual#flag--compilation_mode))
**Path variables**
* `BINDIR`: The base of the generated binary tree for the target
architecture.
Note that a different tree may be used for programs that run during the
build on the host architecture, to support cross-compiling.
If you want to run a tool from within a `genrule`, the
recommended way to get its path is `$(execpath toolname)`,
where *toolname* must be listed in the `genrule`'s
`tools` attribute.
* `GENDIR`:
The base of the generated code tree for the target architecture.
**Machine architecture variables**
* `TARGET_CPU`:
The target architecture's CPU, e.g. `k8`.
## Predefined genrule variables
The following are specially available to `genrule`'s
`cmd` attribute and are
generally important for making that attribute work.
[See an example of predefined genrule variables](https://github.com/bazelbuild/examples/tree/main/make-variables#predefined-genrule-variables).
* `OUTS`: The `genrule`'s `outs` list. If you have
only one output file, you can also use `$@`.
* `SRCS`: The `genrule`'s `srcs` list (or more
precisely: the path names of the files corresponding to labels in the
`srcs` list).
If you have only one source file, you can also use `$<`.
* `<`: `SRCS`, if it is a single file. Else triggers
a build error.
* `@`: `OUTS`, if it is a single file. Else triggers a
build error.
* `RULEDIR`: The output directory of the target, that is, the
directory corresponding to the name of the package containing the target
under the `genfiles` or `bin` tree. For
`//my/pkg:my_genrule` this always ends in `my/pkg`,
even if `//my/pkg:my_genrule`'s outputs are in subdirectories.
* `@D`: The output directory. If
[outs](/reference/be/general#genrule.outs) has one entry,
this expands to the directory containing that file. If it has multiple
entries, this expands to the package's root directory in the
`genfiles` tree, *even if all output files are in the same
subdirectory*!
**Note:** Use `RULEDIR` over `@D` because
`RULEDIR` has simpler semantics and behaves the same way
regardless of the number of output files.
If the genrule needs to generate temporary intermediate files (perhaps as
a result of using some other tool like a compiler), it should attempt to
write them to `@D` (although `/tmp` will also
be writable) and remove them before finishing.
Especially avoid writing to directories containing inputs. They may be on
read-only filesystems. Even if not, doing so would trash the source tree.
**Note:** If the filenames corresponding to the input labels or the output
filenames contain spaces, `'`, or other special characters (or your
genrule is part of a Starlark macro which downstream users may invoke on such
files), then `$(SRCS)` and `$(OUTS)` are not suitable
for interpolation into a command line, as they do not have the semantics that
`"${@}"` would in Bash.
One workaround is to convert to a Bash array, with
```
mapfile SRCS <<< "$$(sed -e 's/ /\\n/g' <<'genrule_srcs_expansion'
$(SRC)
genrule_srcs_expansion
)
```
and then use `"$$\{SRCS[@]}"` in subsequent command lines in place
of `$(SRCS)`. A more robust option is to write a Starlark rule
instead.
## Predefined source/output path variables
The predefined variables `execpath`, `execpaths`,
`rootpath`, `rootpaths`, `location`, and
`locations` take label parameters (e.g. `$(execpath //foo:bar)`) and substitute the file paths denoted by that label.
For source files, this is the path relative to your workspace root.
For files that are outputs of rules, this is the file's *output path*
(see the explanation of *output files* below).
[See an example of predefined path variables](https://github.com/bazelbuild/examples/tree/main/make-variables#predefined-path-variables).
* `execpath`: Denotes the path beneath the
[execroot](/docs/output_directories)
where Bazel runs build actions.
In the above example, Bazel runs all build actions in the directory linked
by the `bazel-myproject` symlink in your workspace root. The
source file `empty.source` is linked at the path
`bazel-myproject/testapp/empty.source`. So its exec path (which
is the subpath below the root) is `testapp/empty.source`. This
is the path build actions can use to find the file.
Output files are staged similarly, but are also prefixed with the subpath
`bazel-out/cpu-compilation_mode/bin` (or for the outputs of
tools: `bazel-out/cpu-opt-exec-hash/bin`). In the above example,
`//testapp:app` is a tool because it appears in
`show_app_output`'s `tools` attribute.
So its output file `app` is written to
`bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app`.
The exec path is thus `bazel-out/cpu-opt-exec-hash/bin/testapp/app`. This extra prefix
makes it possible to build the same target for, say, two different CPUs in
the same build without the results clobbering each other.
The label passed to this variable must represent exactly one file. For
labels representing source files, this is automatically true. For labels
representing rules, the rule must generate exactly one output. If this is
false or the label is malformed, the build fails with an error.
* `rootpath`: Denotes the path that a built binary can use to
find a dependency at runtime relative to the subdirectory of its runfiles
directory corresponding to the main repository.
**Note:** This only works if [`--enable_runfiles`](/reference/command-line-reference#flag--enable_runfiles) is enabled, which is not the case on
Windows by default. Use `rlocationpath` instead for
cross-platform support.
This is similar to `execpath` but strips the configuration
prefixes described above. In the example from above this means both
`empty.source` and `app` use pure workspace-relative
paths: `testapp/empty.source` and `testapp/app`.
The `rootpath` of a file in an external repository
`repo` will start with `../repo/`, followed by the
repository-relative path.
This has the same "one output only" requirements as `execpath`.
* `rlocationpath`: The path a built binary can pass to the `Rlocation` function of a runfiles library to find a dependency at
runtime, either in the runfiles directory (if available) or using the
runfiles manifest.
This is similar to `rootpath` in that it does not contain
configuration prefixes, but differs in that it always starts with the
name of the repository. In the example from above this means that `empty.source` and `app` result in the following
paths: `myproject/testapp/empty.source` and `myproject/testapp/app`.
The `rlocationpath` of a file in an external repository
`repo` will start with `repo/`, followed by the
repository-relative path.
Passing this path to a binary and resolving it to a file system path using
the runfiles libraries is the preferred approach to find dependencies at
runtime. Compared to `rootpath`, it has the advantage that it
works on all platforms and even if the runfiles directory is not
available.
This has the same "one output only" requirements as `execpath`.
* `location`: A synonym for either `execpath` or
`rootpath`, depending on the attribute being expanded. This is
legacy pre-Starlark behavior and not recommended unless you really know what
it does for a particular rule. See [#2475](https://github.com/bazelbuild/bazel/issues/2475#issuecomment-339318016)
for details.
`execpaths`, `rootpaths`, `rlocationpaths`,
and `locations` are the plural variations of `execpath`,
`rootpath`, `rlocationpath`, and`location`,
respectively. They support labels producing multiple outputs, in which case
each output is listed separated by a space. Zero-output rules and malformed
labels produce build errors.
All referenced labels must appear in the consuming target's `srcs`,
output files, or `deps`. Otherwise the build fails. C++ targets can
also reference labels in `data`.
Labels don't have to be in canonical form: `foo`, `:foo`
and `//somepkg:foo` are all fine.
## Custom variables
Custom "Make" variables can be referenced by any attribute marked as
*"Subject to 'Make variable' substitution"*, but only on targets that
depend on other targets that *define* these variables.
As best practice all variables should be custom unless there's a really good
reason to bake them into core Bazel. This saves Bazel from having to load
potentially expensive dependencies to supply variables consuming tarets may
not care about.
**C++ toolchain variables**
The following are defined in C++ toolchain rules and available to any rule
that sets `toolchains = ["@bazel_tools//tools/cpp:toolchain_type"]`
Some rules, like `java_binary`, implicitly
include the C++ toolchain in their rule definition. They inherit these variables
automatically.
The built-in C++ rules are much more sophisticated than "run the compiler on
it". In order to support compilation modes as diverse as \*SAN, ThinLTO,
with/without modules, and carefully optimized binaries at the same time as
fast running tests on multiple platforms, the built-in rules go to great
lengths to ensure the correct inputs, outputs, and command-line flags are set
on each of potentially multiple internally generated actions.
These variables are a fallback mechanism to be used by language experts in
rare cases. If you are tempted to use them, please [contact the Bazel devs](https://bazel.build/help) first.
* `ABI`: The C++ ABI version.
* `AR`: The "ar" command from crosstool.
* `C_COMPILER`:
The C/C++ compiler identifier, e.g. `llvm`.
* `CC`: The C and C++ compiler command.
We strongly recommended always using `CC_FLAGS` in
combination with `CC`. Fail to do so at your own risk.
* `CC_FLAGS`: A minimal set of flags for the C/C++
compiler to be usable by genrules. In particular, this contains flags to
select the correct architecture if `CC` supports multiple
architectures.
* `DUMPBIN`: Microsoft COFF Binary File Dumper (dumpbin.exe) from
from Microsoft Visual Studio.
* `NM`: The "nm" command from crosstool.
* `OBJCOPY`: The objcopy command from the same suite as the C/C++
compiler.
* `STRIP`: The strip command from the same suite as the C/C++
compiler.
**Java toolchain variables**
The following are defined in Java toolchain rules and available to any rule
that sets `toolchains = ["@rules_java//toolchains:current_java_runtime"]` (or
`"@rules_java//toolchains:current_host_java_runtime"`
for the host toolchain equivalent).
Most of the tools in the JDK should not be used directly. The built-in Java
rules use much more sophisticated approaches to Java compilation and packaging
than upstream tools can express, such as interface Jars, header interface
Jars, and highly optimized Jar packaging and merging implementations.
These variables are a fallback mechanism to be used by language experts in
rare cases. If you are tempted to use them, please [contact the Bazel devs](https://bazel.build/help) first.
* `JAVA`: The "java" command (a Java virtual
machine). Avoid this, and use a `java_binary` rule
instead where possible. May be a relative path. If you must change
directories before invoking `java`, you need to capture the
working directory before changing it.
* `JAVABASE`: The base directory containing the
Java utilities. May be a relative path. It will have a "bin"
subdirectory.
**Starlark-defined variables**
Rule and [toolchain](/docs/toolchains) writers can define
completely custom variables by returning a
[TemplateVariableInfo](/rules/lib/TemplateVariableInfo)
provider. Any rules depending on these through the
`toolchains` attribute can then read their values:
[See an example of Starlark-defined variables](https://github.com/bazelbuild/examples/tree/main/make-variables#custom-starlark-defined-variables).
# Bazel BUILD Encyclopedia of Functions
Source: https://bazel.build/reference/be/overview
## Concepts and terminology
* [Common definitions](/reference/be/common-definitions)
* [Bourne shell tokenization](/reference/be/common-definitions#sh-tokenization)
* [Label expansion](/reference/be/common-definitions#label-expansion)
* [Typical attributes for most rules](/reference/be/common-definitions#typical-attributes)
* [Common attributes for all rules](/reference/be/common-definitions#common-attributes)
* [Common attributes for tests](/reference/be/common-definitions#common-attributes-tests)
* [Common attributes for binaries](/reference/be/common-definitions#common-attributes-binaries)
* [Configurable attributes](/reference/be/common-definitions#configurable-attributes)
* [Implicit output targets](/reference/be/common-definitions#implicit-outputs)
* ["Make" variables](/reference/be/make-variables)
* [Use](/reference/be/make-variables#use)
## Functions
* [package](/reference/be/functions#package)
* [package\_group](/reference/be/functions#package_group)
* [exports\_files](/reference/be/functions#exports_files)
* [glob](/reference/be/functions#glob)
* [select](/reference/be/functions#select)
## Rules
Native rules ship with the Bazel binary and do not require a `load` statement.
Native rules are available globally in BUILD files. In .bzl files, you can find them in
the `native` module.
For non-native Starlark rules that ship separately from Bazel, see the list of
[recommended rules](/rules/rules#recommended-rules).
### Language-specific native rules
| Language | Flags | Binary rules | Library rules | Test rules | Other rules |
| - | - | - | - | - | - |
| C / C++ | | [cc\_binary](c-cpp#cc_binary) | [cc\_import](c-cpp#cc_import) [cc\_library](c-cpp#cc_library) [cc\_shared\_library](c-cpp#cc_shared_library) [cc\_static\_library](c-cpp#cc_static_library) | [cc\_test](c-cpp#cc_test) | [cc\_toolchain](c-cpp#cc_toolchain) [fdo\_prefetch\_hints](c-cpp#fdo_prefetch_hints) [fdo\_profile](c-cpp#fdo_profile) [memprof\_profile](c-cpp#memprof_profile) [propeller\_optimize](c-cpp#propeller_optimize) |
| Java | | [java\_binary](java#java_binary) | [java\_import](java#java_import) [java\_library](java#java_library) | [java\_test](java#java_test) | [java\_package\_configuration](java#java_package_configuration) [java\_plugin](java#java_plugin) [java\_runtime](java#java_runtime) [java\_toolchain](java#java_toolchain) |
| Objective-C | | | [objc\_import](objective-c#objc_import) [objc\_library](objective-c#objc_library) | | |
| Protocol Buffer | | | [cc\_proto\_library](protocol-buffer#cc_proto_library) [java\_lite\_proto\_library](protocol-buffer#java_lite_proto_library) [java\_proto\_library](protocol-buffer#java_proto_library) [proto\_library](protocol-buffer#proto_library) [py\_proto\_library](protocol-buffer#py_proto_library) | | [proto\_lang\_toolchain](protocol-buffer#proto_lang_toolchain) [proto\_toolchain](protocol-buffer#proto_toolchain) |
| Python | | [py\_binary](python#py_binary) | [py\_library](python#py_library) | [py\_test](python#py_test) | [py\_runtime](python#py_runtime) |
| Shell | | [sh\_binary](shell#sh_binary) | [sh\_library](shell#sh_library) | [sh\_test](shell#sh_test) | |
### Language-agnostic native rules
| Family | Rules |
| - | - |
| Extra Actions |
|
# Platforms and Toolchains Rules
Source: https://bazel.build/reference/be/platforms-and-toolchains
This set of rules exists to allow you to model specific hardware platforms you are
building for and specify the specific tools you may need to compile code for those platforms.
The user should be familiar with the concepts explained [here](/extending/platforms).
## Rules
* [constraint\_setting](#constraint_setting)
* [constraint\_value](#constraint_value)
* [platform](#platform)
* [toolchain](#toolchain)
* [toolchain\_type](#toolchain_type)
## constraint\_setting
[View rule source](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintSettingRule.java)
```
constraint_setting(name, aspect_hints, default_constraint_value, deprecation, features, licenses, refines_constraint_value, tags, testonly, visibility)
```
This rule is used to introduce a new constraint type for which a platform may specify a value.
For instance, you might define a `constraint_setting` named "glibc\_version" to represent
the capability for platforms to have different versions of the glibc library installed.
For more details, see the
[Platforms](https://bazel.build/docs/platforms) page.
Each `constraint_setting` has an extensible set of associated
`constraint_value`s. Usually these are defined in the same package, but sometimes a
different package will introduce new values for an existing setting. For instance, the predefined
setting `@platforms//cpu:cpu` can be extended with a custom value in order to
define a platform targeting an obscure cpu architecture.
### Arguments
| Attributes | |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `default_constraint_value` | [Name](/concepts/labels#target-names); [nonconfigurable](common-definitions#configurable-attributes); default is `None` The label of the default value for this setting, to be used if no value is given. If this attribute is present, the `constraint_value` it points to must be defined in the same package as this `constraint_setting`. If a constraint setting has a default value, then whenever a platform does not include any constraint value for that setting, it is the same as if the platform had specified the default value. Otherwise, if there is no default value, the constraint setting is considered to be unspecified by that platform. In that case, the platform would not match against any constraint list (such as for a `config_setting`) that requires a particular value for that setting. |
| `refines_constraint_value` | [Label](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); default is `None` The label of a `constraint_value` that this setting refines. If set, any `platform` that specifies a non-default `constraint_value` for this setting must also specify the refined `constraint_value` in its `constraint_values` attribute. Platforms that resolve to the default `constraint_value` for this setting (either implicitly via `default_constraint_value` or explicitly) are exempt from this requirement. When both the refined `constraint_value` and a `constraint_value` for this setting appear as conditions in the same `select` and both are satisfied, the condition that includes the refining `constraint_value` is considered more specific and is chosen unambiguously. |
## constraint\_value
[View rule source](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/platform/ConstraintValueRule.java)
```
constraint_value(name, aspect_hints, constraint_setting, deprecation, features, licenses, tags, testonly, visibility)
```
This rule introduces a new value for a given constraint type.
For more details, see the
[Platforms](https://bazel.build/docs/platforms) page.
#### Example
The following creates a new possible value for the predefined `constraint_value`
representing cpu architecture.
```
constraint_value(
name = "mips",
constraint_setting = "@platforms//cpu:cpu",
)
```
Platforms can then declare that they have the `mips` architecture as an alternative to
`x86_64`, `arm`, and so on.
### Arguments
| Attributes | |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `constraint_setting` | [Label](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); required The `constraint_setting` for which this `constraint_value` is a possible choice. |
## platform
[View rule source](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/platform/PlatformRule.java)
```
platform(name, aspect_hints, constraint_values, deprecation, exec_properties, features, flags, licenses, missing_toolchain_error, parents, required_settings, tags, testonly, visibility)
```
This rule defines a new platform -- a named collection of constraint choices
(such as cpu architecture or compiler version) describing an environment in
which part of the build may run.
For more details, see the [Platforms](/extending/platforms) page.
#### Example
This defines a platform that describes any environment running Linux on ARM.
```
platform(
name = "linux_arm",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
```
### Platform Flags
Platforms may use the `flags` attribute to specify a list of flags that will be added
to the configuration whenever the platform is used as the target platform (i.e., as the value of
the `--platforms` flag).
Flags set from the platform effectively have the highest precedence and overwrite any previous
value for that flag, from the command line, rc file, or transition.
#### Example
```
platform(
name = "foo",
flags = [
"--dynamic_mode=fully",
"--//bool_flag",
"--no//package:other_bool_flag",
],
)
```
This defines a platform named `foo`. When this is the target platform (either because
the user specified `--platforms//:foo`, because a transition set the
`//command_line_option:platforms` flag to `["//:foo"]`, or because
`//:foo` was used as an execution platform), then the given flags will be set in the
configuration.
#### Platforms and Repeatable Flags
Some flags will accumulate values when they are repeated, such as `--features`,
`--copt`, any Starlark flag created as `config.string(repeatable = True)`.
These flags are not compatible with setting the flags from the platform: instead, all previous
values will be removed and overwritten with the values from the platform.
As an example, given the following platform, the invocation `build --platforms=//:repeat_demo --features feature_a --features feature_b` will end up with the value of the
`--feature` flag being `["feature_c", "feature_d"]`, removing the features
set on the command line.
```
platform(
name = "repeat_demo",
flags = [
"--features=feature_c",
"--features=feature_d",
],
)
```
For this reason, it is discouraged to use repeatable flags in the `flags` attribute.
### Platform Inheritance
Platforms may use the `parents` attribute to specify another platform that they will
inherit constraint values from. Although the `parents` attribute takes a list, no
more than a single value is currently supported, and specifying multiple parents is an error.
When checking for the value of a constraint setting in a platform, first the values directly set
(via the `constraint_values` attribute) are checked, and then the constraint values on
the parent. This continues recursively up the chain of parent platforms. In this manner, any
values set directly on a platform will override the values set on the parent.
Platforms inherit the `exec_properties` attribute from the parent platform.
The dictionary entries in `exec_properties` of the parent and child platforms
will be combined.
If the same key appears in both the parent's and the child's `exec_properties`,
the child's value will be used. If the child platform specifies an empty string as a value, the
corresponding property will be unset.
#### Example: Constraint Values
```
platform(
name = "parent",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
platform(
name = "child_a",
parents = [":parent"],
constraint_values = [
"@platforms//cpu:x86_64",
],
)
platform(
name = "child_b",
parents = [":parent"],
)
```
In this example, the child platforms have the following properties:
* `child_a` has the constraint values `@platforms//os:linux` (inherited
from the parent) and `@platforms//cpu:x86_64` (set directly on the platform).
* `child_b` inherits all constraint values from the parent, and doesn't set any of
its own.
#### Example: Execution properties
```
platform(
name = "parent",
exec_properties = {
"k1": "v1",
"k2": "v2",
},
)
platform(
name = "child_a",
parents = [":parent"],
)
platform(
name = "child_b",
parents = [":parent"],
exec_properties = {
"k1": "child"
}
)
platform(
name = "child_c",
parents = [":parent"],
exec_properties = {
"k1": ""
}
)
platform(
name = "child_d",
parents = [":parent"],
exec_properties = {
"k3": "v3"
}
)
```
In this example, the child platforms have the following properties:
* `child_a` inherits the "exec\_properties" of the parent and does not set its own.
* `child_b` inherits the parent's `exec_properties` and overrides the
value of `k1`. Its `exec_properties` will be:
`{ "k1": "child", "k2": "v2" }`.
* `child_c` inherits the parent's `exec_properties` and unsets
`k1`. Its `exec_properties` will be:
`{ "k2": "v2" }`.
* `child_d` inherits the parent's `exec_properties` and adds a new
property. Its `exec_properties` will be:
`{ "k1": "v1", "k2": "v2", "k3": "v3" }`.
### Arguments
| Attributes | |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `constraint_values` | List of [labels](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); default is `[]` The combination of constraint choices that this platform comprises. In order for a platform to apply to a given environment, the environment must have at least the values in this list. Each `constraint_value` in this list must be for a different `constraint_setting`. For example, you cannot define a platform that requires the cpu architecture to be both `@platforms//cpu:x86_64` and `@platforms//cpu:arm`. |
| `exec_properties` | Dictionary: String -> String; [nonconfigurable](common-definitions#configurable-attributes); default is `{}` A map of strings that affect the way actions are executed remotely. Bazel makes no attempt to interpret this, it is treated as opaque data that's forwarded via the Platform field of the [remote execution protocol](https://github.com/bazelbuild/remote-apis). This includes any data from the parent platform's `exec_properties` attributes. If the child and parent platform define the same keys, the child's values are kept. Any keys associated with a value that is an empty string are removed from the dictionary. |
| `flags` | List of strings; [nonconfigurable](common-definitions#configurable-attributes); default is `[]` A list of flags that will be enabled when this platform is used as the target platform in a configuration. Only flags that are part of the configuration can be set, such as those that can be used in transitions, or the `--define` flag. |
| `missing_toolchain_error` | String; [nonconfigurable](common-definitions#configurable-attributes); default is `"For more information on platforms or toolchains see https://bazel.build/concepts/platforms-intro"` A custom error message that is displayed when a mandatory toolchain requirement cannot be satisfied for this target platform. Intended to point to relevant documentation users can read to understand why their toolchains are misconfigured. Not inherited from parent platforms. |
| `parents` | List of [labels](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); default is `[]` The label of a `platform` target that this platform should inherit from. Although the attribute takes a list, there should be no more than one platform present. Any constraint\_settings not set directly on this platform will be found in the parent platform. See the section on [Platform Inheritance](#platform_inheritance) for details. |
| `required_settings` | List of [labels](/concepts/labels); default is `[]` A list of `config_setting`s that must be satisfied by the target configuration in order for this platform to be used as an execution platform during toolchain resolution. Required settings are not inherited from parent platforms. |
## toolchain
[View rule source](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/platform/ToolchainRule.java)
```
toolchain(name, aspect_hints, deprecation, exec_compatible_with, features, licenses, package_metadata, tags, target_compatible_with, target_settings, testonly, toolchain, toolchain_type, use_target_platform_constraints, visibility)
```
This rule declares a specific toolchain's type and constraints so that it can be selected
during toolchain resolution. See the
[Toolchains](https://bazel.build/docs/toolchains) page for more
details.
### Arguments
| Attributes | |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `exec_compatible_with` | List of [labels](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); default is `[]` A list of `constraint_value`s that must be satisfied by an execution platform in order for this toolchain to be selected for a target building on that platform. |
| `target_compatible_with` | List of [labels](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); default is `[]` A list of `constraint_value`s that must be satisfied by the target platform in order for this toolchain to be selected for a target building for that platform. |
| `target_settings` | List of [labels](/concepts/labels); default is `[]` A list of `config_setting`s that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution. |
| `toolchain` | [Name](/concepts/labels#target-names); required The target representing the actual tool or tool suite that is made available when this toolchain is selected. |
| `toolchain_type` | [Label](/concepts/labels); [nonconfigurable](common-definitions#configurable-attributes); required The label of a `toolchain_type` target that represents the role that this toolchain serves. |
| `use_target_platform_constraints` | Boolean; [nonconfigurable](common-definitions#configurable-attributes); default is `False` If `True`, this toolchain behaves as if its `exec_compatible_with` and `target_compatible_with` constraints are set to those of the current target platform. `exec_compatible_with` and `target_compatible_with` must not be set in that case. |
## toolchain\_type
[View rule source](https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/ToolchainType.java)
```
toolchain_type(name, aspect_hints, compatible_with, deprecation, features, no_match_error, package_metadata, restricted_to, tags, target_compatible_with, testonly, visibility)
```
This rule defines a new type of toolchain -- a simple target that represents a class of tools that
serve the same role for different platforms.
See the [Toolchains](/docs/toolchains) page for more details.
#### Example
This defines a toolchain type for a custom rule.
```
toolchain_type(
name = "bar_toolchain_type",
)
```
This can be used in a bzl file.
```
bar_binary = rule(
implementation = _bar_binary_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
...
# No `_compiler` attribute anymore.
},
toolchains = ["//bar_tools:toolchain_type"]
)
```
### Arguments
| Attributes | |
| - | - |
| `name` | [Name](/concepts/labels#target-names); required A unique name for this target. |
| `no_match_error` | String; [nonconfigurable](common-definitions#configurable-attributes); default is `""` A custom error message to display when no matching toolchain is found for this type. |
# Command line reference
Source: https://bazel.build/reference/command-line-reference
## Commands
| | |
| - | - |
| [`aquery`](#aquery) | Analyzes the given targets and queries the action graph. |
| [`build`](#build) | Builds the specified targets. |
| [`canonicalize-flags`](#canonicalize-flags) | Canonicalizes a list of bazel options. |
| [`clean`](#clean) | Removes output files and optionally stops the server. |
| [`coverage`](#coverage) | Generates code coverage report for specified test targets. |
| [`cquery`](#cquery) | Loads, analyzes, and queries the specified targets w/ configurations. |
| [`dump`](#dump) | Dumps the internal state of the bazel server process. |
| [`fetch`](#fetch) | Fetches external repositories that are prerequisites to the targets. |
| [`help`](#help) | Prints help for commands, or the index. |
| [`info`](#info) | Displays runtime info about the bazel server. |
| [`license`](#license) | Prints the license of this software. |
| [`mobile-install`](#mobile-install) | Installs targets to mobile devices. |
| [`mod`](#mod) | Queries the Bzlmod external dependency graph |
| [`print_action`](#print_action) | Prints the command line args for compiling a file. |
| [`query`](#query) | Executes a dependency graph query. |
| [`run`](#run) | Runs the specified target. |
| [`shutdown`](#shutdown) | Stops the bazel server. |
| [`test`](#test) | Builds and runs the specified test targets. |
| [`vendor`](#vendor) | Fetches external repositories into a folder specified by the flag --vendor\_dir. |
| [`version`](#version) | Prints version information for bazel. |
## Startup Options
Options that appear before the command and are parsed by the client
**--\[no]autodetect\_server\_javabase** `boolean` (default: true)
When --noautodetect\_server\_javabase is passed, Bazel does not fall back to the local JDK for running the bazel server and instead exits.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]batch** `boolean` *deprecated* (default: false)
If set, Bazel will be run as just a client process without a server, instead of in the standard client/server mode. This is deprecated and will be removed, please prefer shutting down the server explicitly if you wish to avoid lingering servers.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE), [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION), [`deprecated`](#metadata_tag_DEPRECATED)
**--\[no]batch\_cpu\_scheduling** `boolean` (default: false)
Only on Linux; use 'batch' CPU scheduling for Blaze. This policy is useful for workloads that are non-interactive, but do not want to lower their nice value. See 'man 2 sched\_setscheduler'. If false, then Bazel does not perform a system call.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--bazelrc** `path`
The location of the user .bazelrc file containing default values of Bazel options.
`/dev/null` indicates that all further `--bazelrc`s will be ignored, which is useful to
disable the search for a user rc file, e.g. in release builds.
This option can also be specified multiple times. e.g. with
`--bazelrc=x.rc --bazelrc=y.rc --bazelrc=/dev/null --bazelrc=z.rc`.
* `x.rc` and `y.rc` are read.
* `z.rc` is ignored due to the prior `/dev/null`.
If unspecified, Bazel uses the first `.bazelrc` file it finds in
the following two locations: the workspace directory, then the user's home
directory.
Note: command line options will always supersede any option in bazelrc.
*May be used multiple times; values are accumulated.*
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
**--\[no]block\_for\_lock** `boolean` (default: true)
When --noblock\_for\_lock is passed, Bazel does not wait for a running command to complete, but instead exits immediately. If a duration is specified (e.g. --block\_for\_lock=30s), Bazel will wait up to that duration for the lock before exiting.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--\[no]client\_debug** `boolean` (default: false)
If true, log debug information from the client to stderr. Changing this option will not cause the server to restart.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--connect\_timeout\_secs** `an integer` (default: 30)
The amount of time the client waits for each attempt to connect to the server
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]delete\_output\_base\_on\_shutdown** `boolean` (default: false)
If true, the server will delete its output base directory upon shutting down (whether via explicit shutdown, idle timeout, low memory, or batch mode completion). Only supported on local filesystems; network filesystems (such as NFS) are not supported.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE), [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--digest\_function** `hash function` (default: see description)
The hash function to use when computing file digests.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE), [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--experimental\_cgroup\_parent** `path` (default: see description)
The cgroup where to start the bazel server as an absolute path. The server process will be started in the specified cgroup for each supported controller. For example, if the value of this flag is /build/bazel and the cpu and memory controllers are mounted respectively on /sys/fs/cgroup/cpu and /sys/fs/cgroup/memory, the server will be started in the cgroups /sys/fs/cgroup/cpu/build/bazel and /sys/fs/cgroup/memory/build/bazel.It is not an error if the specified cgroup is not writable for one or more of the controllers. This options does not have any effect on platforms that do not support cgroups.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING), [`execution`](#effect_tag_EXECUTION)
**--\[no]experimental\_run\_in\_user\_cgroup** `boolean` (default: false)
If true, the Bazel server will be run with systemd-run, and the user will own the cgroup. This flag only takes effect on Linux.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING), [`execution`](#effect_tag_EXECUTION)
**--\[no]experimental\_use\_compact\_object\_headers** `boolean` (default: true)
Use compact object headers in the JVM. Enabled by default for Bazel when using the embedded JDK. This can reduce memory usage by 5-7%.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION), [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--extra\_classpath** `a string`
A colon-separated list of classpath entries to be added to the classpath of the Bazel server.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--failure\_detail\_out** `path` (default: see description)
If set, specifies a location to write a failure\_detail protobuf message if the server experiences a failure and cannot report it via gRPC, as normal. Otherwise, the location will be \$\{OUTPUT\_BASE}/failure\_detail.rawproto.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]home\_rc** `boolean` (default: true)
Whether or not to look for the home bazelrc file at `$HOME/.bazelrc`
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
**--\[no]idle\_server\_tasks** `boolean` (default: true)
Run System.gc() when the server is idle
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE), [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--\[no]ignore\_all\_rc\_files** `boolean` (default: false)
Disables all rc files, regardless of the values of other rc-modifying flags, even if these flags come later in the list of startup options.
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
**--io\_nice\_level** `\{-1,0,1,2,3,4,5,6,7\}` (default: -1)
Only on Linux; set a level from 0-7 for best-effort IO scheduling using the sys\_ioprio\_set system call. 0 is highest priority, 7 is lowest. The anticipatory scheduler may only honor up to priority 4. If set to a negative value, then Bazel does not perform a system call.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--local\_startup\_timeout\_secs** `an integer` (default: 120)
The maximum amount of time the client waits to connect to the server
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--macos\_qos\_class** `a string` (default: default)
Sets the QoS service class of the bazel server when running on macOS. This flag has no effect on all other platforms but is supported to ensure rc files can be shared among them without changes. Possible values are: default (leave QoS unchanged), utility, and background. Only utility and background request a macOS process QoS class because Apple's posix\_spawnattr\_set\_qos\_class\_np API does not accept user-interactive or user-initiated for spawned processes.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--max\_idle\_secs** `integer` (default: 10800)
The number of seconds the build server will wait idling before shutting down. Zero means that the server will never shutdown. This is only read on server-startup, changing this option will not cause the server to restart.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--output\_base** `path` (default: see description)
If set, specifies the output location to which all build output will be written. Otherwise, the location will be \$\{OUTPUT\_ROOT}/*blaze*\$\{USER}/\$\{MD5\_OF\_WORKSPACE\_ROOT}. Note: If you specify a different option from one to the next Bazel invocation for this value, you'll likely start up a new, additional Bazel server. Bazel starts exactly one server per specified output base. Typically there is one output base per workspace - however, with this option you may have multiple output bases per workspace and thereby run multiple builds for the same client on the same machine concurrently. See 'bazel help shutdown' on how to shutdown a Bazel server.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--output\_user\_root** `path` (default: see description)
The user-specific directory beneath which all build outputs are written; by default, this is a function of \$USER, but by specifying a constant, build outputs can be shared between collaborating users.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]preemptible** `boolean` (default: false)
If true, the command can be preempted if another command is started.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--\[no]quiet** `boolean` (default: false)
If true, no informational messages are emitted on the console, only errors. Changing this option will not cause the server to restart.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--server\_jvm\_out** `path` (default: see description)
The location to write the server's JVM's output. If unset then defaults to a location in output\_base.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]shutdown\_on\_low\_sys\_mem** `boolean` (default: false)
If max\_idle\_secs is set and the build server has been idle for at least 5 minutes, shut down the server when available system memory falls below critical thresholds. Linux and macOS only.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT), [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]system\_rc** `boolean` (default: true)
Whether or not to look for the system-wide bazelrc.
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
**--\[no]unlimit\_coredumps** `boolean` (default: false)
Raises the soft coredump limit to the hard limit to make coredumps of the server (including the JVM) and the client possible under common conditions. Stick this flag in your bazelrc once and forget about it so that you get coredumps when you actually encounter a condition that triggers them.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]windows\_enable\_symlinks** `boolean` (default: false)
If true, real symbolic links will be created on Windows instead of file copying. Requires Windows developer mode to be enabled and Windows 10 version 1703 or greater.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]workspace\_rc** `boolean` (default: true)
Whether or not to look for the workspace bazelrc file at `$workspace/.bazelrc`
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
Remote caching and execution options
**--\[no]experimental\_remote\_repo\_contents\_cache** `boolean` (default: false)
If enabled, the remote cache will be used to store the results of reproducible repository
rules. If a repository rule needs to be evaluated and its result is already in the remote
cache, the contents of the repository will be kept in an in-memory file system and are
only downloaded when needed, either by Bazel itself or an action that runs locally.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
Miscellaneous options, not otherwise categorized.
**--host\_jvm\_args** `jvm_arg`
Flags to pass to the JVM executing Blaze.
*May be used multiple times; values are accumulated.*
**--host\_jvm\_debug** `void`
Convenience option to add some additional JVM startup flags, which cause the JVM to wait during startup until you connect from a JDWP-compliant debugger (like Eclipse) to port 5005.
Expands to:
* `--host_jvm_args=-agentlib:jdwp=transport=dt_socket,server=y,address=5005`
**--server\_javabase** `jvm path`
Path to the JVM used to execute Bazel itself.
## Options Common to all Commands
Options that appear before the command and are parsed by the client
**--distdir** `a path`
Additional places to search for archives before accessing the network to download them.
*May be used multiple times; values are accumulated.*
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]experimental\_repository\_cache\_hardlinks** `boolean` (default: false)
If set, the repository cache will hardlink the file in case of a cache hit, rather than copying. This is intended to save disk space.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--experimental\_repository\_downloader\_retries** `an integer` (default: 5)
The maximum number of attempts to retry a download error. If set to 0, retries are disabled.
Tags: [`experimental`](#metadata_tag_EXPERIMENTAL)
**--experimental\_scale\_timeouts** `a double` (default: 1.0)
Scale all timeouts in Starlark repository rules by this factor. In this way, external repositories can be made working on machines that are slower than the rule author expected, without changing the source code
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--http\_connector\_attempts** `an integer` (default: 8)
The maximum number of attempts for http downloads.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--http\_connector\_retry\_max\_timeout** `An immutable length of time.` (default: 0s)
The maximum timeout for http download retries. With a value of 0, no timeout maximum is defined.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--http\_max\_parallel\_downloads** `an integer` (default: 8)
The maximum number parallel http downloads.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--http\_timeout\_scaling** `a double` (default: 1.0)
Scale all timeouts related to http downloads by the given factor
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--repo\_contents\_cache** `a path` (default: see description)
Specifies the location of the repo contents cache, which contains fetched repo
directories shareable across workspaces. An empty string as argument requests the repo
contents cache to be disabled, otherwise the default of `{--repository_cache}/contents`
is used. Note that this means setting `--repository_cache=` would by default disable the
repo contents cache as well, unless `--repo_contents_cache={some_path}` is also set.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--repo\_contents\_cache\_gc\_idle\_delay** `An immutable length of time.` (default: 5m)
Specifies the amount of time the server must remain idle before garbage collection happens
to the repo contents cache.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--repo\_contents\_cache\_gc\_max\_age** `An immutable length of time.` (default: 14d)
Specifies the amount of time an entry in the repo contents cache can stay unused before
it's garbage collected. If set to zero, only duplicate entries will be garbage collected.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--repository\_cache** `a path` (default: see description)
Specifies the cache location of the downloaded values obtained
during the fetching of external repositories. An empty string
as argument requests the cache to be disabled,
otherwise the default of `{--output_user_root}/cache/repos/v1` is used.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]repository\_disable\_download** `boolean` (default: false)
If set, downloading using `ctx.download{,_and_extract}` is not allowed during repository
fetching. Note that network access is not completely disabled; ctx.execute could
still run an arbitrary executable that accesses the Internet.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
Options that control build execution
**--experimental\_ui\_max\_stdouterr\_bytes** `an integer in (-1)-1073741819 range` (default: 1048576)
The maximum size of the stdout / stderr files that will be printed to the console. -1 implies no limit.
Tags: [`execution`](#effect_tag_EXECUTION)
**--gc\_churning\_threshold** `an integer in 0-100 range` (default: 100)
At any point after an invocation has been running for at least one minute, if Blaze has spent at least this percentage of the invocation's wall time doing full GCs, Blaze will give up and fail with an OOM. A value of 100 effectively means to never give up for this reason.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--gc\_churning\_threshold\_if\_multiple\_top\_level\_targets** `an integer` (default: -1)
If set to a value in \[0, 100] and this is a command that takes top-level targets (e.g. build but not query) and there are multiple such top-level targets, overrides --gc\_churning\_threshold. Useful to configure more aggressive OOMing behavior (i.e. a lower value than --gc\_churning\_threshold) when they are multiple top-level targets so that the invoker of Bazel can split and retry while still having less aggressive behavior when there is a single top-level target.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--gc\_thrashing\_threshold** `an integer in 0-100 range` (default: 100)
The percent of tenured space occupied (0-100) above which GcThrashingDetector considers memory pressure events against its limits (--gc\_thrashing\_limits). If set to 100, GcThrashingDetector is disabled.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
Options that configure the toolchain used for action execution
**--\[no]incompatible\_enable\_proto\_toolchain\_resolution** `boolean` (default: true)
If true, proto lang rules define toolchains from protobuf repository.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
Options that let the user configure the intended output, affecting its value, as opposed to its existence
**--bep\_maximum\_open\_remote\_upload\_files** `an integer` (default: -1)
Maximum number of open files allowed during BEP artifact upload.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]experimental\_strict\_repo\_env** `boolean` (default: false)
If true, repository rules and module extensions will only inherit `PATH`, `PATHEXT`
(on Windows), and environment variables explicitly specified by `--repo_env`.
Note that unless `--incompatible_repo_env_ignores_action_env` is true,
`--action_env=NAME=VALUE` will also be included.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]incompatible\_repo\_env\_ignores\_action\_env** `boolean` (default: true)
If true, `--action_env=NAME=VALUE` will no longer affect repository rule and module extension environments.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--remote\_download\_all** `void`
Downloads all remote outputs to the local machine. This flag is an alias for --remote\_download\_outputs=all.
Expands to:
* `--remote_download_outputs=all`
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--remote\_download\_minimal** `void`
Does not download any remote build outputs to the local machine. This flag is an alias for --remote\_download\_outputs=minimal.
Expands to:
* `--remote_download_outputs=minimal`
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--remote\_download\_outputs** `all, minimal or toplevel` (default: toplevel)
If set to 'minimal' doesn't download any remote build outputs to the local machine, except the ones required by local actions. If set to 'toplevel' behaves like 'minimal' except that it also downloads outputs of top level targets to the local machine. Both options can significantly reduce build times if network bandwidth is a bottleneck.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--remote\_download\_symlink\_template** `a string`
Instead of downloading remote build outputs to the local machine, create symbolic links. The target of the symbolic links can be specified in the form of a template string. This template string may contain \{hash} and \{size\_bytes} that expand to the hash of the object and the size in bytes, respectively. These symbolic links may, for example, point to a FUSE file system that loads objects from the CAS on demand.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--remote\_download\_toplevel** `void`
Only downloads remote outputs of top level targets to the local machine. This flag is an alias for --remote\_download\_outputs=toplevel.
Expands to:
* `--remote_download_outputs=toplevel`
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--repo\_env** `a 'name[=value]' assignment with an optional value part or the special syntax '=name' to unset a variable`
Specifies additional environment variables to be available only for repository rules. Note that repository rules see the full environment anyway, but in this way variables can be set via command-line flags and `.bazelrc` entries. The special syntax `=NAME` can be used to explicitly unset a variable. The string `%bazel_workspace%` in a value will be replaced with the absolute path of the workspace as printed by `bazel info workspace`.
*May be used multiple times; values are accumulated.*
Tags: [`action_command_lines`](#effect_tag_ACTION_COMMAND_LINES)
Options that affect how strictly Bazel enforces valid build inputs (rule definitions, flag combinations, etc.)
**--\[no]allow\_experimental\_loads** `boolean` (default: false)
If enabled, issue only a warning instead of an error for loads of experimental .bzls.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--\[no]check\_bzl\_visibility** `boolean` (default: true)
If disabled, .bzl load visibility errors are demoted to warnings.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--\[no]incompatible\_enforce\_starlark\_utf8** `boolean` (default: warning)
If enabled (or set to 'error'), fail if Starlark files are not UTF-8 encoded. If set to 'warning', emit a warning instead. If set to 'off', Bazel assumes that Starlark files are UTF-8 encoded but does not verify this assumption. Note that Starlark files which are not UTF-8 encoded can cause Bazel to behave inconsistently.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
This option affects semantics of the Starlark language or the build API accessible to BUILD files, .bzl files, or WORKSPACE files.
**--bzl\_file\_size\_limit\_allowlist** `a build target label ending with .allowlist.scl`
A label to a .allowlist.scl file defining an ALLOWED dict of .bzl/.scl file paths exempt from file size limits. Keys are paths relative to the repository root, e.g. "pkg/foo.bzl" for the main repository or "@@repo//pkg/foo.bzl" for other repositories.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--\[no]experimental\_bzl\_visibility** `boolean` (default: true)
If enabled, adds a `visibility()` function that .bzl files may call during top-level evaluation to set their visibility for the purpose of load() statements.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_cc\_shared\_library** `boolean` (default: false)
If set to true, rule attributes and Starlark API methods needed for the rule cc\_shared\_library will be available
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_dormant\_deps** `boolean` (default: false)
If set to true, attr.label(materializer=), attr(for\_dependency\_resolution=), attr.dormant\_label(), attr.dormant\_label\_list() and rule(for\_dependency\_resolution=) are allowed.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_enable\_android\_migration\_apis** `boolean` (default: false)
If set to true, enables the APIs required to support the Android Starlark migration.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--\[no]experimental\_enable\_first\_class\_macros** `boolean` (default: true)
If set to true, enables the `macro()` construct for defining symbolic macros.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--\[no]experimental\_enable\_starlark\_set** `boolean` (default: true)
If true, enable the set data type and set() constructor in Starlark.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_google\_legacy\_api** `boolean` (default: false)
If set to true, exposes a number of experimental pieces of Starlark build API pertaining to Google legacy code.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_isolated\_extension\_usages** `boolean` (default: false)
If true, enables the `isolate` parameter in the `use_extension` function.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--\[no]experimental\_platforms\_api** `boolean` (default: false)
If set to true, enables a number of platform-related Starlark APIs useful for debugging.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_repo\_remote\_exec** `boolean` (default: false)
If set to true, repository\_rule gains some remote execution capabilities.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_repository\_ctx\_execute\_wasm** `boolean` (default: false)
If true enables the repository\_ctx `load_wasm` and `execute_wasm` methods.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_repository\_ctx\_wasm\_compilation** `boolean` (default: false)
If true enables compilation of WebAssembly modules.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_single\_package\_toolchain\_binding** `boolean` (default: false)
If enabled, the register\_toolchain function may not include target patterns which may refer to more than one package.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]experimental\_starlark\_dynamic\_type\_checking** `boolean` (default: false)
Enables dynamic type checking of arguments and return values for functions that contain type annotations or related syntax.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_starlark\_static\_type\_checking** `boolean` (default: false)
Enables static type checking in files and functions that contain type annotations or related syntax.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--experimental\_starlark\_type\_checking** `void`
Enables both static and dynamic type checking in files and functions that contain type annotations or related syntax. This is an expansion flag for --experimental\_starlark\_static\_type\_checking and --experimental\_starlark\_dynamic\_type\_checking. (When both flags are disabled, Bazel is more forgiving of invalid types in type annotations.)
Expands to:
* `--experimental_starlark_static_type_checking`
* `--experimental_starlark_dynamic_type_checking`
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]experimental\_starlark\_type\_syntax** `boolean` (default: true)
Enables type annotations and related syntax in .bzl files. Locations of files where these are allowed is further restricted by `--experimental_starlark_types_allowed_paths`.
Type syntax is never permitted in .scl files regardless of this flag.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--experimental\_starlark\_types\_allowed\_paths** `comma-separated list of options`
List of canonical Label prefixes under which Starlark type annotations are allowed.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]force\_starlark\_stack\_trace** `boolean` (default: false)
If --force\_starlark\_stack\_trace=true, Starlark stace traces will always be printed from calls to fail(), including those normally supressed with fail(..., stack\_trace = False)
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--\[no]incompatible\_allow\_tags\_propagation** `boolean` (default: true)
If set to true, tags will be propagated from a target to the actions' execution requirements; otherwise tags are not propagated. See [https://github.com/bazelbuild/bazel/issues/8830](https://github.com/bazelbuild/bazel/issues/8830) for details.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`experimental`](#metadata_tag_EXPERIMENTAL)
**--\[no]incompatible\_always\_check\_depset\_elements** `boolean` (default: true)
Check the validity of elements added to depsets, in all constructors. Elements must be immutable, but historically the depset(direct=...) constructor forgot to check. Use tuples instead of lists in depset elements. See [https://github.com/bazelbuild/bazel/issues/10313](https://github.com/bazelbuild/bazel/issues/10313) for details.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_check\_external\_repo\_source\_dir\_package\_boundary** `boolean` (default: false)
If true, a source directory in an external repository fails the build if it crosses a package boundary into a sub-package, matching the behavior that already applies to source directories in the main repository. If false, such package boundary crossings inside external repositories are not detected.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_disable\_objc\_library\_transition** `boolean` (default: true)
Disable objc\_library's custom transition and inherit from the top level target instead (No-op in Bazel)
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_disable\_starlark\_host\_transitions** `boolean` (default: false)
If set to true, rule attributes cannot set 'cfg = "host"'. Rules should set 'cfg = "exec"' instead.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_disable\_target\_default\_provider\_fields** `boolean` (default: false)
If set to true, disable the ability to utilize the default provider via field syntax. Use provider-key syntax instead. For example, instead of using `ctx.attr.dep.files` to access `files`, utilize \`ctx.attr.dep\[DefaultInfo].files See [https://github.com/bazelbuild/bazel/issues/9014](https://github.com/bazelbuild/bazel/issues/9014) for details.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--incompatible\_disable\_transitions\_on** `comma-separated set of options`
A comma-separated list of flags that cannot be used in transitions inputs or outputs.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE), [`non_configurable`](#metadata_tag_NON_CONFIGURABLE)
**--\[no]incompatible\_disallow\_ctx\_resolve\_tools** `boolean` (default: true)
If set to true, calling the deprecated ctx.resolve\_tools API always fails. Uses of this API should be replaced by an executable or tools argument to ctx.actions.run or ctx.actions.run\_shell.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_disallow\_empty\_glob** `boolean` (default: true)
If set to true, the default value of the `allow_empty` argument of glob() is False.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_enable\_deprecated\_label\_apis** `boolean` (default: true)
If enabled, certain deprecated APIs (native.repository\_name, Label.workspace\_name, Label.workspace\_root, Label.relative) can be used.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--\[no]incompatible\_fail\_on\_unknown\_attributes** `boolean` (default: true)
If enabled, targets that have unknown attributes set to None fail.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_fix\_package\_group\_reporoot\_syntax** `boolean` (default: true)
In package\_group's `packages` attribute, changes the meaning of the value "//..." to refer to all packages in the current repository instead of all packages in any repository. You can use the special value "public" in place of "//..." to obtain the old behavior. This flag requires that --incompatible\_package\_group\_has\_public\_syntax also be enabled.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_locations\_prefers\_executable** `boolean` (default: true)
Whether a target that provides an executable expands to the executable rather than the files in `DefaultInfo.files` under \$(locations ...) expansion if the number of files is not 1.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_no\_attr\_license** `boolean` (default: true)
If set to true, disables the function `attr.license`.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_no\_implicit\_file\_export** `boolean` (default: true)
If set, (used) source files are package private unless exported explicitly. See [https://github.com/bazelbuild/proposals/blob/master/designs/2019-10-24-file-visibility.md](https://github.com/bazelbuild/proposals/blob/master/designs/2019-10-24-file-visibility.md)
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_no\_rule\_outputs\_param** `boolean` (default: false)
If set to true, disables the `outputs` parameter of the `rule()` Starlark function.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_package\_group\_has\_public\_syntax** `boolean` (default: true)
In package\_group's `packages` attribute, allows writing "public" or "private" to refer to all packages or no packages respectively.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_require\_matching\_aspect\_hints\_providers** `boolean` (default: false)
If set to true, targets in the aspect\_hints attribute must satisfy the providers required by at least one aspect's required\_aspect\_hints\_providers. That is, for each target C in a target P's aspect\_hints attribute, C will be made a dependency of P only if there is at least one aspect A being applied to P where C's rule class declares providers that satifies A's required\_aspect\_hints\_providers.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_require\_mnemonic\_for\_run\_actions** `boolean` (default: false)
If set to true, ctx.actions.run and ctx.actions.run\_shell will require an explicit mnemonic.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_resolve\_select\_keys\_eagerly** `boolean` (default: false)
If enabled, string keys in dicts passed to select() in .bzl files are immediately resolved to Labels relative to the file instead of being interpreted relative to the BUILD file they are ultimately loaded from.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_run\_shell\_command\_string** `boolean` (default: true)
If set to true, the command parameter of actions.run\_shell will only accept string
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_simplify\_unconditional\_selects\_in\_rule\_attrs** `boolean` (default: true)
If true, simplify configurable rule attributes which contain only unconditional selects; for example, if \["a"] + select("//conditions:default", \["b"]) is assigned to a rule attribute, it is stored as \["a", "b"]. This option does not affect attributes of symbolic macros or attribute default values.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_stop\_exporting\_build\_file\_path** `boolean` (default: false)
If set to true, deprecated ctx.build\_file\_path will not be available. ctx.label.package + '/BUILD' can be used instead.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_symbolic\_macro\_strict\_attrs** `boolean` (default: false)
If enabled, invalid attribute values in symbolic macros are treated as an error and fail the build, matching the behavior of rules.
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--\[no]incompatible\_unambiguous\_label\_stringification** `boolean` (default: true)
When true, Bazel will stringify the label @//foo:bar to @//foo:bar, instead of //foo:bar. This only affects the behavior of str(), the % operator, and so on; the behavior of repr() is unchanged. See [https://github.com/bazelbuild/bazel/issues/15916](https://github.com/bazelbuild/bazel/issues/15916) for more information.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--max\_bzl\_file\_size** `a long integer` (default: 0)
The hard maximum size in bytes allowed for an individual .bzl or .scl file. Files exceeding this size fail compilation unless on --bzl\_file\_size\_limit\_allowlist (zero means no limit).
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--max\_computation\_steps** `a long integer` (default: 0)
The maximum number of Starlark computation steps that may be executed by a BUILD file (zero means no limit).
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
**--nested\_set\_count\_limit** `an integer` (default: 0)
The maximum number of newly constructed non-empty nested sets (also known as depsets) that may be created during the analysis of a single target or aspect (values \<= 0 mean no limit). The count includes nested sets created internally by Bazel (e.g. for actions, runfiles and providers), not only Starlark depset() calls.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--nested\_set\_count\_limit\_allowlist** `comma-separated list of options`
Package specifications (e.g. //foo/bar for a single package, //foo/... for a subtree) exempt from --nested\_set\_count\_limit. Exempt are targets in these packages, aspects applied to those targets, and Starlark aspects defined in these packages.
*May be used multiple times; values are accumulated.*
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--nested\_set\_depth\_limit** `an integer` (default: 3500)
The maximum depth of the graph internal to a depset (also known as NestedSet), above which the depset() constructor will fail.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--soft\_max\_bzl\_file\_size** `a long integer` (default: 0)
The soft maximum size in bytes for an individual .bzl or .scl file. Files exceeding this size fail compilation unless they define \_KNOWN\_OVERSIZED\_BZL\_FILE at the top level or are on --bzl\_file\_size\_limit\_allowlist (zero means no limit).
Tags: [`build_file_semantics`](#effect_tag_BUILD_FILE_SEMANTICS)
Options relating to Bzlmod output and semantics
**--allow\_yanked\_versions** `a string`
Specified the module versions in the form of
`{module1}@{version1},module2@{version2}` that will be allowed in the resolved
dependency graph even if they are declared yanked in the registry where they come
from (if they are not coming from a `NonRegistryOverride`).
Otherwise, yanked versions will cause the resolution to fail. You can also define allowed
yanked versions with the `BZLMOD_ALLOW_YANKED_VERSIONS` environment variable. You can
disable this check by using the keyword `all` (not recommended).
*May be used multiple times; values are accumulated.*
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--check\_bazel\_compatibility** `error, warning or off` (default: error)
Check bazel version compatibility of Bazel modules. Valid values are `error` to escalate it to a resolution failure, `off` to disable the check, or `warning` to print a warning when mismatch detected.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--check\_direct\_dependencies** `off, warning or error` (default: warning)
Check if the direct `bazel_dep` dependencies declared in the root module are the same versions you get in the resolved dependency graph. Valid values are `off` to disable the check, `warning` to print a warning when mismatch detected or `error` to escalate it to a resolution failure.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--\[no]ignore\_dev\_dependency** `boolean` (default: false)
If true, Bazel ignores `bazel_dep`, `use_extension`, and `include` declared as
`dev_dependency` in the `MODULE.bazel` of the root module. Note that these dev
dependencies are always ignored in the `MODULE.bazel` if it is not the root module,
regardless of the value of this flag.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--\[no]incompatible\_require\_repo\_extension\_metadata** `boolean` (default: false)
Require repository rules and module extensions to return explicit metadata. Valid values are `false` to disable the check, `all` to require metadata everywhere, or `root` to require metadata only for repo rules and extensions defined in the root module.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS), [`incompatible_change`](#metadata_tag_INCOMPATIBLE_CHANGE)
**--inject\_module** `an equals-separated mapping of module name to path`
Adds a new module with a local path in the form of `{module name}={path}`. This is
equivalent to adding a `bazel_dep` on the module (with a repository name equal to the
module name) together with a corresponding `local_path_override` to the root module's
`MODULE.bazel` file, except that the override still applies when `--ignore_dev_dependency`
is set (overrides in `MODULE.bazel` are normally ignored in that case). If the given path
is an absolute path, it will be used as it is. If the given path is a relative path, it is
relative to the current working directory. If the given path starts with `%workspace%`, it
is relative to the workspace root, which is the output of `bazel info workspace`. If the
given path is empty, then remove any previous injections. Use `--override_module` instead
to override a module that is already in the dependency graph.
*May be used multiple times; values are accumulated.*
**--lockfile\_mode** `off, update, refresh or error` (default: update)
Specifies how and whether or not to use the lockfile. Valid values are `update` to use the lockfile and update it if there are changes, `refresh` to additionally refresh mutable information (yanked versions and previously missing modules) from remote registries from time to time, `error` to use the lockfile but throw an error if needed information is not up-to-date (superfluous entries that the current resolution does not consult are ignored, not reported), or `off` to neither read from or write to the lockfile.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--module\_mirrors** `a '[name=]value1[,..,valueN]' assignment`
Specifies URLs under which the source URLs of Bazel modules can be found, in addition
to and taking precedence over any registry-provided mirror URLs. This flag can be
specified per-registry using the syntax
`--module_mirrors==[,,...]` (e.g.,
`--module_mirrors=https://bcr.bazel.build=https://mirror.example.com`). It can also
be specified as a comma-separated list of mirror URLs that applies to all registries that
don't have an explicit list (e.g., `--module_mirrors=https://mirror1,https://mirror2`).
Set this to an empty value to disable the use of any mirrors not specified by the
registries. Later uses of this flag override earlier ones with the same (or no) registry.
The default set of mirrors may change over time, but all downloads from mirrors are
verified by hashes stored in the registry (and thus pinned by the lockfile).
*May be used multiple times; values are accumulated.*
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--override\_module** `an equals-separated mapping of module name to path`
Override a module with a local path in the form of `{module name}={path}`. If the given
path is an absolute path, it will be used as it is. If the given path is a
relative path, it is relative to the current working directory. If the given path
starts with `%workspace%`, it is relative to the workspace root, which is the
output of `bazel info workspace`. If the given path is empty, then remove any
previous overrides.
*May be used multiple times; values are accumulated.*
**--registry** `a string`
Specifies the registries to use to locate Bazel module dependencies. The order is important: modules will be looked up in earlier registries first, and only fall back to later registries when they're missing from the earlier ones.
*May be used multiple times; values are accumulated.*
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
**--vendor\_dir** `a path` (default: see description)
Specifies the directory that should hold the external repositories in vendor mode, whether for the purpose of fetching them into it or using them while building. The path can be specified as either an absolute path or a path relative to the workspace directory.
Tags: [`loading_and_analysis`](#effect_tag_LOADING_AND_ANALYSIS)
**--watch\_registry** `a string`
Watches a local file:// registry for changes, so that edits to its files are picked up without a shutdown, at the cost of some overhead on every command. The registry must also be passed with --registry, e.g. --registry=file:///path/to/registry --watch\_registry=file:///path/to/registry.
*May be used multiple times; values are accumulated.*
Tags: [`changes_inputs`](#effect_tag_CHANGES_INPUTS)
Options that trigger optimizations of the build time
**--\[no]experimental\_non\_deterministic\_memory\_optimizations** `boolean` (default: true)
Whether to enable memory optimizations that may be non-deterministic with respect to their efficacy. Enable this to use less memory; disable this for more consistent memory measurements
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--gc\_thrashing\_limits** `comma separated pairs of \:\` (default: 1s:2,20s:3,1m:5)
Limits which, if reached, cause GcThrashingDetector to crash Bazel with an OOM. Each limit is specified as \:\ where period is a duration and count is a positive integer. If more than --gc\_thrashing\_threshold percent of tenured space (old gen heap) remains occupied after \ consecutive full GCs within \, an OOM is triggered. Multiple limits can be specified separated by commas.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--\[no]heuristically\_drop\_nodes** `boolean` (default: false)
If true, Bazel will remove FileState and DirectoryListingState nodes after related File and DirectoryListing node is done to save memory. We expect that it is less likely that these nodes will be needed again. If so, the program will re-evaluate them.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--\[no]keep\_state\_after\_build** `boolean` (default: true)
If false, Blaze will discard the inmemory state from this build when the build finishes. Subsequent builds will not have any incrementality with respect to this one.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
**--skyframe\_high\_water\_mark\_full\_gc\_drops\_per\_invocation** `an integer, \>= 0` (default: 10)
Flag for advanced configuration of Bazel's internal Skyframe engine. If Bazel detects its retained heap percentage usage exceeds the threshold set by --skyframe\_high\_water\_mark\_threshold, when a full GC event occurs, it will drop unnecessary temporary Skyframe state, up to this many times per invocation. Defaults to 10. Zero means that full GC events will never trigger drops. If the limit is reached, Skyframe state will no longer be dropped when a full GC event occurs and that retained heap percentage threshold is exceeded.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--skyframe\_high\_water\_mark\_minor\_gc\_drops\_per\_invocation** `an integer, \>= 0` (default: 10)
Flag for advanced configuration of Bazel's internal Skyframe engine. If Bazel detects its retained heap percentage usage exceeds the threshold set by --skyframe\_high\_water\_mark\_threshold, when a minor GC event occurs, it will drop unnecessary temporary Skyframe state, up to this many times per invocation. Defaults to 10. Zero means that minor GC events will never trigger drops. If the limit is reached, Skyframe state will no longer be dropped when a minor GC event occurs and that retained heap percentage threshold is exceeded.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--skyframe\_high\_water\_mark\_threshold** `an integer` (default: 85)
Flag for advanced configuration of Bazel's internal Skyframe engine. If Bazel detects its retained heap percentage usage is at least this threshold, it will drop unnecessary temporary Skyframe state. Tweaking this may let you mitigate wall time impact of GC thrashing, when the GC thrashing is (i) caused by the memory usage of this temporary state and (ii) more costly than reconstituting the state when it is needed.
Tags: [`host_machine_resource_optimizations`](#effect_tag_HOST_MACHINE_RESOURCE_OPTIMIZATIONS)
**--\[no]track\_incremental\_state** `boolean` (default: true)
If false, Bazel will not persist data that allows for invalidation and re-evaluation on incremental builds in order to save memory on this build. Subsequent builds will not have any incrementality with respect to this one. Usually you will want to specify --batch when setting this to false.
Tags: [`loses_incremental_state`](#effect_tag_LOSES_INCREMENTAL_STATE)
Options that affect the verbosity, format or location of logging
**--\[no]announce\_rc** `boolean` (default: false)
Whether to announce rc options.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]attempt\_to\_print\_relative\_paths** `boolean` (default: false)
When printing the location part of messages, attempt to use a path relative to the workspace directory or one of the directories specified by --package\_path.
Tags: [`terminal_output`](#effect_tag_TERMINAL_OUTPUT)
**--bes\_backend** `a string`
Specifies the build event service (BES) backend endpoint in the form
`[SCHEME://]HOST[:PORT]`. The default is to disable BES uploads. Supported schemes
are `grpc` and `grpcs` (grpc with TLS enabled). If no scheme is provided, Bazel
assumes `grpcs`.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]bes\_check\_preceding\_lifecycle\_events** `boolean` (default: false)
Sets the field `check_preceding_lifecycle_events_present` on
`PublishBuildToolEventStreamRequest` which tells BES to check whether it previously
received `InvocationAttemptStarted` and `BuildEnqueued` events matching the current
tool event.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_header** `a 'name=value' assignment`
Specify a header in `NAME=VALUE` form that will be included in BES requests.
Multiple headers can be passed by specifying the flag multiple times. Multiple
values for the same name will be converted to a comma-separated list.
*May be used multiple times; values are accumulated.*
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS), [`fully_redacted_in_logs`](#metadata_tag_FULLY_REDACTED_IN_LOGS)
**--bes\_instance\_name** `a string` (default: see description)
Specifies the instance name under which the BES will persist uploaded BEP. Defaults to null.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_keywords** `comma-separated list of options`
Specifies a list of notification keywords to be added the default set of keywords
published to BES (`command_name={command_name}`, `protocol_name=BEP`).
Defaults to none.
*May be used multiple times; values are accumulated.*
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]bes\_lifecycle\_events** `boolean` (default: true)
Specifies whether to publish BES lifecycle events. (defaults to 'true').
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_oom\_finish\_upload\_timeout** `An immutable length of time.` (default: 10m)
Specifies how long bazel should wait for the BES/BEP upload to complete while OOMing. This flag ensures termination when the JVM is severely GC thrashing and cannot make progress on any user thread.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--bes\_outerr\_buffer\_size** `an integer` (default: 10240)
Specifies the maximal size of stdout or stderr to be buffered in BEP, before it is
reported as a progress event. Individual writes are still reported in a single
event, even if larger than the specified value up to `--bes_outerr_chunk_size`.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_outerr\_chunk\_size** `an integer` (default: 1048576)
Specifies the maximal size of stdout or stderr to be sent to BEP in a single message.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_proxy** `a string` (default: see description)
Connect to the Build Event Service through a proxy. Currently this flag can only be
used to configure a Unix domain socket (`unix:/path/to/socket`).
**--bes\_results\_url** `a string`
Specifies the base URL where a user can view the information streamed to the BES backend. Bazel will output the URL appended by the invocation id to the terminal.
Tags: [`terminal_output`](#effect_tag_TERMINAL_OUTPUT)
**--bes\_system\_keywords** `comma-separated list of options`
Specifies a list of notification keywords to be included directly, without the
`user_keyword=` prefix included for keywords supplied via `--bes_keywords`.
Intended for Build service operators that set `--bes_lifecycle_events=false` and
include keywords when calling `PublishLifecycleEvent`. Build service operators
using this flag should prevent users from overriding the flag value.
*May be used multiple times; values are accumulated.*
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_timeout** `An immutable length of time.` (default: 0s)
Specifies how long bazel should wait for the BES/BEP upload to complete after the
build and tests have finished. A valid timeout is a natural number followed by a
unit: Days (d), hours (h), minutes (m), seconds (s), and milliseconds (ms). The
default value is `0` which means that there is no timeout.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--bes\_upload\_mode** `wait_for_upload_complete, nowait_for_upload_complete or fully_async` (default: wait\_for\_upload\_complete)
Specifies whether the Build Event Service upload should block the build completion or
should end the invocation immediately and finish the upload in the
background.
* `wait_for_upload_complete`: blocks at the end of the current invocation until
all events (including lifecycle events if applicable) are uploaded and
acknowledged by the backend.
* `nowait_for_upload_complete`: blocks at the beginning of the next invocation
until all events (including lifecycle events if applicable) are uploaded and
acknowledged by the backend.
* `fully_async`: blocks at the beginning of the next invocation until all events
are uploaded but does not wait for acknowledgements. Events may be lost in case
of (transient) failures and backends may report streams as incomplete in this
mode. There is no guarantee that `FinishInvocationAttempt` or `FinishBuild`
lifecycle events are sent.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--build\_event\_binary\_file** `a string`
If non-empty, write a varint delimited binary representation of representation of the
build event protocol to that file. This option implies
`--bes_upload_mode=wait_for_upload_complete`.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]build\_event\_binary\_file\_path\_conversion** `boolean` (default: true)
Convert paths in the binary file representation of the build event protocol to more
globally valid URIs whenever possible; if disabled, the `file://` uri scheme will
always be used
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--build\_event\_binary\_file\_upload\_mode** `wait_for_upload_complete, nowait_for_upload_complete or fully_async` (default: wait\_for\_upload\_complete)
Specifies whether the Build Event Service upload for `--build_event_binary_file` should
block the build completion or should end the invocation immediately and finish
the upload in the background. Either `wait_for_upload_complete` (default),
`nowait_for_upload_complete`, or `fully_async`.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--build\_event\_json\_file** `a string`
If non-empty, write a JSON serialisation of the build event protocol to that file.
This option implies `--bes_upload_mode=wait_for_upload_complete`.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]build\_event\_json\_file\_path\_conversion** `boolean` (default: true)
Convert paths in the json file representation of the build event protocol to more
globally valid URIs whenever possible; if disabled, the `file://` uri scheme will
always be used
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--build\_event\_json\_file\_upload\_mode** `wait_for_upload_complete, nowait_for_upload_complete or fully_async` (default: wait\_for\_upload\_complete)
Specifies whether the Build Event Service upload for `--build_event_json_file` should
block the build completion or should end the invocation immediately and finish
the upload in the background. Either `wait_for_upload_complete` (default),
`nowait_for_upload_complete`, or `fully_async`.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--build\_event\_max\_named\_set\_of\_file\_entries** `an integer` (default: 5000)
The maximum number of entries for a single `named_set_of_files` event; values smaller
than 2 are ignored and no event splitting is performed. This is intended for
limiting the maximum event size in the build event protocol, although it does not
directly control event size. The total event size is a function of the structure
of the set as well as the file and uri lengths, which may in turn depend on the
hash function.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]build\_event\_publish\_all\_actions** `boolean` (default: false)
Whether all actions should be published.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--build\_event\_text\_file** `a string`
If non-empty, write a textual representation of the build event protocol to that file
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]build\_event\_text\_file\_path\_conversion** `boolean` (default: true)
Convert paths in the text file representation of the build event protocol to more
globally valid URIs whenever possible; if disabled, the `file://` uri scheme will
always be used
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--build\_event\_text\_file\_upload\_mode** `wait_for_upload_complete, nowait_for_upload_complete or fully_async` (default: wait\_for\_upload\_complete)
Specifies whether the Build Event Service upload for `--build_event_text_file` should
block the build completion or should end the invocation immediately and finish
the upload in the background. Either `wait_for_upload_complete` (default),
`nowait_for_upload_complete`, or `fully_async`.
Tags: [`eagerness_to_exit`](#effect_tag_EAGERNESS_TO_EXIT)
**--build\_event\_upload\_max\_retries** `an integer` (default: 4)
The maximum number of times Bazel should retry uploading a build event.
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--\[no]experimental\_bep\_target\_summary** `boolean` (default: false)
Whether to publish `TargetSummary` events.
**--\[no]experimental\_build\_event\_expand\_filesets** `boolean` (default: false)
No-op.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--experimental\_build\_event\_output\_group\_mode** `an output group name followed by an OutputGroupFileMode, e.g. default=both`
Specify how an output group's files will be represented in `TargetComplete`/`AspectComplete`
BEP events. Values are an assignment of an output group name to one of
`NAMED_SET_OF_FILES_ONLY`, `INLINE_ONLY`, or `BOTH`. The default value is
`NAMED_SET_OF_FILES_ONLY`. If an output group is repeated, the final value to
appear is used. The default value sets the mode for coverage artifacts to BOTH:
`--experimental_build_event_output_group_mode=baseline.lcov=both`
*May be used multiple times; values are accumulated.*
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--experimental\_build\_event\_upload\_retry\_minimum\_delay** `An immutable length of time.` (default: 1s)
Initial, minimum delay for exponential backoff retries when BEP upload fails. (exponent: 1.6)
Tags: [`bazel_internal_configuration`](#effect_tag_BAZEL_INTERNAL_CONFIGURATION)
**--experimental\_build\_event\_upload\_strategy** `a string` (default: see description)
Selects how to upload artifacts referenced in the build event protocol. In Bazel
the valid options include `local` and `remote`. The default value is `local`.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]experimental\_collect\_load\_average\_in\_profiler** `boolean` (default: true)
If enabled, the profiler collects the system's overall load average.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_collect\_pressure\_stall\_indicators** `boolean` (default: false)
If enabled, the profiler collects the Linux PSI data.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_collect\_resource\_estimation** `boolean` (default: false)
If enabled, the profiler collects CPU and memory usage estimation for local actions.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_collect\_skyframe\_counts\_in\_profiler** `boolean` (default: false)
If enabled, the profiler collects SkyFunction counts in the Skyframe graph over time for key function types, like configured targets and action executions. May have a performance hit as this visits the ENTIRE Skyframe graph at every profiling time unit. Do not use this flag with performance-critical measurements.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_collect\_system\_network\_usage** `boolean` (default: true)
If enabled, the profiler collects the system's network usage.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_collect\_worker\_data\_in\_profiler** `boolean` (default: true)
If enabled, the profiler collects worker's aggregated resource data.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--experimental\_command\_profile** `cpu, wall, alloc or lock` (default: see description)
Records a Java Flight Recorder profile for the duration of the command. One of the supported profiling event types (cpu, wall, alloc or lock) must be given as an argument. The profile is written to a file named after the event type under the output base directory. The syntax and semantics of this flag might change in the future to support additional profile types or output formats; use at your own risk.
**--\[no]experimental\_memory\_profile\_await\_bes\_quiescence** `boolean` (default: false)
If set, wait for the Build Event Service event queue to quiesce before taking memory profile measurements at the end of the build. Ignored if --memory\_profile is not set.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--experimental\_profile\_additional\_tasks** `phase, action, discover_inputs, action_check, action_lock, action_update, action_complete, action_rewinding, bzlmod, info, create_package, remote_execution, local_execution, scanner, local_parse, upload_time, remote_process_time, remote_queue, remote_setup, fetch, local_process_time, vfs_stat, vfs_dir, vfs_readlink, vfs_md5, vfs_xattr, vfs_delete, vfs_open, vfs_read, vfs_write, vfs_glob, vfs_vmfs_stat, vfs_vmfs_dir, vfs_vmfs_read, wait, thread_name, thread_sort_index, skyframe_eval, skyfunction, critical_path, critical_path_component, manual_gc, handle_gc_notification, local_action_counts, starlark_parser, starlark_user_fn, starlark_builtin_fn, starlark_user_compiled_fn, starlark_repository_fn, starlark_thread_context, action_fs_staging, remote_cache_check, remote_download, remote_network, filesystem_traversal, worker_execution, worker_setup, worker_borrow, worker_working, worker_copying_outputs, sandbox_setup, sandbox_process_time, sandbox_outputs, credential_helper, conflict_check, dynamic_lock, repository_fetch, repository_vendor, repo_cache_gc_wait, spawn_log, rpc, skycache, wasm_load, wasm_exec or unknown`
Specifies additional profile tasks to be included in the profile.
*May be used multiple times; values are accumulated.*
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_profile\_include\_primary\_output** `boolean` (default: false)
Includes the extra "out" attribute in action and critical-path events that contains the exec path to the action's primary output.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_profile\_include\_target\_configuration** `boolean` (default: false)
Includes target configuration hash in action and critical-path events' JSON profile data.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_profile\_include\_target\_label** `boolean` (default: false)
Includes target label in action and critical-path events' JSON profile data.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]experimental\_record\_metrics\_for\_all\_mnemonics** `boolean` (default: false)
Controls the output of BEP `ActionSummary` and `BuildGraphMetrics`, limiting the
number of mnemonics in `ActionData` and number of entries reported in
`BuildGraphMetrics.AspectCount/RuleClassCount`. By default the number of types is
limited to the top 20, by number of executed actions for `ActionData`, and
instances for `RuleClass` and `Aspect`. Setting this option will write statistics
for all mnemonics, rule classes and aspects.
**--\[no]experimental\_record\_skyframe\_metrics** `boolean` (default: false)
Controls the output of BEP `BuildGraphMetrics`, including expensive
to compute skyframe metrics about `Skykey`s, `RuleClass`es and `Aspect`s.
With this flag set to `false` `BuildGraphMetrics.rule_count` and `aspect`
fields will not be populated in the BEP.
**--\[no]experimental\_run\_bep\_event\_include\_residue** `boolean` (default: false)
Whether to include the command-line residue in run build events which could contain the residue. By default, the residue is not included in run command build events that could contain the residue.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--\[no]experimental\_stream\_log\_file\_uploads** `boolean` (default: false)
Stream log file uploads directly to the remote storage rather than writing them to disk.
Tags: [`affects_outputs`](#effect_tag_AFFECTS_OUTPUTS)
**--experimental\_workspace\_rules\_log\_file** `a path` (default: see description)
Log certain Workspace Rules events into this file as delimited WorkspaceEvent protos.
**--\[no]generate\_json\_trace\_profile** `boolean` (default: auto)
If enabled, Bazel profiles the build and writes a JSON-format profile into a file in the output base. View profile by loading into chrome://tracing. By default Bazel writes the profile for all build-like commands and query.
Tags: [`bazel_monitoring`](#effect_tag_BAZEL_MONITORING)
**--\[no]heap\_dump\_on\_oom** `boolean` (default: false)
Whether to manually output a heap dump if an OOM is thrown (including manual OOMs due to reaching --gc\_thrashing\_limits). The dump will be written to \
--host_jvm_args=-DRULE_MEMORY_TRACKER=1
```
Note: You can download the allocation instrumenter jar file from [Maven Central
Repository][allocation-instrumenter-link].
[allocation-instrumenter-link]: https://repo1.maven.org/maven2/com/google/code/java-allocation-instrumenter/java-allocation-instrumenter/3.3.4
These start the server in memory tracking mode. If you forget these for even
one Bazel invocation the server will restart and you will have to start over.
### Using the Memory Tracker
As an example, look at the target `foo` and see what it does. To only
run the analysis and not run the build execution phase, add the
`--nobuild` flag.
```
$ bazel $(STARTUP_FLAGS) build --nobuild //foo:foo
```
Next, see how much memory the whole Bazel instance consumes:
```
$ bazel $(STARTUP_FLAGS) info used-heap-size-after-gc
> 2594MB
```
Break it down by rule class by using `bazel dump --rules`:
```
$ bazel $(STARTUP_FLAGS) dump --rules
>
RULE COUNT ACTIONS BYTES EACH
genrule 33,762 33,801 291,538,824 8,635
config_setting 25,374 0 24,897,336 981
filegroup 25,369 25,369 97,496,272 3,843
cc_library 5,372 73,235 182,214,456 33,919
proto_library 4,140 110,409 186,776,864 45,115
android_library 2,621 36,921 218,504,848 83,366
java_library 2,371 12,459 38,841,000 16,381
_gen_source 719 2,157 9,195,312 12,789
_check_proto_library_deps 719 668 1,835,288 2,552
... (more output)
```
Look at where the memory is going by producing a `pprof` file
using `bazel dump --skylark_memory`:
```
$ bazel $(STARTUP_FLAGS) dump --skylark_memory=$HOME/prof.gz
> Dumping Starlark heap to: /usr/local/google/home/$USER/prof.gz
```
Use the `pprof` tool to investigate the heap. A good starting point is
getting a flame graph by using `pprof -flame $HOME/prof.gz`.
Get `pprof` from [https://github.com/google/pprof](https://github.com/google/pprof).
Get a text dump of the hottest call sites annotated with lines:
```
$ pprof -text -lines $HOME/prof.gz
>
flat flat% sum% cum cum%
146.11MB 19.64% 19.64% 146.11MB 19.64% android_library :-1
113.02MB 15.19% 34.83% 113.02MB 15.19% genrule :-1
74.11MB 9.96% 44.80% 74.11MB 9.96% glob :-1
55.98MB 7.53% 52.32% 55.98MB 7.53% filegroup :-1
53.44MB 7.18% 59.51% 53.44MB 7.18% sh_test :-1
26.55MB 3.57% 63.07% 26.55MB 3.57% _generate_foo_files /foo/tc/tc.bzl:491
26.01MB 3.50% 66.57% 26.01MB 3.50% _build_foo_impl /foo/build_test.bzl:78
22.01MB 2.96% 69.53% 22.01MB 2.96% _build_foo_impl /foo/build_test.bzl:73
... (more output)
```
# Rules Tutorial
Source: https://bazel.build/rules/rules-tutorial
[Starlark](https://github.com/bazelbuild/starlark) is a Python-like
configuration language originally developed for use in Bazel and since adopted
by other tools. Bazel's `BUILD` and `.bzl` files are written in a dialect of
Starlark properly known as the "Build Language", though it is often simply
referred to as "Starlark", especially when emphasizing that a feature is
expressed in the Build Language as opposed to being a built-in or "native" part
of Bazel. Bazel augments the core language with numerous build-related functions
such as `glob`, `genrule`, `java_binary`, and so on.
See the
[Bazel](/start/) and [Starlark](/extending/concepts) documentation for
more details, and the
[Rules SIG template](https://github.com/bazel-contrib/rules-template) as a
starting point for new rulesets.
## The empty rule
To create your first rule, create the file `foo.bzl`:
```python theme={null}
def _foo_binary_impl(ctx):
pass
foo_binary = rule(
implementation = _foo_binary_impl,
)
```
When you call the [`rule`](/rules/lib/globals/bzl#rule) function, you
must define a callback function. The logic will go there, but you
can leave the function empty for now. The [`ctx`](/rules/lib/builtins/ctx) argument
provides information about the target.
You can load the rule and use it from a `BUILD` file.
Create a `BUILD` file in the same directory:
```python theme={null}
load(":foo.bzl", "foo_binary")
foo_binary(name = "bin")
```
Now, the target can be built:
```
$ bazel build bin
INFO: Analyzed target //:bin (2 packages loaded, 17 targets configured).
INFO: Found 1 target...
Target //:bin up-to-date (nothing to build)
```
Even though the rule does nothing, it already behaves like other rules: it has a
mandatory name, it supports common attributes like `visibility`, `testonly`, and
`tags`.
## Evaluation model
Before going further, it's important to understand how the code is evaluated.
Update `foo.bzl` with some print statements:
```python theme={null}
def _foo_binary_impl(ctx):
print("analyzing", ctx.label)
foo_binary = rule(
implementation = _foo_binary_impl,
)
print("bzl file evaluation")
```
and BUILD:
```python theme={null}
load(":foo.bzl", "foo_binary")
print("BUILD file")
foo_binary(name = "bin1")
foo_binary(name = "bin2")
```
[`ctx.label`](/rules/lib/builtins/ctx#label)
corresponds to the label of the target being analyzed. The `ctx` object has
many useful fields and methods; you can find an exhaustive list in the
[API reference](/rules/lib/builtins/ctx).
Query the code:
```
$ bazel query :all
DEBUG: /usr/home/bazel-codelab/foo.bzl:8:1: bzl file evaluation
DEBUG: /usr/home/bazel-codelab/BUILD:2:1: BUILD file
//:bin2
//:bin1
```
Make a few observations:
* "bzl file evaluation" is printed first. Before evaluating the `BUILD` file,
Bazel evaluates all the files it loads. If multiple `BUILD` files are loading
foo.bzl, you would see only one occurrence of "bzl file evaluation" because
Bazel caches the result of the evaluation.
* The callback function `_foo_binary_impl` is not called. Bazel query loads
`BUILD` files, but doesn't analyze targets.
To analyze the targets, use the [`cquery`](/query/cquery) ("configured
query") or the `build` command:
```
$ bazel build :all
DEBUG: /usr/home/bazel-codelab/foo.bzl:2:5: analyzing //:bin1
DEBUG: /usr/home/bazel-codelab/foo.bzl:2:5: analyzing //:bin2
INFO: Analyzed 2 targets (0 packages loaded, 0 targets configured).
INFO: Found 2 targets...
```
As you can see, `_foo_binary_impl` is now called twice - once for each target.
Notice that neither "bzl file evaluation" nor "BUILD file" are printed again,
because the evaluation of `foo.bzl` is cached after the call to `bazel query`.
Bazel only emits `print` statements when they are actually executed.
## Creating a file
To make your rule more useful, update it to generate a file. First, declare the
file and give it a name. In this example, create a file with the same name as
the target:
```python theme={null}
ctx.actions.declare_file(ctx.label.name)
```
If you run `bazel build :all` now, you will get an error:
```
The following files have no generating action:
bin2
```
Whenever you declare a file, you have to tell Bazel how to generate it by
creating an [action](/extending/rules#actions). Use [`ctx.actions.write`](/rules/lib/builtins/actions#write),
to create a file with the given content.
```python theme={null}
def _foo_binary_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name)
ctx.actions.write(
output = out,
content = "Hello\n",
)
```
The code is valid, but it won't do anything:
```
$ bazel build bin1
Target //:bin1 up-to-date (nothing to build)
```
The `ctx.actions.write` function registered an action, which taught Bazel
how to generate the file. But Bazel won't create the file until it is
actually requested. So the last thing to do is tell Bazel that the file
is an output of the rule, and not a temporary file used within the rule
implementation.
```python theme={null}
def _foo_binary_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name)
ctx.actions.write(
output = out,
content = "Hello!\n",
)
return [DefaultInfo(files = depset([out]))]
```
Look at the `DefaultInfo` and `depset` functions later. For now,
assume that the last line is the way to choose the outputs of a rule.
Now, run Bazel:
```
$ bazel build bin1
INFO: Found 1 target...
Target //:bin1 up-to-date:
bazel-bin/bin1
$ cat bazel-bin/bin1
Hello!
```
You have successfully generated a file!
## Attributes
To make the rule more useful, add new attributes using
[the `attr` module](/rules/lib/toplevel/attr) and update the rule definition.
Add a string attribute called `username`:
```python theme={null}
foo_binary = rule(
implementation = _foo_binary_impl,
attrs = {
"username": attr.string(),
},
)
```
Next, set it in the `BUILD` file:
```python theme={null}
foo_binary(
name = "bin",
username = "Alice",
)
```
To access the value in the callback function, use `ctx.attr.username`. For
example:
```python theme={null}
def _foo_binary_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name)
ctx.actions.write(
output = out,
content = "Hello {}!\n".format(ctx.attr.username),
)
return [DefaultInfo(files = depset([out]))]
```
Note that you can make the attribute mandatory or set a default value. Look at
the documentation of [`attr.string`](/rules/lib/toplevel/attr#string).
You may also use other types of attributes, such as [boolean](/rules/lib/toplevel/attr#bool)
or [list of integers](/rules/lib/toplevel/attr#int_list).
## Dependencies
Dependency attributes, such as [`attr.label`](/rules/lib/toplevel/attr#label)
and [`attr.label_list`](/rules/lib/toplevel/attr#label_list),
declare a dependency from the target that owns the attribute to the target whose
label appears in the attribute's value. This kind of attribute forms the basis
of the target graph.
In the `BUILD` file, the target label appears as a string object, such as
`//pkg:name`. In the implementation function, the target will be accessible as a
[`Target`](/rules/lib/builtins/Target) object. For example, view the files returned
by the target using [`Target.files`](/rules/lib/builtins/Target#modules.Target.files).
### Multiple files
By default, only targets created by rules may appear as dependencies (such as a
`foo_library()` target). If you want the attribute to accept targets that are
input files (such as source files in the repository), you can do it with
`allow_files` and specify the list of accepted file extensions (or `True` to
allow any file extension):
```python theme={null}
"srcs": attr.label_list(allow_files = [".java"]),
```
The list of files can be accessed with `ctx.files.`. For
example, the list of files in the `srcs` attribute can be accessed through
```python theme={null}
ctx.files.srcs
```
### Single file
If you need only one file, use `allow_single_file`:
```python theme={null}
"src": attr.label(allow_single_file = [".java"])
```
This file is then accessible under `ctx.file.`:
```python theme={null}
ctx.file.src
```
## Create a file with a template
You can create a rule that generates a .cc file based on a template. Also, you
can use `ctx.actions.write` to output a string constructed in the rule
implementation function, but this has two problems. First, as the template gets
bigger, it becomes more memory efficient to put it in a separate file and avoid
constructing large strings during the analysis phase. Second, using a separate
file is more convenient for the user. Instead, use
[`ctx.actions.expand_template`](/rules/lib/builtins/actions#expand_template),
which performs substitutions on a template file.
Create a `template` attribute to declare a dependency on the template
file:
```python theme={null}
def _hello_world_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name + ".cc")
ctx.actions.expand_template(
output = out,
template = ctx.file.template,
substitutions = {"{NAME}": ctx.attr.username},
)
return [DefaultInfo(files = depset([out]))]
hello_world = rule(
implementation = _hello_world_impl,
attrs = {
"username": attr.string(default = "unknown person"),
"template": attr.label(
allow_single_file = [".cc.tpl"],
mandatory = True,
),
},
)
```
Users can use the rule like this:
```python theme={null}
hello_world(
name = "hello",
username = "Alice",
template = "file.cc.tpl",
)
cc_binary(
name = "hello_bin",
srcs = [":hello"],
)
```
If you don't want to expose the template to the end-user and always use the
same one, you can set a default value and make the attribute private:
```python theme={null}
"_template": attr.label(
allow_single_file = True,
default = "file.cc.tpl",
),
```
Attributes that start with an underscore are private and cannot be set in a
`BUILD` file. The template is now an *implicit dependency*: Every `hello_world`
target has a dependency on this file. Don't forget to make this file visible
to other packages by updating the `BUILD` file and using
[`exports_files`](/reference/be/functions#exports_files):
```python theme={null}
exports_files(["file.cc.tpl"])
```
## Going further
* Take a look at the [reference documentation for rules](/extending/rules#contents).
* Get familiar with [depsets](/extending/depsets).
* Check out the [examples repository](https://github.com/bazelbuild/examples/tree/master/rules)
which includes additional examples of rules.
# Testing
Source: https://bazel.build/rules/testing
There are several different approaches to testing Starlark code in Bazel. This
page gathers the current best practices and frameworks by use case.
## Testing rules
[Skylib](https://github.com/bazelbuild/bazel-skylib) has a test framework called
[`unittest.bzl`](https://github.com/bazelbuild/bazel-skylib/blob/main/lib/unittest.bzl)
for checking the analysis-time behavior of rules, such as their actions and
providers. Such tests are called "analysis tests" and are currently the best
option for testing the inner workings of rules.
Some caveats:
* Test assertions occur within the build, not a separate test runner process.
Targets that are created by the test must be named such that they do not
collide with targets from other tests or from the build. An error that
occurs during the test is seen by Bazel as a build breakage rather than a
test failure.
* It requires a fair amount of boilerplate to set up the rules under test and
the rules containing test assertions. This boilerplate may seem daunting at
first. It helps to [keep in mind](/extending/concepts#evaluation-model) that macros
are evaluated and targets generated during the loading phase, while rule
implementation functions don't run until later, during the analysis phase.
* Analysis tests are intended to be fairly small and lightweight. Certain
features of the analysis testing framework are restricted to verifying
targets with a maximum number of transitive dependencies (currently 500).
This is due to performance implications of using these features with larger
tests.
The basic principle is to define a testing rule that depends on the
rule-under-test. This gives the testing rule access to the rule-under-test's
providers.
The testing rule's implementation function carries out assertions. If there are
any failures, these are not raised immediately by calling `fail()` (which would
trigger an analysis-time build error), but rather by storing the errors in a
generated script that fails at test execution time.
See below for a minimal toy example, followed by an example that checks actions.
### Minimal example
`//mypkg/myrules.bzl`:
```python theme={null}
MyInfo = provider(fields = {
"val": "string value",
"out": "output File",
})
def _myrule_impl(ctx):
"""Rule that just generates a file and returns a provider."""
out = ctx.actions.declare_file(ctx.label.name + ".out")
ctx.actions.write(out, "abc")
return [MyInfo(val="some value", out=out)]
myrule = rule(
implementation = _myrule_impl,
)
```
`//mypkg/myrules_test.bzl`:
```python theme={null}
load("@bazel_skylib//lib:unittest.bzl", "asserts", "analysistest")
load(":myrules.bzl", "myrule", "MyInfo")
# ==== Check the provider contents ====
def _provider_contents_test_impl(ctx):
env = analysistest.begin(ctx)
target_under_test = analysistest.target_under_test(env)
# If preferred, could pass these values as "expected" and "actual" keyword
# arguments.
asserts.equals(env, "some value", target_under_test[MyInfo].val)
# If you forget to return end(), you will get an error about an analysis
# test needing to return an instance of AnalysisTestResultInfo.
return analysistest.end(env)
# Create the testing rule to wrap the test logic. This must be bound to a global
# variable, not called in a macro's body, since macros get evaluated at loading
# time but the rule gets evaluated later, at analysis time. Since this is a test
# rule, its name must end with "_test".
provider_contents_test = analysistest.make(_provider_contents_test_impl)
# Macro to setup the test.
def _test_provider_contents():
# Rule under test. Be sure to tag 'manual', as this target should not be
# built using `:all` except as a dependency of the test.
myrule(name = "provider_contents_subject", tags = ["manual"])
# Testing rule.
provider_contents_test(name = "provider_contents_test",
target_under_test = ":provider_contents_subject")
# Note the target_under_test attribute is how the test rule depends on
# the real rule target.
# Entry point from the BUILD file; macro for running each test case's macro and
# declaring a test suite that wraps them together.
def myrules_test_suite(name):
# Call all test functions and wrap their targets in a suite.
_test_provider_contents()
# ...
native.test_suite(
name = name,
tests = [
":provider_contents_test",
# ...
],
)
```
`//mypkg/BUILD`:
```python theme={null}
load(":myrules.bzl", "myrule")
load(":myrules_test.bzl", "myrules_test_suite")
# Production use of the rule.
myrule(
name = "mytarget",
)
# Call a macro that defines targets that perform the tests at analysis time,
# and that can be executed with "bazel test" to return the result.
myrules_test_suite(name = "myrules_test")
```
The test can be run with `bazel test //mypkg:myrules_test`.
Aside from the initial `load()` statements, there are two main parts to the
file:
* The tests themselves, each of which consists of 1) an analysis-time
implementation function for the testing rule, 2) a declaration of the
testing rule via `analysistest.make()`, and 3) a loading-time function
(macro) for declaring the rule-under-test (and its dependencies) and testing
rule. If the assertions do not change between test cases, 1) and 2) may be
shared by multiple test cases.
* The test suite function, which calls the loading-time functions for each
test, and declares a `test_suite` target bundling all tests together.
For consistency, follow the recommended naming convention: Let `foo` stand for
the part of the test name that describes what the test is checking
(`provider_contents` in the above example). For example, a JUnit test method
would be named `testFoo`.
Then:
* the macro which generates the test and target under test should be
named `_test_foo` (`_test_provider_contents`)
* its test rule type should be named `foo_test` (`provider_contents_test`)
* the label of the target of this rule type should be `foo_test`
(`provider_contents_test`)
* the implementation function for the testing rule should be named
`_foo_test_impl` (`_provider_contents_test_impl`)
* the labels of the targets of the rules under test and their dependencies
should be prefixed with `foo_` (`provider_contents_`)
Note that the labels of all targets can conflict with other labels in the same
BUILD package, so it's helpful to use a unique name for the test.
### Failure testing
It may be useful to verify that a rule fails given certain inputs or in certain
state. This can be done using the analysis test framework:
The test rule created with `analysistest.make` should specify `expect_failure`:
```python theme={null}
failure_testing_test = analysistest.make(
_failure_testing_test_impl,
expect_failure = True,
)
```
The test rule implementation should make assertions on the nature of the failure
that took place (specifically, the failure message):
```python theme={null}
def _failure_testing_test_impl(ctx):
env = analysistest.begin(ctx)
asserts.expect_failure(env, "This rule should never work")
return analysistest.end(env)
```
Also make sure that your target under test is specifically tagged 'manual'.
Without this, building all targets in your package using `:all` will result in a
build of the intentionally-failing target and will exhibit a build failure. With
'manual', your target under test will build only if explicitly specified, or as
a dependency of a non-manual target (such as your test rule):
```python theme={null}
def _test_failure():
myrule(name = "this_should_fail", tags = ["manual"])
failure_testing_test(name = "failure_testing_test",
target_under_test = ":this_should_fail")
# Then call _test_failure() in the macro which generates the test suite and add
# ":failure_testing_test" to the suite's test targets.
```
### Verifying registered actions
You may want to write tests which make assertions about the actions that your
rule registers, for example, using `ctx.actions.run()`. This can be done in your
analysis test rule implementation function. An example:
```python theme={null}
def _inspect_actions_test_impl(ctx):
env = analysistest.begin(ctx)
target_under_test = analysistest.target_under_test(env)
actions = analysistest.target_actions(env)
asserts.equals(env, 1, len(actions))
action_output = actions[0].outputs.to_list()[0]
asserts.equals(
env, target_under_test.label.name + ".out", action_output.basename)
return analysistest.end(env)
```
Note that `analysistest.target_actions(env)` returns a list of
[`Action`](/rules/lib/builtins/Action) objects which represent actions registered by the
target under test.
### Verifying rule behavior under different flags
You may want to verify your real rule behaves a certain way given certain build
flags. For example, your rule may behave differently if a user specifies:
```shell theme={null}
bazel build //mypkg:real_target -c opt
```
versus
```shell theme={null}
bazel build //mypkg:real_target -c dbg
```
At first glance, this could be done by testing the target under test using the
desired build flags:
```shell theme={null}
bazel test //mypkg:myrules_test -c opt
```
But then it becomes impossible for your test suite to simultaneously contain a
test which verifies the rule behavior under `-c opt` and another test which
verifies the rule behavior under `-c dbg`. Both tests would not be able to run
in the same build!
This can be solved by specifying the desired build flags when defining the test
rule:
```python theme={null}
myrule_c_opt_test = analysistest.make(
_myrule_c_opt_test_impl,
config_settings = {
"//command_line_option:compilation_mode": "opt",
},
)
```
Normally, a target under test is analyzed given the current build flags.
Specifying `config_settings` overrides the values of the specified command line
options. (Any unspecified options will retain their values from the actual
command line).
In the specified `config_settings` dictionary, command line flags must be
prefixed with a special placeholder value `//command_line_option:`, as is shown
above.
## Validating artifacts
The main ways to check that your generated files are correct are:
* You can write a test script in shell, Python, or another language, and
create a target of the appropriate `*_test` rule type.
* You can use a specialized rule for the kind of test you want to perform.
### Using a test target
The most straightforward way to validate an artifact is to write a script and
add a `*_test` target to your BUILD file. The specific artifacts you want to
check should be data dependencies of this target. If your validation logic is
reusable for multiple tests, it should be a script that takes command line
arguments that are controlled by the test target's `args` attribute. Here's an
example that validates that the output of `myrule` from above is `"abc"`.
`//mypkg/myrule_validator.sh`:
```shell theme={null}
if [ "$(cat $1)" = "abc" ]; then
echo "Passed"
exit 0
else
echo "Failed"
exit 1
fi
```
`//mypkg/BUILD`:
```python theme={null}
...
myrule(
name = "mytarget",
)
...
# Needed for each target whose artifacts are to be checked.
sh_test(
name = "validate_mytarget",
srcs = [":myrule_validator.sh"],
args = ["$(location :mytarget.out)"],
data = [":mytarget.out"],
)
```
### Using a custom rule
A more complicated alternative is to write the shell script as a template that
gets instantiated by a new rule. This involves more indirection and Starlark
logic, but leads to cleaner BUILD files. As a side-benefit, any argument
preprocessing can be done in Starlark instead of the script, and the script is
slightly more self-documenting since it uses symbolic placeholders (for
substitutions) instead of numeric ones (for arguments).
`//mypkg/myrule_validator.sh.template`:
```shell theme={null}
if [ "$(cat %TARGET%)" = "abc" ]; then
echo "Passed"
exit 0
else
echo "Failed"
exit 1
fi
```
`//mypkg/myrule_validation.bzl`:
```python theme={null}
def _myrule_validation_test_impl(ctx):
"""Rule for instantiating myrule_validator.sh.template for a given target."""
exe = ctx.outputs.executable
target = ctx.file.target
ctx.actions.expand_template(output = exe,
template = ctx.file._script,
is_executable = True,
substitutions = {
"%TARGET%": target.short_path,
})
# This is needed to make sure the output file of myrule is visible to the
# resulting instantiated script.
return [DefaultInfo(runfiles=ctx.runfiles(files=[target]))]
myrule_validation_test = rule(
implementation = _myrule_validation_test_impl,
attrs = {"target": attr.label(allow_single_file=True),
# You need an implicit dependency in order to access the template.
# A target could potentially override this attribute to modify
# the test logic.
"_script": attr.label(allow_single_file=True,
default=Label("//mypkg:myrule_validator"))},
test = True,
)
```
`//mypkg/BUILD`:
```python theme={null}
...
myrule(
name = "mytarget",
)
...
# Needed just once, to expose the template. Could have also used export_files(),
# and made the _script attribute set allow_files=True.
filegroup(
name = "myrule_validator",
srcs = [":myrule_validator.sh.template"],
)
# Needed for each target whose artifacts are to be checked. Notice that you no
# longer have to specify the output file name in a data attribute, or its
# $(location) expansion in an args attribute, or the label for the script
# (unless you want to override it).
myrule_validation_test(
name = "validate_mytarget",
target = ":mytarget",
)
```
Alternatively, instead of using a template expansion action, you could have
inlined the template into the .bzl file as a string and expanded it during the
analysis phase using the `str.format` method or `%`-formatting.
## Testing Starlark utilities
[Skylib](https://github.com/bazelbuild/bazel-skylib)'s
[`unittest.bzl`](https://github.com/bazelbuild/bazel-skylib/blob/main/lib/unittest.bzl)
framework can be used to test utility functions (that is, functions that are
neither macros nor rule implementations). Instead of using `unittest.bzl`'s
`analysistest` library, `unittest` may be used. For such test suites, the
convenience function `unittest.suite()` can be used to reduce boilerplate.
`//mypkg/myhelpers.bzl`:
```python theme={null}
def myhelper():
return "abc"
```
`//mypkg/myhelpers_test.bzl`:
```python theme={null}
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load(":myhelpers.bzl", "myhelper")
def _myhelper_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, "abc", myhelper())
return unittest.end(env)
myhelper_test = unittest.make(_myhelper_test_impl)
# No need for a test_myhelper() setup function.
def myhelpers_test_suite(name):
# unittest.suite() takes care of instantiating the testing rules and creating
# a test_suite.
unittest.suite(
name,
myhelper_test,
# ...
)
```
`//mypkg/BUILD`:
```python theme={null}
load(":myhelpers_test.bzl", "myhelpers_test_suite")
myhelpers_test_suite(name = "myhelpers_tests")
```
For more examples, see Skylib's own [tests](https://github.com/bazelbuild/bazel-skylib/blob/main/tests/BUILD).
# Using Macros to Create Custom Verbs
Source: https://bazel.build/rules/verbs-tutorial
Day-to-day interaction with Bazel happens primarily through a few commands:
`build`, `test`, and `run`. At times, though, these can feel limited: you may
want to push packages to a repository, publish documentation for end-users, or
deploy an application with Kubernetes. But Bazel doesn't have a `publish` or
`deploy` command – where do these actions fit in?
## The bazel run command
Bazel's focus on hermeticity, reproducibility, and incrementality means the
`build` and `test` commands aren't helpful for the above tasks. These actions
may run in a sandbox, with limited network access, and aren't guaranteed to be
re-run with every `bazel build`.
Instead, rely on `bazel run`: the workhorse for tasks that you *want* to have
side effects. Bazel users are accustomed to rules that create executables, and
rule authors can follow a common set of patterns to extend this to
"custom verbs".
### In the wild: rules\_k8s
For example, consider [`rules_k8s`](https://github.com/bazelbuild/rules_k8s),
the Kubernetes rules for Bazel. Suppose you have the following target:
```python theme={null}
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
```
The [`k8s_object` rule](https://github.com/bazelbuild/rules_k8s#usage) builds a
standard Kubernetes YAML file when `bazel build` is used on the `staging`
target. However, the additional targets are also created by the `k8s_object`
macro with names like `staging.apply` and `:staging.delete`. These build
scripts to perform those actions, and when executed with `bazel run
staging.apply`, these behave like our own `bazel k8s-apply` or `bazel
k8s-delete` commands.
### Another example: ts\_api\_guardian\_test
This pattern can also be seen in the Angular project. The
[`ts_api_guardian_test` macro](https://github.com/angular/angular/blob/16ac611a8410e6bcef8ffc779f488ca4fa102155/tools/ts-api-guardian/index.bzl#L22)
produces two targets. The first is a standard `nodejs_test` target which compares
some generated output against a "golden" file (that is, a file containing the
expected output). This can be built and run with a normal `bazel
test` invocation. In `angular-cli`, you can run [one such target](https://github.com/angular/angular-cli/blob/e1269cb520871ee29b1a4eec6e6c0e4a94f0b5fc/etc/api/BUILD)
with `bazel test //etc/api:angular_devkit_core_api`.
Over time, this golden file may need to be updated for legitimate reasons.
Updating this manually is tedious and error-prone, so this macro also provides
a `nodejs_binary` target that updates the golden file, instead of comparing
against it. Effectively, the same test script can be written to run in "verify"
or "accept" mode, based on how it's invoked. This follows the same pattern
you've learned already: there is no native `bazel test-accept` command, but the
same effect can be achieved with
`bazel run //etc/api:angular_devkit_core_api.accept`.
This pattern can be quite powerful, and turns out to be quite common once you
learn to recognize it.
## Adapting your own rules
[Macros](/extending/macros) are the heart of this pattern. Macros are used like
rules, but they can create several targets. Typically, they will create a
target with the specified name which performs the primary build action: perhaps
it builds a normal binary, a Docker image, or an archive of source code. In
this pattern, additional targets are created to produce scripts performing side
effects based on the output of the primary target, like publishing the
resulting binary or updating the expected test output.
To illustrate this, wrap an imaginary rule that generates a website with
[Sphinx](https://www.sphinx-doc.org) with a macro to create an additional
target that allows the user to publish it when ready. Consider the following
existing rule for generating a website with Sphinx:
```python theme={null}
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
```
Next, consider a rule like the following, which builds a script that, when run,
publishes the generated pages:
```python theme={null}
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
```
Finally, define the following symbolic macro (available in Bazel 8 or newer) to
create targets for both of the above rules together:
```starlark theme={null}
def _sphinx_site_impl(name, visibility, srcs, **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML. We
# set `visibility = visibility` to make it visible to callers of the
# macro.
_sphinx_site(name = name, visibility = visibility, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above. We don't want it to be visible to callers of
# our macro, so we omit visibility for it.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
sphinx_site = macro(
implementation = _sphinx_site_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
# Inherit common attributes like tags and testonly
inherit_attrs = "common",
)
```
Or, if you need to support Bazel releases older than Bazel 8, you would instead
define a legacy macro:
```starlark theme={null}
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
```
In the `BUILD` files, use the macro as though it just creates the primary
target:
```python theme={null}
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
```
In this example, a "docs" target is created, just as though the macro were a
standard, single Bazel rule. When built, the rule generates some configuration
and runs Sphinx to produce an HTML site, ready for manual inspection. However,
an additional "docs.publish" target is also created, which builds a script for
publishing the site. Once you check the output of the primary target, you can
use `bazel run :docs.publish` to publish it for public consumption, just like
an imaginary `bazel publish` command.
It's not immediately obvious what the implementation of the `_sphinx_publisher`
rule might look like. Often, actions like this write a *launcher* shell script.
This method typically involves using
[`ctx.actions.expand_template`](/rules/lib/builtins/actions#expand_template)
to write a very simple shell script, in this case invoking the publisher binary
with a path to the output of the primary target. This way, the publisher
implementation can remain generic, the `_sphinx_site` rule can just produce
HTML, and this small script is all that's necessary to combine the two
together.
In `rules_k8s`, this is indeed what `.apply` does:
[`expand_template`](https://github.com/bazelbuild/rules_k8s/blob/f10e7025df7651f47a76abf1db5ade1ffeb0c6ac/k8s/object.bzl#L213-L241)
writes a very simple Bash script, based on
[`apply.sh.tpl`](https://github.com/bazelbuild/rules_k8s/blob/f10e7025df7651f47a76abf1db5ade1ffeb0c6ac/k8s/apply.sh.tpl),
which runs `kubectl` with the output of the primary target. This script can
then be build and run with `bazel run :staging.apply`, effectively providing a
`k8s-apply` command for `k8s_object` targets.
# Writing Rules on Windows
Source: https://bazel.build/rules/windows
This page focuses on writing Windows-compatible rules, common problems of
writing portable rules, and some solutions.
## Paths
Problems:
* **Length limit**: maximum path length is 259 characters.
Though Windows also supports longer paths (up to 32767 characters), many programs are built with
the lower limit.
Be aware of this about programs you run in the actions.
* **Working directory**: is also limited to 259 characters.
Processes cannot `cd` into a directory longer than 259 characters.
* **Case-sensitivity**: Windows paths are case-insensitive, Unix paths are case-sensitive.
Be aware of this when creating command lines for actions.
* **Path separators**: are backslash (`\`), not forward slash (`/`).
Bazel stores paths Unix-style with `/` separators. Though some Windows programs support
Unix-style paths, others don't. Some built-in commands in cmd.exe support them, some don't.
It's best to always use `\` separators on Windows: replace `/` with `\` when you create command
lines and environment variables for actions.
* **Absolute paths**: don't start with slash (`/`).
Absolute paths on Windows start with a drive letter, such as `C:\foo\bar.txt`. There's no single
filesystem root.
Be aware of this if your rule checks if a path is absolute. Absolute paths
should be avoided since they are often non-portable.
Solutions:
* **Keep paths short.**
Avoid long directory names, deeply nested directory structures, long file names, long workspace
names, long target names.
All of these may become path components of actions' input files, and may exhaust the path length
limit.
* **Use a short output root.**
Use the `--output_user_root=` flag to specify a short path for Bazel outputs. A good idea
is to have a drive (or virtual drive) just for Bazel outputs (such as `D:\`), and adding this line
to your `.bazelrc` file:
```
build --output_user_root=D:/
```
or
```
build --output_user_root=C:/_bzl
```
* **Use junctions.**
Junctions are, loosely speaking\[1], directory symlinks. Junctions are easy to create
and can point to directories (on the same computer) with long paths. If a build action creates a
junction whose path is short but whose target is long, then tools with short path limit can access
the files in the junction'ed directory.
In `.bat` files or in cmd.exe you can create junctions like so:
```
mklink /J c:\path\to\junction c:\path\to\very\long\target\path
```
\[1]: Strictly speaking
[Junctions are not Symbolic Links](https://superuser.com/a/343079), but for
the sake of build actions you may regard Junctions as Directory Symlinks.
* **Replace `/` with `\` in paths in actions / envvars.**
When you create the command line or environment variables for an action, make the paths
Windows-style. Example:
```python theme={null}
def as_path(p, is_windows):
if is_windows:
return p.replace("/", "\\")
else:
return p
```
## Environment variables
Problems:
* **Case-sensitivity**: Windows environment variable names are case-insensitive.
For example, in Java `System.getenv("SystemRoot")` and `System.getenv("SYSTEMROOT")` yields the
same result. (This applies to other languages too.)
* **Hermeticity**: actions should use as few custom environment variables as possible.
Environment variables are part of the action's cache key. If an action uses environment variables
that change often, or are custom to users, that makes the rule less cache-able.
Solutions:
* **Only use upper-case environment variable names.**
This works on Windows, macOS, and Linux.
* **Minimize action environments.**
When using `ctx.actions.run`, set the environment to `ctx.configuration.default_shell_env`. If the
action needs more environment variables, put them all in a dictionary and pass that to the action.
Example:
```python theme={null}
load("@bazel_skylib//lib:dicts.bzl", "dicts")
def _make_env(ctx, output_file, is_windows):
out_path = output_file.path
if is_windows:
out_path = out_path.replace("/", "\\")
return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
```
## Actions
Problems:
* **Executable outputs**: Every executable file must have an executable extension.
The most common extensions are `.exe` (binary files) and `.bat` (Batch scripts).
Be aware that shell scripts (`.sh`) are NOT executable on Windows; you cannot specify them as
`ctx.actions.run`'s `executable`. There's also no `+x` permission that files can have, so you
can't execute arbitrary files like on Linux.
* **Bash commands**: For sake of portability, avoid running Bash commands directly in actions.
Bash is widespread on Unix-like systems, but it's often unavailable on Windows. Bazel itself is
relying less and less on Bash (MSYS2), so in the future users would be less likely to have MSYS2
installed along with Bazel. To make rules easier to use on Windows, avoid running Bash commands in
actions.
* **Line endings**: Windows uses CRLF (`\r\n`), Unix-like systems uses LF (`\n`).
Be aware of this when comparing text files. Be mindful of your Git settings, especially of line
endings when checking out or committing. (See Git's `core.autocrlf` setting.)
Solutions:
* **Use a Bash-less purpose-made rule.**
`native.genrule()` is a wrapper for Bash commands, and it's often used to solve simple problems
like copying a file or writing a text file. You can avoid relying on Bash (and reinventing the
wheel): see if bazel-skylib has a purpose-made rule for your needs. None of them depends on Bash
when built/tested on Windows.
Build rule examples:
* `copy_file()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/copy_file.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/copy_file_doc.md)):
copies a file somewhere else, optionally making it executable
* `write_file()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/write_file.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/write_file_doc.md)):
writes a text file, with the desired line endings (`auto`, `unix`, or `windows`), optionally
making it executable (if it's a script)
* `run_binary()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/run_binary.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/run_binary_doc.md)):
runs a binary (or `*_binary` rule) with given inputs and expected outputs as a build action
(this is a build rule wrapper for `ctx.actions.run`)
* `native_binary()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/native_binary.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/native_binary_doc.md#native_binary)):
wraps a native binary in a `*_binary` rule, which you can `bazel run` or use in `run_binary()`'s
`tool` attribute or `native.genrule()`'s `tools` attribute
Test rule examples:
* `diff_test()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/diff_test.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/diff_test_doc.md)):
test that compares contents of two files
* `native_test()`
([source](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/native_binary.bzl),
[documentation](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/native_binary_doc.md#native_test)):
wraps a native binary in a `*_test` rule, which you can `bazel test`
* **On Windows, consider using `.bat` scripts for trivial things.**
Instead of `.sh` scripts, you can solve trivial tasks with `.bat` scripts.
For example, if you need a script that does nothing, or prints a message, or exits with a fixed
error code, then a simple `.bat` file will suffice. If your rule returns a `DefaultInfo()`
provider, the `executable` field may refer to that `.bat` file on Windows.
And since file extensions don't matter on macOS and Linux, you can always use `.bat` as the
extension, even for shell scripts.
Be aware that empty `.bat` files cannot be executed. If you need an empty script, write one space
in it.
* **Use Bash in a principled way.**
In Starlark build and test rules, use `ctx.actions.run_shell` to run Bash scripts and Bash
commands as actions.
In Starlark macros, wrap Bash scripts and commands in a `native.sh_binary()` or
`native.genrule()`. Bazel will check if Bash is available and run the script or command through
Bash.
In Starlark repository rules, try avoiding Bash altogether. Bazel currently offers no way to run
Bash commands in a principled way in repository rules.
## Deleting files
Problems:
* **Files cannot be deleted while open.**
Open files cannot be deleted (by default), attempts result in "Access Denied"
errors. If you cannot delete a file, maybe a running process still holds it
open.
* **Working directory of a running process cannot be deleted.**
Processes have an open handle to their working directory, and the directory cannot be deleted
until the process terminates.
Solutions:
* **In your code, try to close files eagerly.**
In Java, use `try-with-resources`. In Python, use `with open(...) as f:`. In principle, try
closing handles as soon as possible.
# Contributing to Bazel
Source: https://bazel.build/contribute/index
There are many ways to help the Bazel project and ecosystem.
## Provide feedback
As you use Bazel, you may find things that can be improved.
You can help by [reporting issues](http://github.com/bazelbuild/bazel/issues)
when:
* Bazel crashes or you encounter a bug that can [only be resolved using `bazel clean`](/run/build#correct-incremental-rebuilds).
* 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
You can engage with the Bazel community by:
* Answering questions [on Stack Overflow](https://stackoverflow.com/questions/tagged/bazel).
* Helping other users [on Slack](https://slack.bazel.build).
* Improving documentation or [contributing examples](https://github.com/bazelbuild/examples).
* Sharing your experience or your tips, for example, on a blog or social media.
## 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](http://github.com/bazelbuild/bazel/issues)
or email [bazel-discuss@](mailto:bazel-discuss@googlegroups.com).
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](/contribute/patch-acceptance). If you use AI tools to
assist your contribution, review the
[AI-assisted contributions guidelines](/contribute/ai-assisted-contributions).
## Bazel's code description
Bazel has a large codebase with code in multiple locations. See the [codebase guide](/contribute/codebase) for more details.
Bazel is organized as follows:
* Client code is in `src/main/cpp` and provides the command-line interface.
* Protocol buffers are in `src/main/protobuf`.
* Server code is in `src/main/java` and `src/test/java`.
* Core code which is mostly composed of [SkyFrame](/reference/skyframe)
and some utilities.
* Built-in rules are in `com.google.devtools.build.lib.rules` and in
`com.google.devtools.build.lib.bazel.rules`. You might want to read about
the [Challenges of Writing Rules](/rules/challenges) first.
* Java native interfaces are in `src/main/native`.
* Various tooling for language support are described in the list in the
[compiling Bazel](/install/compile-source) section.
### Searching Bazel's source code
To quickly search through Bazel's source code, use
[Bazel Code Search](https://source.bazel.build/). 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](/contribute/search).
# Module extensions
Source: https://bazel.build/external/extension
Module extensions allow users to extend the module system by reading input data
from modules across the dependency graph, performing necessary logic to resolve
dependencies, and finally creating repos by calling [repo rules](/external/repo). These extensions have capabilities similar to repo
rules, which enables them to perform file I/O, send network requests, and so on.
Among other things, they allow Bazel to interact with other package management
systems while also respecting the dependency graph built out of Bazel modules.
You can define module extensions in `.bzl` files, just like repo rules. They're
not invoked directly; rather, each module specifies pieces of data called *tags*
for extensions to read. Bazel runs module resolution before evaluating any
extensions. The extension reads all the tags belonging to it across the entire
dependency graph.
## Extension usage
Extensions are hosted in Bazel modules themselves. To use an extension in a
module, first add a `bazel_dep` on the module hosting the extension, and then
call the [`use_extension`](/rules/lib/globals/module#use_extension) built-in function
to bring it into scope. Consider the following example — a snippet from a
`MODULE.bazel` file to use the "maven" extension defined in the
[`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external)
module:
```python theme={null}
bazel_dep(name = "rules_jvm_external", version = "4.5")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
```
This binds the return value of `use_extension` to a variable, which allows the
user to use dot-syntax to specify tags for the extension. The tags must follow
the schema defined by the corresponding *tag classes* specified in the
[extension definition](#extension_definition). For an example specifying some
`maven.install` and `maven.artifact` tags:
```python theme={null}
maven.install(artifacts = ["org.junit:junit:4.13.2"])
maven.artifact(group = "com.google.guava",
artifact = "guava",
version = "27.0-jre",
exclusions = ["com.google.j2objc:j2objc-annotations"])
```
Use the [`use_repo`](/rules/lib/globals/module#use_repo) directive to bring repos
generated by the extension into the scope of the current module.
```python theme={null}
use_repo(maven, "maven")
```
Repos generated by an extension are part of its API. In this example, the
"maven" module extension promises to generate a repo called `maven`. With the
declaration above, the extension properly resolves labels such as
`@maven//:org_junit_junit` to point to the repo generated by the "maven"
extension.
Note: Module extensions are evaluated lazily. This means that an extension will
typically not be evaluated unless some module brings one of its repositories
into scope using `use_repo` and that repository is referenced in a build. While
testing a module extension, `bazel mod deps` can be useful as it
unconditionally evaluates all module extensions.
## Extension definition
You can define module extensions similarly to [repo rules](/external/repo),
using the [`module_extension`](/rules/lib/globals/bzl#module_extension)
function. However, while repo rules have a number of attributes, module
extensions have [`tag_class`es](/rules/lib/globals/bzl#tag_class), each of which
has a number of attributes. The tag classes define schemas for tags used by this
extension. For example, the "maven" extension above might be defined like this:
```python theme={null}
# @rules_jvm_external//:extensions.bzl
_install = tag_class(attrs = {"artifacts": attr.string_list(), ...})
_artifact = tag_class(attrs = {"group": attr.string(), "artifact": attr.string(), ...})
maven = module_extension(
implementation = _maven_impl,
tag_classes = {"install": _install, "artifact": _artifact},
)
```
These declarations show that `maven.install` and `maven.artifact` tags can be
specified using the specified attribute schema.
The implementation function of module extensions are similar to those of repo
rules, except that they get a [`module_ctx`](/rules/lib/builtins/module_ctx) object,
which grants access to all modules using the extension and all pertinent tags.
The implementation function then calls repo rules to generate repos.
```python theme={null}
# @rules_jvm_external//:extensions.bzl
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") # a repo rule
def _maven_impl(ctx):
# This is a fake implementation for demonstration purposes only
# collect artifacts from across the dependency graph
artifacts = []
for mod in ctx.modules:
for install in mod.tags.install:
artifacts += install.artifacts
artifacts += [_to_artifact(artifact) for artifact in mod.tags.artifact]
# call out to the coursier CLI tool to resolve dependencies
output = ctx.execute(["coursier", "resolve", artifacts])
repo_attrs = _process_coursier_output(output)
# call repo rules to generate repos
for attrs in repo_attrs:
http_file(**attrs)
_generate_hub_repo(name = "maven", repo_attrs)
```
### Extension identity
Module extensions are identified by the name and the `.bzl` file that appears
in the call to `use_extension`. In the following example, the extension `maven`
is identified by the `.bzl` file `@rules_jvm_external//:extension.bzl` and the
name `maven`:
```python theme={null}
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
```
Re-exporting an extension from a different `.bzl` file gives it a new identity
and if both versions of the extension are used in the transitive module graph,
then they will be evaluated separately and will only see the tags associated
with that particular identity.
As an extension author you should make sure that users will only use your
module extension from one single `.bzl` file.
## Repository names and visibility
Repos generated by extensions have canonical names in the form of `module_repo_canonical_name+extension_name+repo_name`. Note that the canonical name
format is not an API you should depend on — it's subject to change at any time.
This naming policy means that each extension has its own "repo namespace"; two
distinct extensions can each define a repo with the same name without risking
any clashes. It also means that `repository_ctx.name` reports the canonical name
of the repo, which is *not* the same as the name specified in the repo rule
call.
Taking repos generated by module extensions into consideration, there are
several repo visibility rules:
* A Bazel module repo can see all repos introduced in its `MODULE.bazel` file
via [`bazel_dep`](/rules/lib/globals/module#bazel_dep) and
[`use_repo`](/rules/lib/globals/module#use_repo).
* A repo generated by a module extension can see all repos visible to the
module that hosts the extension, *plus* all other repos generated by the
same module extension (using the names specified in the repo rule calls as
their apparent names).
* This might result in a conflict. If the module repo can see a repo with
the apparent name `foo`, and the extension generates a repo with the
specified name `foo`, then for all repos generated by that extension
`foo` refers to the former.
* Similarly, in a module extension's implementation function, repos created
by the extension can refer to each other by their apparent names in
attributes, regardless of the order in which they are created.
* In case of a conflict with a repository visible to the module, labels
passed to repository rule attributes can be wrapped in a call to
[`Label`](/rules/lib/toplevel/attr#label) to ensure that they refer to
the repo visible to the module instead of the extension-generated repo
of the same name.
### Overriding and injecting module extension repos
The root module can use
[`override_repo`](/rules/lib/globals/module#override_repo) and
[`inject_repo`](/rules/lib/globals/module#inject_repo) to override or inject
module extension repos.
#### Example: Replacing `rules_java`'s `java_tools` with a vendored copy
```python theme={null}
# MODULE.bazel
local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(
name = "my_java_tools",
path = "vendor/java_tools",
)
bazel_dep(name = "rules_java", version = "7.11.1")
java_toolchains = use_extension("@rules_java//java:extension.bzl", "toolchains")
override_repo(java_toolchains, remote_java_tools = "my_java_tools")
```
#### Example: Patch a Go dependency to depend on `@zlib` instead of the system zlib
```python theme={null}
# MODULE.bazel
bazel_dep(name = "gazelle", version = "0.38.0")
bazel_dep(name = "zlib", version = "1.3.1.bcr.3")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
go_deps.module_override(
patches = [
"//patches:my_module_zlib.patch",
],
path = "example.com/my_module",
)
use_repo(go_deps, ...)
inject_repo(go_deps, "zlib")
```
```diff theme={null}
# patches/my_module_zlib.patch
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -1,6 +1,6 @@
go_binary(
name = "my_module",
importpath = "example.com/my_module",
srcs = ["my_module.go"],
- copts = ["-lz"],
+ cdeps = ["@zlib"],
)
```
## Best practices
This section describes best practices when writing extensions so they are
straightforward to use, maintainable, and adapt well to changes over time.
### Put each extension in a separate file
When extensions are in a different files, it allows one extension to load
repositories generated by another extension. Even if you don't use this
functionality, it's best to put them in separate files in case you need it
later. This is because the extension's identify is based on its file, so moving
the extension into another file later changes your public API and is a backwards
incompatible change for your users.
### Specify reproducibility and use facts
If your extension always defines the same repositories given the same inputs
(extension tags, files it reads, etc.) and in particular doesn't rely on
any [downloads](/rules/lib/builtins/module_ctx#download) that aren't guarded by
a checksum, consider returning
[`extension_metadata`](/rules/lib/builtins/module_ctx#extension_metadata) with
`reproducible = True`. This allows Bazel to skip this extension when writing to
the `MODULE.bazel` lockfile, which helps keep the lockfile small and reduces
the chance of merge conflicts. Note that Bazel still caches the results of
reproducible extensions in a way that persists across server restarts, so even
a long-running extension can be marked as reproducible without a performance
penalty.
If your extension relies on effectively immutable data obtained from outside
the build, most commonly from the network, but you don't have a checksum
available to guard the download, consider using the `facts` parameter of
[`extension_metadata`](/rules/lib/builtins/module_ctx#extension_metadata) to
persistently record such data and thus allow your extension to become
reproducible. `facts` is expected to be a dictionary with string keys and
arbitrary JSON-like Starlark values that is always persisted in the lockfile and
available to future evaluations of the extension via the
[`facts`](/rules/lib/builtins/module_ctx#facts) field of `module_ctx`.
`facts` are not invalidated even when the code of your module extension changes,
so be prepared to handle the case where the structure of `facts` changes.
Bazel also assumes that two different `facts` dicts produced by two different
evaluations of the same extension can be shallowly merged (i.e., as if by using
the `|` operator on two dicts). This is partially enforced by `module_ctx.facts`
not supporting enumeration of its entries, just lookups by key.
An example of using `facts` would be to record a mapping from version numbers of
some SDK to the an object containing the download URL and checksum of that
version. The first time the extension is evaluated, it can fetch this mapping
from the network, but on later evaluations it can use the mapping from `facts`
to avoid the network requests.
If you need to make a backwards-incompatible change to the schema of the values
your extension stores in `facts`, set the
[`facts_version`](/rules/lib/globals/bzl#module_extension.facts_version)
parameter on `module_extension` to a higher integer than its previous value.
Bazel persists `facts_version` in the lockfile alongside the facts and discards
any persisted facts when the recorded version differs from the current one,
making sure your extension only ever observes facts produced by the same schema.
### Specify dependence on operating system and architecture
If your extension relies on the operating system or its architecture type,
ensure to indicate this in the extension definition using the `os_dependent`
and `arch_dependent` boolean attributes. This ensures that Bazel recognizes the
need for re-evaluation if there are changes to either of them.
Since this kind of dependence on the host makes it more difficult to maintain
the lockfile entry for this extension, consider
[marking the extension reproducible](#specify_reproducibility) if possible.
### Only the root module should directly affect repository names
Remember that when an extension creates repositories, they are created within
the namespace of the extension. This means collisions can occur if different
modules use the same extension and end up creating a repository with the same
name. This often manifests as a module extension's `tag_class` having a `name`
argument that is passed as a repository rule's `name` value.
For example, say the root module, `A`, depends on module `B`. Both modules
depend on module `mylang`. If both `A` and `B` call
`mylang.toolchain(name="foo")`, they will both try to create a repository named
`foo` within the `mylang` module and an error will occur.
To avoid this, either remove the ability to set the repository name directly,
or only allow the root module to do so. It's OK to allow the root module this
ability because nothing will depend on it, so it doesn't have to worry about
another module creating a conflicting name.
# Frequently asked questions
Source: https://bazel.build/external/faq
This page answers some frequently asked questions about external dependencies in
Bazel.
## MODULE.bazel
### How should I version a Bazel module?
Setting `version` with the [`module`] directive in the source archive
`MODULE.bazel` can have several downsides and unintended side effects if not
managed carefully:
* Duplication: releasing a new version of a module typically involves both
incrementing the version in `MODULE.bazel` and tagging the release, two
separate steps that can fall out of sync. While automation can
reduce this risk, it's simpler and safer to avoid it altogether.
* Inconsistency: users overriding a module with a specific commit using a
[non-registry override] will see an incorrect version. for example, if the
`MODULE.bazel` in the source archive sets `version = "0.3.0"` but
additional commits have been made since that release, a user overriding
with one of those commits would still see `0.3.0`. In reality, the version
should reflect that it's ahead of the release, for example `0.3.1-rc1`.
* Non-registry override issues: using placeholder values can cause issues
when users override a module with a non-registry override. For example,
`0.0.0` doesn't sort as the highest version, which is usually the expected
behavior users want when doing a non-registry override.
Thus, it's best to avoid setting the version in the source archive
`MODULE.bazel`. Instead, set it in the `MODULE.bazel` stored in the registry
(e.g., the [Bazel Central Registry]), which is the actual source of truth for
the module version during Bazel's external dependency resolution (see [Bazel
registries]).
This is usually automated, for example the [`rules-template`] example rule
repository uses a [bazel-contrib/publish-to-bcr publish.yaml GitHub Action] to
publish the release to the BCR. The action [generates a patch for the source
archive `MODULE.bazel`] with the release version. This patch is stored in the
registry and is applied when the module is fetched during Bazel's external
dependency resolution.
This way, the version in the releases in the registry will be correctly set to
the released version and thus, `bazel_dep`, `single_version_override` and
`multiple_version_override` will work as expected, while avoiding potential
issues when doing a non-registry override because the version in the source
archive will be the default value (`''`), which will always be handled
correctly (it's the default version value after all) and will behave as
expected when sorting (the empty string is treated as the highest version).
[Bazel Central Registry]: https://registry.bazel.build/
[Bazel registries]: https://bazel.build/external/registry
[bazel-contrib/publish-to-bcr publish.yaml GitHub Action]: https://github.com/bazel-contrib/publish-to-bcr/blob/v0.2.2/.github/workflows/publish.yaml
[generates a patch for the source archive `MODULE.bazel`]: https://github.com/bazel-contrib/publish-to-bcr/blob/v0.2.2/src/domain/create-entry.ts#L176-L216
[`module`]: /rules/lib/globals/module#module
[non-registry override]: module.md#non-registry_overrides
[`rules-template`]: https://github.com/bazel-contrib/rules-template
### What is a compatibility level?
You should stop using `compatibility_level`.
Increasing `compatibility_level` leads to version conflicts that are difficult
for end users to resolve. Therefore, starting with Bazel 8.6.0 and 9.1.0, both
`compatibility_level` and `max_compatibility_level` are no-ops.
Module maintainers introducing major breaking changes should ensure that build
failures provide clear error messages and actionable migration paths.
**Legacy documentation:**
The [`compatibility_level`](/external/module#compatibility_level) of a Bazel module
should be incremented *in the same commit* that introduces a backwards
incompatible ("breaking") change.
However, Bazel can throw an error if it detects that versions of the *same
module* with *different compatibility levels* exist in the resolved dependency
graph. This can happen when for example' two modules depend on versions of a
third module with different compatibility levels.
Thus, incrementing `compatibility_level` too frequently can be very disruptive
and is discouraged. To avoid this situation, the `compatibility_level` should be
incremented *only* when the breaking change affects most use cases and isn't
easy to migrate and/or work-around.
### Why does MODULE.bazel not support `load`s?
During dependency resolution, the MODULE.bazel file of all referenced external
dependencies are fetched from registries. At this stage, the source archives of
the dependencies are not fetched yet; so if the MODULE.bazel file `load`s
another file, there is no way for Bazel to actually fetch that file without
fetching the entire source archive. Note the MODULE.bazel file itself is
special, as it's directly hosted on the registry.
There are a few use cases that people asking for `load`s in MODULE.bazel are
generally interested in, and they can be solved without `load`s:
* Ensuring that the version listed in MODULE.bazel is consistent with build
metadata stored elsewhere, for example in a .bzl file: This can be achieved
by using the
[`native.module_version`](/rules/lib/toplevel/native#module_version) method
in a .bzl file loaded from a BUILD file.
* Splitting up a very large MODULE.bazel file into manageable sections,
particularly for monorepos: The root module can use the
[`include`](/rules/lib/globals/module#include) directive to split its
MODULE.bazel file into multiple segments. For the same reason we don't allow
`load`s in MODULE.bazel files, `include` cannot be used in non-root modules.
* Users of the old WORKSPACE system might remember declaring a repo, and then
immediately `load`ing from that repo to perform complex logic. This
capability has been replaced by [module extensions](/external/extension).
### Can I specify a SemVer range for a `bazel_dep`?
No. Some other package managers like [npm][npm-semver] and [Cargo][cargo-semver]
support version ranges (implicitly or explicitly), and this often requires a
constraint solver (making the output harder to predict for users) and makes
version resolution nonreproducible without a lockfile.
Bazel instead uses [Minimal Version Selection](/external/module#version-selection) like
Go, which in contrast makes the output easy to predict and guarantees
reproducibility. This is a tradeoff that matches Bazel's design goals.
Furthermore, Bazel module versions are [a superset of SemVer](/external/module#version-format), so what makes sense in a strict SemVer
environment doesn't always carry over to Bazel module versions.
### Can I automatically get the latest version for a `bazel_dep`?
Some users occasionally ask for the ability to specify `bazel_dep(name = "foo",
version = "latest")` to automatically get the latest version of a dep. This is
similar to [the question about SemVer ranges](#can-i-specify-a-semver-range-for-a-bazel-dep), and the answer is also
no.
The recommended solution here is to have automation take care of this. For
example, [Renovate](https://docs.renovatebot.com/modules/manager/) supports
Bazel modules.
Sometimes, users asking this question are really looking for a way to quickly
iterate during local development. This can be achieved by using a
[`local_path_override`](/rules/lib/globals/module#local_path_override).
### Why all these `use_repo`s?
Module extension usages in MODULE.bazel files sometimes come with a big
`use_repo` directive. For example, a typical usage of the
[`go_deps` extension][go_deps] from `gazelle` might look like:
```python theme={null}
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(
go_deps,
"com_github_gogo_protobuf",
"com_github_golang_mock",
"com_github_golang_protobuf",
"org_golang_x_net",
... # potentially dozens of lines...
)
```
The long `use_repo` directive may seem redundant, since the information is
arguably already in the referenced `go.mod` file.
The reason Bazel needs this `use_repo` directive is that it runs module
extensions lazily. That is, a module extension is only run if its result is
observed. Since a module extension's "output" is repo definitions, this means
that we only run a module extension if a repo it defines is requested (for
instance, if the target `@org_golang_x_net//:foo` is built, in the example
above). However, we don't know which repos a module extension would define until
after we run it. This is where the `use_repo` directive comes in; the user can
tell Bazel which repos they expect the extension to generate, and Bazel would
then only run the extension when these specific repos are used.
To help the maintain this `use_repo` directive, a module extension can return
an [`extension_metadata`](/rules/lib/builtins/module_ctx#extension_metadata)
object from its implementation function. The user can run the `bazel mod tidy`
command to update the `use_repo` directives for these module extensions.
## Bzlmod migration
### Which is evaluated first, MODULE.bazel or WORKSPACE?
When both `--enable_bzlmod` and `--enable_workspace` are set, it's natural to
wonder which system is consulted first. The short answer is that MODULE.bazel
(Bzlmod) is evaluated first.
The long answer is that "which evaluates first" is not the right question to
ask; rather, the right question to ask is: in the context of the repo with
[canonical name](/external/overview#canonical-repo-name) `@@foo`, what does the [apparent repo name](/external/overview#apparent-repo-name) `@bar` resolve to? Alternatively, what
is the repo mapping of `@@base`?
Labels with apparent repo names (a single leading `@`) can refer to different
things based on the context they're resolved from. When you see a label
`@bar//:baz` and wonder what it actually points to, you need to first find out
what the context repo is: for example, if the label is in a BUILD file located
in the repo `@@foo`, then the context repo is `@@foo`.
Then, depending on what the context repo is, the ["repository visibility" table](/external/migration#repository-visibility) in the migration guide can
be used to find out which repo an apparent name actually resolves to.
* If the context repo is the main repo (`@@`):
1. If `bar` is an apparent repo name introduced by the root module's
MODULE.bazel file (through any of
[`bazel_dep`](/rules/lib/globals/module#bazel_dep.repo_name),
[`use_repo`](/rules/lib/globals/module#use_repo),
[`module`](/rules/lib/globals/module#module.repo_name),
[`use_repo_rule`](/rules/lib/globals/module#use_repo_rule)), then `@bar`
resolves to what that MODULE.bazel file claims.
2. Otherwise, if `bar` is a repo defined in WORKSPACE (which means that its
canonical name is `@@bar`), then `@bar` resolves to `@@bar`.
3. Otherwise, `@bar` resolves to something like
`@@[unknown repo 'bar' requested from @@]`, and this will ultimately
result in an error.
* If the context repo is a Bzlmod-world repo (that is, it corresponds to a
non-root Bazel module, or is generated by a module extension), then it
will only ever see other Bzlmod-world repos, and no WORKSPACE-world repos.
* Notably, this includes any repos introduced in a `non_module_deps`-like
module extension in the root module, or `use_repo_rule` instantiations
in the root module.
* If the context repo is defined in WORKSPACE:
1. First, check if the context repo definition has the magical
`repo_mapping` attribute. If so, go through the mapping first (so for a
repo defined with `repo_mapping = {"@bar": "@baz"}`, we would be looking
at `@baz` below).
2. If `bar` is an apparent repo name introduced by the root module's
MODULE.bazel file, then `@bar` resolves to what that MODULE.bazel file
claims. (This is the same as item 1 in the main repo case.)
3. Otherwise, `@bar` resolves to `@@bar`. This most likely will point to a
repo `bar` defined in WORKSPACE; if such a repo is not defined, Bazel
will throw an error.
For a more succinct version:
* Bzlmod-world repos (excluding the main repo) will only see Bzlmod-world
repos.
* WORKSPACE-world repos (including the main repo) will first see what the root
module in the Bzlmod world defines, then fall back to seeing WORKSPACE-world
repos.
Of note, labels in the Bazel command line (including Starlark flags, label-typed
flag values, and build/test target patterns) are treated as having the main repo
as the context repo.
## Other
### How do I prepare and run an offline build?
Use the `bazel fetch` command to prefetch repos. You can use the `--repo` flag
(like `bazel fetch --repo @foo`) to fetch only the repo `@foo` (resolved in the
context of the main repo, see [question above](#which-is-evaluated-first-module-bazel-or-workspace)), or use a target
pattern (like `bazel fetch @foo//:bar`) to fetch all transitive dependencies of
`@foo//:bar` (this is equivalent to `bazel build --nobuild @foo//:bar`).
To make sure no fetches happen during a build, use `--nofetch`. More precisely,
this makes any attempt to run a non-local repository rule fail.
If you want to fetch repos *and* modify them to test locally, consider using
the [`bazel vendor`](/external/vendor) command.
### How do I insulate my builds from the Internet?
Here are some websites on the publicly accessible Internet that a typical Bazel
build relies on, and what you can do to insulate yourself from potential
outages, especially as an enterprise Bazel user.
* `releases.bazel.build`: Bazelisk downloads Bazel release binaries from this
website. You can [configure Bazelisk][bazelisk-config] to have it download
from your company's internal mirror instead.
* `bcr.bazel.build`: Bazel consults the BCR for module metadata during module
resolution. You can mirror the BCR itself and set the `--registry` flag to
remove your dependency on BCR serving infrastructure (see the
[disclaimer][bcr-disclaimer] for more information). Alternatively, you can
ensure your MODULE.bazel.lock file is up to date, and set up your CI or
developer machines with a prepopulated download cache
(`--repository_cache`). If properly set up, the download cache will contain
all necessary registry files needed for a build, and the lockfile will
contain their checksums; Bazel will then use the cached results and avoid
Internet access altogether during module resolution.
* `mirror.bazel.build` and `github.com`: Many modules have source archives
hosted on these two websites. Consider setting up a company-internal mirror
for source archives, and use either `--downloader_config` or
`--module_mirrors` to point Bazel at them. Alternatively, a prepopulated
download cache as mentioned in the previous bullet point will also help
Bazel completely avoid accessing the Internet for source archives.
### How do I use HTTP proxies?
Bazel respects the `http_proxy` and `HTTPS_PROXY` environment variables commonly
accepted by other programs, such as
[curl](https://everything.curl.dev/usingcurl/proxies/env.html).
### How do I make Bazel prefer IPv6 in dual-stack IPv4/IPv6 setups?
On IPv6-only machines, Bazel can download dependencies with no changes. However,
on dual-stack IPv4/IPv6 machines Bazel follows the same convention as Java,
preferring IPv4 if enabled. In some situations, for example when the IPv4
network cannot resolve/reach external addresses, this can cause `Network
unreachable` exceptions and build failures. In these cases, you can override
Bazel's behavior to prefer IPv6 by using the
[`java.net.preferIPv6Addresses=true` system property](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html).
Specifically:
* Use `--host_jvm_args=-Djava.net.preferIPv6Addresses=true` [startup option](/docs/user-manual#startup-options), for example by adding the
following line in your [`.bazelrc` file](/run/bazelrc):
`startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true`
* When running Java build targets that need to connect to the internet (such
as for integration tests), use the
`--jvmopt=-Djava.net.preferIPv6Addresses=true` [tool flag](/docs/user-manual#jvmopt). For example, include in your [`.bazelrc` file](/run/bazelrc):
`build --jvmopt=-Djava.net.preferIPv6Addresses`
* If you are using
[`rules_jvm_external`](https://github.com/bazelbuild/rules_jvm_external) for
dependency version resolution, also add
`-Djava.net.preferIPv6Addresses=true` to the `COURSIER_OPTS` environment
variable to [provide JVM options for Coursier](https://github.com/bazelbuild/rules_jvm_external#provide-jvm-options-for-coursier-with-coursier_opts).
### Can repo rules be run remotely with remote execution?
No; or at least, not yet. Users employing remote execution services to speed up
their builds may notice that repo rules are still run locally. For example, an
`http_archive` would be first downloaded onto the local machine (using any local
download cache if applicable), extracted, and then each source file would be
uploaded to the remote execution service as an input file. It's natural to ask
why the remote execution service doesn't just download and extract that archive,
saving a useless roundtrip.
Part of the reason is that repo rules (and module extensions) are akin to
"scripts" that are run by Bazel itself. A remote executor doesn't necessarily
even have a Bazel installed.
Another reason is that Bazel often needs the BUILD files in the downloaded and
extracted archives to perform loading and analysis, which *are* performed
locally.
There are preliminary ideas to solve this problem by re-imagining repo rules as
build rules, which would naturally allow them to be run remotely, but conversely
raise new architectural concerns (for example, the `query` commands would
potentially need to run actions, complicating their design).
For more previous discussion on this topic, see [A way to support repositories that need Bazel for being fetched](https://github.com/bazelbuild/bazel/discussions/20464).
[npm-semver]: https://docs.npmjs.com/about-semantic-versioning
[cargo-semver]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#version-requirement-syntax
[go_deps]: https://github.com/bazel-contrib/rules_go/blob/master/docs/go/core/bzlmod.md#specifying-external-dependencies
[bazelisk-config]: https://github.com/bazelbuild/bazelisk?tab=readme-ov-file#where-does-bazelisk-get-bazel-from
[bcr-disclaimer]: https://github.com/bazelbuild/bazel-central-registry?tab=readme-ov-file#disclaimer
# Bazel Lockfile
Source: https://bazel.build/external/lockfile
The lockfile feature in Bazel enables the recording of specific versions or
dependencies of software libraries or packages required by a project. It
achieves this by storing the result of module resolution and extension
evaluation. The lockfile promotes reproducible builds, ensuring consistent
development environments. Additionally, it enhances build efficiency by allowing
Bazel to skip the parts of the resolution process that are unaffected by changes
in project dependencies. Furthermore, the lockfile improves stability by
preventing unexpected updates or breaking changes in external libraries, thereby
reducing the risk of introducing bugs.
## Lockfile Generation
The lockfile is generated under the workspace root with the name
`MODULE.bazel.lock`. It is created or updated during the build process,
specifically after module resolution and extension evaluation. Importantly, it
only includes dependencies that are included in the current invocation of the
build.
When changes occur in the project that affect its dependencies, the lockfile is
automatically updated to reflect the new state. This ensures that the lockfile
remains focused on the specific set of dependencies required for the current
build, providing an accurate representation of the project's resolved
dependencies.
## Lockfile Usage
The lockfile can be controlled by the flag
[`--lockfile_mode`](/reference/command-line-reference#flag--lockfile_mode) to
customize the behavior of Bazel when the project state differs from the
lockfile. The available modes are:
* `update` (Default): Use the information that is present in the lockfile to
skip downloads of known registry files and to avoid re-evaluating extensions
whose results are still up-to-date. If information is missing, it will
be added to the lockfile. In this mode, Bazel also avoids refreshing
mutable information, such as yanked versions, for dependencies that haven't
changed.
* `refresh`: Like `update`, but mutable information is always refreshed when
switching to this mode and roughly every hour while in this mode.
* `error`: Like `update`, but if any information consulted during resolution
is missing or out-of-date, Bazel will fail with an error. This mode never
changes the lockfile or performs network requests during resolution. Module
extensions that marked themselves as `reproducible` may still perform
network requests, but are expected to always produce the same result. Note
that superfluous information is ignored, not reported, so a lockfile that
passes in this mode may nevertheless be rewritten (pruned) by `update`.
* `off`: The lockfile is neither checked nor updated.
## Lockfile Benefits
The lockfile offers several benefits and can be utilized in various ways:
* **Reproducible builds.** By capturing the specific versions or dependencies
of software libraries, the lockfile ensures that builds are reproducible
across different environments and over time. Developers can rely on
consistent and predictable results when building their projects.
* **Fast incremental resolutions.** The lockfile enables Bazel to avoid
downloading registry files that were already used in a previous build.
This significantly improves build efficiency, especially in scenarios where
resolution can be time-consuming.
* **Stability and risk reduction.** The lockfile helps maintain stability by
preventing unexpected updates or breaking changes in external libraries. By
locking the dependencies to specific versions, the risk of introducing bugs
due to incompatible or untested updates is reduced.
### Hidden lockfile
Bazel also maintains another lockfile at
`"$(bazel info output_base)"/MODULE.bazel.lock`. The format and contents of this
lockfile are explicitly unspecified. It is only used as a performance
optimization. While it can be deleted together with the output base via
`bazel clean --expunge`, any need to do so is a bug in either Bazel itself or a
module extension.
## Lockfile Contents
The lockfile contains all the necessary information to determine whether the
project state has changed. It also includes the result of building the project
in the current state. The lockfile consists of two main parts:
1. Hashes of all remote files that are inputs to module resolution.
2. For each module extension, the lockfile includes inputs that affect it,
represented by `bzlTransitiveDigest`, `usagesDigest` and other fields, as
well as the output of running that extension, referred to as
`generatedRepoSpecs`
Here is an example that demonstrates the structure of the lockfile, along with
explanations for each section:
```json theme={null}
{
"lockFileVersion": 10,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4af...5d5b3497",
"https://bcr.bazel.build/modules/foo/1.0/MODULE.bazel": "7cd0312e...5c96ace2",
"https://bcr.bazel.build/modules/foo/2.0/MODULE.bazel": "70390338... 9fc57589",
"https://bcr.bazel.build/modules/foo/2.0/source.json": "7e3a9adf...170d94ad",
"https://registry.mycorp.com/modules/foo/1.0/MODULE.bazel": "not found",
...
},
"selectedYankedVersions": {
"foo@2.0": "Yanked for demo purposes"
},
"moduleExtensions": {
"//:extension.bzl%lockfile_ext": {
"general": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
},
"//:extension.bzl%lockfile_ext2": {
"os:macos": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
},
"os:linux": {
"bzlTransitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
}
}
}
```
### Registry File Hashes
The `registryFileHashes` section contains the hashes of all files from
remote registries accessed during module resolution. Since the resolution
algorithm is fully deterministic when given the same inputs and all remote
inputs are hashed, this ensures a fully reproducible resolution result while
avoiding excessive duplication of remote information in the lockfile. Note that
this also requires recording when a particular registry didn't contain a certain
module, but a registry with lower precedence did (see the "not found" entry in
the example). This inherently mutable information can be updated via
`bazel mod deps --lockfile_mode=refresh`.
Bazel uses the hashes from the lockfile to look up registry files in the
repository cache before downloading them, which speeds up subsequent
resolutions.
### Selected Yanked Versions
The `selectedYankedVersions` section contains the yanked versions of modules
that were selected by module resolution. Since this usually result in an error
when trying to build, this section is only non-empty when yanked versions are
explicitly allowed via `--allow_yanked_versions` or
`BZLMOD_ALLOW_YANKED_VERSIONS`.
This field is needed since, compared to module files, yanked version information
is inherently mutable and thus can't be referenced by a hash. This information
can be updated via `bazel mod deps --lockfile_mode=refresh`.
### Module Extensions
The `moduleExtensions` section is a map that includes only the extensions used
in the current invocation or previously invoked, while excluding any extensions
that are no longer utilized. In other words, if an extension is not being used
anymore across the dependency graph, it is removed from the `moduleExtensions`
map.
If an extension is independent of the operating system or architecture type,
this section features only a single "general" entry. Otherwise, multiple
entries are included, named after the OS, architecture, or both, with each
corresponding to the result of evaluating the extension on those specifics.
Each entry in the extension map corresponds to a used extension and is
identified by its containing file and name. The corresponding value for each
entry contains the relevant information associated with that extension:
1. The `bzlTransitiveDigest` is the digest of the extension implementation
and the .bzl files transitively loaded by it.
2. The `usagesDigest` is the digest of the *usages* of the extension in the
dependency graph, which includes all tags.
3. Further unspecified fields that track other inputs to the extension,
such as contents of files or directories it reads or environment
variables it uses.
4. The `generatedRepoSpecs` encode the repositories created by the
extension with the current input.
5. The optional `moduleExtensionMetadata` field contains metadata provided by
the extension such as whether certain repositories it created should be
imported via `use_repo` by the root module. This information powers the
`bazel mod tidy` command.
Module extensions can opt out of being included in the lockfile by setting the
returning metadata with `reproducible = True`. By doing so, they promise that
they will always create the same repositories when given the same inputs.
## Best Practices
To maximize the benefits of the lockfile feature, consider the following best
practices:
* Regularly update the lockfile via `bazel mod tidy` to reflect changes in
project dependencies or configuration. This ensures that subsequent builds
are as efficient and repeatable as possible. This command also formats
module files and fixes supported `use_repo` calls.
* Include the lockfile in version control to facilitate collaboration and
ensure that all team members have access to the same lockfile, promoting
consistent development environments across the project.
* Use [`bazelisk`](/install/bazelisk) to run Bazel, and include a
`.bazelversion` file in version control that specifies the Bazel version
corresponding to the lockfile. Because Bazel itself is a dependency of
your build, the lockfile is specific to the Bazel version, and will
change even between [backwards compatible](/release/backward-compatibility)
Bazel releases. Using `bazelisk` ensures that all developers are using
a Bazel version that matches the lockfile.
By following these best practices, you can effectively utilize the lockfile
feature in Bazel, leading to more efficient, reliable, and collaborative
software development workflows.
## Merge Conflicts
The lockfile format is designed to minimize merge conflicts, but they can still
happen.
### Automatic Resolution
Bazel provides a custom
[git merge driver](https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver)
to help resolve these conflicts automatically.
Set up the driver by adding this line to a `.gitattributes` file in the root of
your git repository:
```gitattributes theme={null}
# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge
```
Then each developer who wants to use the driver has to register it once by
following these steps:
1. Install [jq](https://jqlang.github.io/jq/download/) (1.5 or higher).
2. Run the following commands:
```bash theme={null}
jq_script=$(curl https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-lockfile-merge.jq)
printf '%s\n' "${jq_script}" | less # to optionally inspect the jq script
git config --global merge.bazel-lockfile-merge.name "Merge driver for the Bazel lockfile (MODULE.bazel.lock)"
git config --global merge.bazel-lockfile-merge.driver "jq -s '${jq_script}' -- %O %A %B > %A.jq_tmp && mv %A.jq_tmp %A"
```
### Manual Resolution
Simple merge conflicts in the `registryFileHashes` and `selectedYankedVersions`
fields can be safely resolved by keeping all the entries from both sides of the
conflict.
Other types of merge conflicts should not be resolved manually. Instead:
1. Restore the previous state of the lockfile
via `git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock`.
2. Resolve any conflicts in the `MODULE.bazel` file.
3. Run `bazel mod deps` to update the lockfile.
# Bzlmod Migration Guide
Source: https://bazel.build/external/migration
Due to the [shortcomings of WORKSPACE](/external/overview#workspace-shortcomings), Bzlmod is replacing the
legacy WORKSPACE system. The WORKSPACE file is already disabled in Bazel 8 (late
2024\) and will be removed in Bazel 9 (late 2025). This guide helps you migrate
your project to Bzlmod and drop WORKSPACE for managing external dependencies.
## Why migrate to Bzlmod?
* There are many [advantages](/external/overview#benefits) compared to the legacy
WORKSPACE system, which helps to ensure a healthy growth of the Bazel
ecosystem.
* If your project is a dependency of other projects, migrating to Bzlmod will
unblock their migration and make it easier for them to depend on your
project.
* Migration to Bzlmod is a necessary step in order to use future Bazel
versions (mandatory in Bazel 9).
## How to migrate to Bzlmod?
Recommended migration process:
1. Use [migration tool](/external/migration_tool) as a helper tool to
streamline the migration process as much as possible.
2. If there are errors left after using the migration tool, resolve them
manually. For understanding the main differences between concepts inside
`WORKSPACE` and `MODULE.bazel` files, check [WORKSPACE versus Bzlmod](#workspace-vs-bzlmod) section.
## WORKSPACE vs Bzlmod
Bazel's WORKSPACE and Bzlmod offer similar features with different syntax. This
section explains how to migrate from specific WORKSPACE functionalities to
Bzlmod.
### Define the root of a Bazel workspace
The WORKSPACE file marks the source root of a Bazel project, this responsibility
is replaced by MODULE.bazel in Bazel version 6.3 and later. With Bazel versions
prior to 6.3, there should still be a `WORKSPACE` or `WORKSPACE.bazel` file at
your workspace root, maybe with comments like:
* **WORKSPACE**
```python theme={null}
# This file marks the root of the Bazel workspace.
# See MODULE.bazel for external dependencies setup.
```
### Enable Bzlmod in your bazelrc
`.bazelrc` lets you set flags that apply every time your run Bazel. To enable
Bzlmod, use the `--enable_bzlmod` flag, and apply it to the `common` command so
it applies to every command:
* **.bazelrc**
```
# Enable Bzlmod for every Bazel command
common --enable_bzlmod
```
### Specify repository name for your workspace
* **WORKSPACE**
The [`workspace`](/versions/8.7.0/rules/lib/globals/workspace#workspace) function is used
to specify a repository name for your workspace. This allows a target
`//foo:bar` in the workspace to be referenced as `@//foo:bar`. If not specified, the default repository name for your
workspace is `__main__`.
```python theme={null}
## WORKSPACE
workspace(name = "com_foo_bar")
```
* **Bzlmod**
It's recommended to reference targets in the same workspace with the
`//foo:bar` syntax without `@`. But if you do need the old syntax
, you can use the module name specified by the
[`module`](/rules/lib/globals/module#module) function as the repository
name. If the module name is different from the needed repository name, you
can use `repo_name` attribute of the
[`module`](/rules/lib/globals/module#module) function to override the
repository name.
```python theme={null}
## MODULE.bazel
module(
name = "bar",
repo_name = "com_foo_bar",
)
```
### Fetch external dependencies as Bazel modules
If your dependency is a Bazel project, you should be able to depend on it as a
Bazel module when it also adopts Bzlmod.
* **WORKSPACE**
With WORKSPACE, it's common to use the
[`http_archive`](/rules/lib/repo/http#http_archive) or
[`git_repository`](/rules/lib/repo/git#git_repository) repository rules to
download the sources of the Bazel project.
```python theme={null}
## WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"],
sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
http_archive(
name = "rules_java",
urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"],
sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a",
)
load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
rules_java_dependencies()
rules_java_toolchains()
```
As you can see, it's a common pattern that users need to load transitive
dependencies from a macro of the dependency. Assume both `bazel_skylib` and
`rules_java` depends on `platform`, the exact version of the `platform`
dependency is determined by the order of the macros.
* **Bzlmod**
With Bzlmod, as long as your dependency is available in [Bazel Central Registry](https://registry.bazel.build) or your custom [Bazel registry](/external/registry), you can simply depend on it with a
[`bazel_dep`](/rules/lib/globals/module#bazel_dep) directive.
```python theme={null}
## MODULE.bazel
bazel_dep(name = "bazel_skylib", version = "1.4.2")
bazel_dep(name = "rules_java", version = "6.1.1")
```
Bzlmod resolves Bazel module dependencies transitively using the
[MVS](https://research.swtch.com/vgo-mvs) algorithm. Therefore, the maximal
required version of `platform` is selected automatically.
### Override a dependency as a Bazel module
As the root module, you can override Bazel module dependencies in different
ways.
Please read the [overrides](/external/module#overrides) section for more
information.
You can find some example usages in the
[examples][override-examples]
repository.
[override-examples]: https://github.com/bazelbuild/examples/blob/main/bzlmod/02-override_bazel_module
### Fetch external dependencies with module extensions
If your dependency is not a Bazel project or not yet available in any Bazel
registry, you can introduce it using
[`use_repo_rule`](/external/module#use_repo_rule) or [module extensions](/external/extension).
* **WORKSPACE**
Download a file using the [`http_file`](/rules/lib/repo/http#http_file)
repository rule.
```python theme={null}
## WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "data_file",
url = "http://example.com/file",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```
* **Bzlmod**
With Bzlmod, you can use the `use_repo_rule` directive in your MODULE.bazel
file to directly instantiate repos:
```python theme={null}
## MODULE.bazel
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "data_file",
url = "http://example.com/file",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```
Under the hood, this is implemented using a module extension. If you need to
perform more complex logic than simply invoking a repo rule, you could also
implement a module extension yourself. You'll need to move the definition
into a `.bzl` file, which also lets you share the definition between
WORKSPACE and Bzlmod during the migration period.
```python theme={null}
## repositories.bzl
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def my_data_dependency():
http_file(
name = "data_file",
url = "http://example.com/file",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```
Implement a module extension to load the dependencies macro. You can define
it in the same `.bzl` file of the macro, but to keep compatibility with
older Bazel versions, it's better to define it in a separate `.bzl` file.
```python theme={null}
## extensions.bzl
load("//:repositories.bzl", "my_data_dependency")
def _non_module_dependencies_impl(_ctx):
my_data_dependency()
non_module_dependencies = module_extension(
implementation = _non_module_dependencies_impl,
)
```
To make the repository visible to the root project, you should declare the
usages of the module extension and the repository in the MODULE.bazel file.
```python theme={null}
## MODULE.bazel
non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
use_repo(non_module_dependencies, "data_file")
```
### Resolve conflict external dependencies with module extension
A project can provide a macro that introduces external repositories based on
inputs from its callers. But what if there are multiple callers in the
dependency graph and they cause a conflict?
Assume the project `foo` provides the following macro which takes `version` as
an argument.
```python theme={null}
## repositories.bzl in foo {#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
http_file(
name = "data_file",
url = "http://example.com/file-%s" % version,
# Omitting the "sha256" attribute for simplicity
)
```
* **WORKSPACE**
With WORKSPACE, you can load the macro from `@foo` and specify the version
of the data dependency you need. Assume you have another dependency `@bar`,
which also depends on `@foo` but requires a different version of the data
dependency.
```python theme={null}
## WORKSPACE
# Introduce @foo and @bar.
...
load("@foo//:repositories.bzl", "data_deps")
data_deps(version = "2.0")
load("@bar//:repositories.bzl", "bar_deps")
bar_deps() # -> which calls data_deps(version = "3.0")
```
In this case, the end user must carefully adjust the order of macros in the
WORKSPACE to get the version they need. This is one of the biggest pain
points with WORKSPACE since it doesn't really provide a sensible way to
resolve dependencies.
* **Bzlmod**
With Bzlmod, the author of project `foo` can use module extension to resolve
conflicts. For example, let's assume it makes sense to always select the
maximal required version of the data dependency among all Bazel modules.
```python theme={null}
## extensions.bzl in foo
load("//:repositories.bzl", "data_deps")
data = tag_class(attrs={"version": attr.string()})
def _data_deps_extension_impl(module_ctx):
# Select the maximal required version in the dependency graph.
version = "1.0"
for mod in module_ctx.modules:
for data in mod.tags.data:
version = max(version, data.version)
data_deps(version)
data_deps_extension = module_extension(
implementation = _data_deps_extension_impl,
tag_classes = {"data": data},
)
```
```python theme={null}
## MODULE.bazel in bar
bazel_dep(name = "foo", version = "1.0")
foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
foo_data_deps.data(version = "3.0")
use_repo(foo_data_deps, "data_file")
```
```python theme={null}
## MODULE.bazel in root module
bazel_dep(name = "foo", version = "1.0")
bazel_dep(name = "bar", version = "1.0")
foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
foo_data_deps.data(version = "2.0")
use_repo(foo_data_deps, "data_file")
```
In this case, the root module requires data version `2.0`, while its
dependency `bar` requires `3.0`. The module extension in `foo` can correctly
resolve this conflict and automatically select version `3.0` for the data
dependency.
### Integrate third party package manager
Following the last section, since module extension provides a way to collect
information from the dependency graph, perform custom logic to resolve
dependencies and call repository rules to introduce external repositories, this
provides a great way for rules authors to enhance the rulesets that integrate
package managers for specific languages.
Please read the [module extensions](/external/extension) page to learn more
about how to use module extensions.
Here is a list of the rulesets that already adopted Bzlmod to fetch dependencies
from different package managers:
* [rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external/blob/master/docs/bzlmod.md)
* [rules\_go](https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md)
* [rules\_python](https://github.com/bazelbuild/rules_python/blob/main/BZLMOD_SUPPORT.md)
A minimal example that integrates a pseudo package manager is available at the
[examples][pkg-mgr-example]
repository.
[pkg-mgr-example]: https://github.com/bazelbuild/examples/tree/main/bzlmod/05-integrate_third_party_package_manager
### Detect toolchains on the host machine
When Bazel build rules need to detect what toolchains are available on your host
machine, they use repository rules to inspect the host machine and generate
toolchain info as external repositories.
* **WORKSPACE**
Given the following repository rule to detect a shell toolchain.
```python theme={null}
## local_config_sh.bzl
def _sh_config_rule_impl(repository_ctx):
sh_path = get_sh_path_from_env("SH_BIN_PATH")
if not sh_path:
sh_path = detect_sh_from_path()
if not sh_path:
sh_path = "/shell/binary/not/found"
repository_ctx.file("BUILD", """
load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain")
sh_toolchain(
name = "local_sh",
path = "{sh_path}",
visibility = ["//visibility:public"],
)
toolchain(
name = "local_sh_toolchain",
toolchain = ":local_sh",
toolchain_type = "@bazel_tools//tools/sh:toolchain_type",
)
""".format(sh_path = sh_path))
sh_config_rule = repository_rule(
environ = ["SH_BIN_PATH"],
local = True,
implementation = _sh_config_rule_impl,
)
```
You can load the repository rule in WORKSPACE.
```python theme={null}
## WORKSPACE
load("//:local_config_sh.bzl", "sh_config_rule")
sh_config_rule(name = "local_config_sh")
```
* **Bzlmod**
With Bzlmod, you can introduce the same repository using a module extension,
which is similar to introducing the `@data_file` repository in the last
section.
```
## local_config_sh_extension.bzl
load("//:local_config_sh.bzl", "sh_config_rule")
sh_config_extension = module_extension(
implementation = lambda ctx: sh_config_rule(name = "local_config_sh"),
)
```
Then use the extension in the MODULE.bazel file.
```python theme={null}
## MODULE.bazel
sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
use_repo(sh_config_ext, "local_config_sh")
```
### Register toolchains & execution platforms
Following the last section, after introducing a repository hosting toolchain
information (e.g. `local_config_sh`), you probably want to register the
toolchain.
* **WORKSPACE**
With WORKSPACE, you can register the toolchain in the following ways.
1. You can register the toolchain the `.bzl` file and load the macro in the
WORKSPACE file.
```python theme={null}
## local_config_sh.bzl
def sh_configure():
sh_config_rule(name = "local_config_sh")
native.register_toolchains("@local_config_sh//:local_sh_toolchain")
```
```python theme={null}
## WORKSPACE
load("//:local_config_sh.bzl", "sh_configure")
sh_configure()
```
2. Or register the toolchain in the WORKSPACE file directly.
```python theme={null}
## WORKSPACE
load("//:local_config_sh.bzl", "sh_config_rule")
sh_config_rule(name = "local_config_sh")
register_toolchains("@local_config_sh//:local_sh_toolchain")
```
* **Bzlmod**
With Bzlmod, the
[`register_toolchains`](/rules/lib/globals/module#register_toolchains) and
[`register_execution_platforms`][register_execution_platforms]
APIs are only available in the MODULE.bazel file. You cannot call
`native.register_toolchains` in a module extension.
```python theme={null}
## MODULE.bazel
sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
use_repo(sh_config_ext, "local_config_sh")
register_toolchains("@local_config_sh//:local_sh_toolchain")
```
The toolchains and execution platforms registered in `WORKSPACE`,
`WORKSPACE.bzlmod` and each Bazel module's `MODULE.bazel` file follow this
order of precedence during toolchain selection (from highest to lowest):
1. toolchains and execution platforms registered in the root module's
`MODULE.bazel` file.
2. toolchains and execution platforms registered in the `WORKSPACE` or
`WORKSPACE.bzlmod` file.
3. toolchains and execution platforms registered by modules that are
(transitive) dependencies of the root module.
4. when not using `WORKSPACE.bzlmod`: toolchains registered in the `WORKSPACE`
[suffix](/external/migration#builtin-default-deps).
[register_execution_platforms]: /rules/lib/globals/module#register_execution_platforms
### Introduce local repositories
You may need to introduce a dependency as a local repository when you need a
local version of the dependency for debugging or you want to incorporate a
directory in your workspace as external repository.
* **WORKSPACE**
With WORKSPACE, this is achieved by two native repository rules,
[`local_repository`](/versions/8.0.0/reference/be/workspace#local_repository) and
[`new_local_repository`](/versions/8.0.0/reference/be/workspace#new_local_repository).
```python theme={null}
## WORKSPACE
local_repository(
name = "rules_java",
path = "/Users/bazel_user/workspace/rules_java",
)
```
* **Bzlmod**
With Bzlmod, you can use
[`local_path_override`](/rules/lib/globals/module#local_path_override) to
override a module with a local path.
```python theme={null}
## MODULE.bazel
bazel_dep(name = "rules_java")
local_path_override(
module_name = "rules_java",
path = "/Users/bazel_user/workspace/rules_java",
)
```
Note: With `local_path_override`, you can only introduce a local directory
as a Bazel module, which means it should have a MODULE.bazel file and its
transitive dependencies are taken into consideration during dependency
resolution. In addition, all module override directives can only be used by
the root module.
It is also possible to introduce a local repository with module extension.
However, you cannot call `native.local_repository` in module extension,
there is ongoing effort on starlarkifying all native repository rules (check
[#18285](https://github.com/bazelbuild/bazel/issues/18285) for progress).
Then you can call the corresponding starlark `local_repository` in a module
extension. It's also trivial to implement a custom version of
`local_repository` repository rule if this is a blocking issue for you.
### Bind targets
The [`bind`](/reference/be/workspace#bind) rule in WORKSPACE is deprecated and
not supported in Bzlmod. It was introduced to give a target an alias in the
special `//external` package. All users depending on this should migrate away.
For example, if you have
```python theme={null}
## WORKSPACE
bind(
name = "openssl",
actual = "@my-ssl//src:openssl-lib",
)
```
This allows other targets to depend on `//external:openssl`. You can migrate
away from this by:
* Replace all usages of `//external:openssl` with `@my-ssl//src:openssl-lib`.
* Tip: Use `bazel query --output=build --noenable_bzlmod --enable_workspace [target]` command to find relevant info
about the target.
* Or use the [`alias`](/reference/be/general#alias) build rule
* Define the following target in a package (e.g. `//third_party`)
```python theme={null}
## third_party/BUILD
alias(
name = "openssl",
actual = "@my-ssl//src:openssl-lib",
)
```
* Replace all usages of `//external:openssl` with `//third_party:openssl`.
### Fetch versus Sync
Fetch and sync commands are used to download external repos locally and keep
them updated. Sometimes also to allow building offline using the `--nofetch`
flag after fetching all repos needed for a build.
* **WORKSPACE**
Sync performs a force fetch for all repositories, or for a specific
configured set of repos, while fetch is *only* used to fetch for a specific
target.
* **Bzlmod**
The sync command is no longer applicable, but fetch offers
[various options](/reference/command-line-reference#fetch-options).
You can fetch a target, a repository, a set of configured repos or all
repositories involved in your dependency resolution and module extensions.
The fetch result is cached and to force a fetch you must include the
`--force` option during the fetch process.
## Manual migration
This section provides useful information and guidance for your **manual** Bzlmod
migration process. For more automatized migration process, check [recommended migration process](#how-migrate-to-bzlmod) section.
### Know your dependencies in WORKSPACE
The first step of migration is to understand what dependencies you have. It
could be hard to figure out what exact dependencies are introduced in the
WORKSPACE file because transitive dependencies are often loaded with `*_deps`
macros.
#### Inspect external dependency with workspace resolved file
Fortunately, the flag
[`--experimental_repository_resolved_file`][resolved_file_flag]
can help. This flag essentially generates a "lock file" of all fetched external
dependencies in your last Bazel command. You can find more details in this [blog post](https://blog.bazel.build/2018/07/09/bazel-sync-and-resolved-file.html).
[resolved_file_flag]: /reference/command-line-reference#flag--experimental_repository_resolved_file
It can be used in two ways:
1. To fetch info of external dependencies needed for building certain targets.
```shell theme={null}
bazel clean --expunge
bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
```
2. To fetch info of all external dependencies defined in the WORKSPACE file.
```shell theme={null}
bazel clean --expunge
bazel sync --experimental_repository_resolved_file=resolved.bzl
```
With the `bazel sync` command, you can fetch all dependencies defined in the
WORKSPACE file, which include:
* `bind` usages
* `register_toolchains` & `register_execution_platforms` usages
However, if your project is cross platforms, bazel sync may break on certain
platforms because some repository rules may only run correctly on supported
platforms.
After running the command, you should have information of your external
dependencies in the `resolved.bzl` file.
#### Inspect external dependency with `bazel query`
You may also know `bazel query` can be used for inspecting repository rules with
```shell theme={null}
bazel query --output=build //external:
```
While it is more convenient and much faster, [bazel query can lie about external dependency version](https://github.com/bazelbuild/bazel/issues/12947),
so be careful using it! Querying and inspecting external
dependencies with Bzlmod is going to achieved by a [new subcommand](https://github.com/bazelbuild/bazel/issues/15365).
#### Built-in default dependencies
If you check the file generated by `--experimental_repository_resolved_file`,
you are going to find many dependencies that are not defined in your WORKSPACE.
This is because Bazel in fact adds prefixes and suffixes to the user's WORKSPACE
file content to inject some default dependencies, which are usually required by
native rules (e.g. `@bazel_tools`, `@platforms` and `@remote_java_tools`). With
Bzlmod, those dependencies are introduced with a built-in module
[`bazel_tools`][bazel_tools] , which is a default dependency for every other
Bazel module.
[bazel_tools]: https://github.com/bazelbuild/bazel/blob/master/src/MODULE.tools
### Hybrid mode for gradual migration
Bzlmod and WORKSPACE can work side by side, which allows migrating dependencies
from the WORKSPACE file to Bzlmod to be a gradual process.
Note: In practice, loading "\*\_deps" macros in WORKSPACE often causes confusions
with Bzlmod dependencies, therefore we recommend starting with a
WORKSPACE.bzlmod file and avoid loading transitive dependencies with macros.
#### WORKSPACE.bzlmod
During the migration, Bazel users may need to switch between builds with and
without Bzlmod enabled. WORKSPACE.bzlmod support is implemented to make the
process smoother.
WORKSPACE.bzlmod has the exact same syntax as WORKSPACE. When Bzlmod is enabled,
if a WORKSPACE.bzlmod file also exists at the workspace root:
* `WORKSPACE.bzlmod` takes effect and the content of `WORKSPACE` is ignored.
* No [prefixes or suffixes](/external/migration#builtin-default-deps) are
added to the WORKSPACE.bzlmod file.
Using the WORKSPACE.bzlmod file can make the migration easier because:
* When Bzlmod is disabled, you fall back to fetching dependencies from the
original WORKSPACE file.
* When Bzlmod is enabled, you can better track what dependencies are left to
migrate with WORKSPACE.bzlmod.
#### Repository visibility
Bzlmod is able to control which other repositories are visible from a given
repository, check [repository names and strict deps](/external/module#repository_names_and_strict_deps) for more details.
Here is a summary of repository visibilities from different types of
repositories when also taking WORKSPACE into consideration.
| | From the main repo | From Bazel module repos | From module extension repos | From WORKSPACE repos |
| - | - | - | - | - |
| The main repo | Visible | If the root module is a direct dependency | If the root module is a direct dependency of the module hosting the module extension | Visible |
| Bazel module repos | Direct deps | Direct deps | Direct deps of the module hosting the module extension | Direct deps of the root module |
| Module extension repos | Direct deps | Direct deps | Direct deps of the module hosting the module extension + all repos generated by the same module extension | Direct deps of the root module |
| WORKSPACE Repos | All visible | Not visible | Not visible | All visible |
Note: For the root module, if a repository `@foo` is defined in WORKSPACE and
`@foo` is also used as an [apparent repository name](/external/overview#apparent-repo-name) in MODULE.bazel, then `@foo`
refers to the one introduced in MODULE.bazel.
Note: For a module extension generated repository `@bar`, if `@foo` is used as
an [apparent repository name](/external/overview#apparent-repo-name) of
another repository generated by the same module extension and direct
dependencies of the module hosting the module extension, then for repository
`@bar`, `@foo` refers to the latter.
### Manual migration process
A typical Bzlmod migration process can look like this:
1. Understand what dependencies you have in WORKSPACE.
2. Add an empty MODULE.bazel file at your project root.
3. Add an empty WORKSPACE.bzlmod file to override the WORKSPACE file content.
4. Build your targets with Bzlmod enabled and check which repository is
missing.
5. Check the definition of the missing repository in the resolved dependency
file.
6. Introduce the missing dependency as a Bazel module, through a module
extension, or leave it in the WORKSPACE.bzlmod for later migration.
7. Go back to 4 and repeat until all dependencies are available.
## Publish Bazel modules
If your Bazel project is a dependency for other projects, you can publish your
project in the [Bazel Central Registry](https://registry.bazel.build/).
To be able to check in your project in the BCR, you need a source archive URL of
the project. Take note of a few things when creating the source archive:
* **Make sure the archive is pointing to a specific version.**
The BCR can only accept versioned source archives because Bzlmod needs to
conduct version comparison during dependency resolution.
* **Make sure the archive URL is stable.**
Bazel verifies the content of the archive by a hash value, so you should
make sure the checksum of the downloaded file never changes. If the URL is
from GitHub, please create and upload a release archive in the release page.
GitHub isn't going to guarantee the checksum of source archives generated on
demand. In short, URLs in the form of
`https://github.com///releases/download/...` is considered stable
while `https://github.com///archive/...` is not. Check [GitHub Archive Checksum Outage](https://blog.bazel.build/2023/02/15/github-archive-checksum.html)
for more context.
* **Make sure the source tree follows the layout of the original repository.**
In case your repository is very large and you want to create a distribution
archive with reduced size by stripping out unnecessary sources, please make
sure the stripped source tree is a subset of the original source tree. This
makes it easier for end users to override the module to a non-release
version by [`archive_override`](/rules/lib/globals/module#archive_override)
and [`git_override`](/rules/lib/globals/module#git_override).
* **Include a test module in a subdirectory that tests your most common
APIs.**
A test module is a Bazel project with its own WORKSPACE and MODULE.bazel
file located in a subdirectory of the source archive which depends on the
actual module to be published. It should contain examples or some
integration tests that cover your most common APIs. Check
[test module][test_module] to learn how to set it up.
[test_module]: https://github.com/bazelbuild/bazel-central-registry/tree/main/docs#test-module
When you have your source archive URL ready, follow the [BCR contribution
guidelines][bcr_contrib_guide] to submit your module to the BCR with a GitHub
Pull Request.
[bcr_contrib_guide]: https://github.com/bazelbuild/bazel-central-registry/tree/main/docs#contribute-a-bazel-module
It is **highly recommended** to set up the [Publish to BCR](https://github.com/bazel-contrib/publish-to-bcr) GitHub App for your
repository to automate the process of submitting your module to the BCR.
## Best practices
This section documents a few best practices you should follow for better
managing your external dependencies.
#### Split targets into different packages to avoid fetching unnecessary dependencies.
Check [#12835](https://github.com/bazelbuild/bazel/issues/12835), where dev
dependencies for tests are forced to be fetched unnecessarily for building
targets that don't need them. This is actually not Bzlmod specific, but
following this practices makes it easier to specify dev dependencies correctly.
#### Specify dev dependencies
You can set the `dev_dependency` attribute to true for
[`bazel_dep`](/rules/lib/globals/module#bazel_dep) and
[`use_extension`](/rules/lib/globals/module#use_extension) directives so that
they don't propagate to dependent projects. As the root module, you can use the
[`--ignore_dev_dependency`][ignore_dev_dep_flag] flag to verify if your targets
still build without dev dependencies and overrides.
[ignore_dev_dep_flag]: /reference/command-line-reference#flag--ignore_dev_dependency
## Community migration progress
You can check the [Bazel Central Registry](https://registry.bazel.build) to find
out if your dependencies are already available. Otherwise feel free to join this
[GitHub discussion](https://github.com/bazelbuild/bazel/discussions/18329) to
upvote or post the dependencies that are blocking your migration.
## Report issues
Please check the [Bazel GitHub issue list][bzlmod_github_issue] for known Bzlmod
issues. Feel free to file new issues or feature requests that can help unblock
your migration!
[bzlmod_github_issue]: https://github.com/bazelbuild/bazel/issues?q=is%3Aopen+is%3Aissue+label%3Aarea-Bzlmod
# Migration tool
Source: https://bazel.build/external/migration_tool
***
## title: 'Bzlmod Migration Tool'
[migration_script]: https://github.com/bazelbuild/bazel-central-registry/blob/main/tools/migrate_to_bzlmod.py
[gemini_cli_setup]: https://github.com/bazelbuild/bazel-central-registry/tree/main/tools/code-agent
To simplify the often complex process of moving from `WORKSPACE` to Bzlmod, it's
highly recommended to use the [migration script][migration_script]. This helper
tool automates many of the steps involved in migrating your external dependency
management system.
**Note**: If you want to try out the AI driven Bzlmod migration, check [Bzlmod Migration Agent Setup][gemini_cli_setup].
## Core Functionality
The script's primary functions are:
* **Collecting dependency information:** Analyzing your project's `WORKSPACE`
file to identify external repositories used by specified build targets,
using Bazel's
[experimental\_repository\_resolved\_file](https://bazel.build/versions/8.2.0/reference/command-line-reference#flag--experimental_repository_resolved_file)
flag to generate a resolved dependencies file containing this information.
* **Identifying direct dependencies:** Using `bazel query` to determine which
repositories are direct dependencies for the specified targets.
* **Migrating to Bzlmod:** Translating relevant `WORKSPACE` dependencies into
their Bzlmod equivalents. This is a two-step process:
1. Introduce all identified direct dependencies to the
`MODULE.bazel` file.
2. Build specified targets with Bzlmod enabled, then
iteratively identify and fix recognizable errors. This step is
needed since some dependencies might be missing in the first step.
* **Generating a migration report:** Creating a `migration_info.md` file that
documents the migration process. This report includes a list of direct
dependencies, the generated Bzlmod declarations, and any manual steps that
may be required to complete the migration.
The migration tool supports:
* Dependencies available in the Bazel Central Registry
* User-defined custom repository rules
* Package manager dependencies
* Maven
* Go
* Python
**Important Notes**:
* The migration tool is a best-effort utility. Always double-check its
recommendations for correctness.
* Use the migration tool with Bazel 7 (not supported with Bazel 8).
## How to Use the Migration Tool
Before you begin:
* Upgrade to the latest Bazel 7 release, which provides robust support for
both WORKSPACE and Bzlmod.
* Verify the following command runs successfully for your project's main build
targets:
```shell theme={null}
bazel build --nobuild --enable_workspace --noenable_bzlmod
```
### Command for running the script
Once the prerequisites are met, run the following commands to use the migration
tool:
# Clone the Bazel Central Registry repository
git clone [https://github.com/bazelbuild/bazel-central-registry.git](https://github.com/bazelbuild/bazel-central-registry.git)
cd bazel-central-registry
# Build the migration tool
bazel build //tools:migrate\_to\_bzlmod
# Create a convenient alias for the tool
alias migrate2bzlmod=\$(realpath ./bazel-bin/tools/migrate\_to\_bzlmod)
# Navigate to your project's root directory and run the tool
cd \
migrate2bzlmod -t \
### Files generated by this script
* `MODULE.bazel` - The central manifest file for Bzlmod, which declares the
project's metadata and its direct dependencies on other Bazel modules.
* `migration_info.md` - A file providing step-by-step instructions on how the
migration tool was executed, designed to assist in the manual completion of
the migration process, if necessary.
* `resolved_deps.py` - Contains a comprehensive list of the project's external
dependencies, generated by analyzing the project's `WORKSPACE` file, serving
as a reference during the transition.
* `query_direct_deps` - Contains migration-relevant information regarding the
utilized targets, obtained by invoking Bazel with `--output=build` on the
project's `WORKSPACE` file. This file is primarily consumed by the migration
script.
* `extension_for_XXX` - A file containing a module extension
definition. The migration tool generates these files for dependencies that
are not standard Bazel modules but can be managed using Bzlmod's [module extensions](/external/extension).
### Flags
Flags available in this migration scripts are:
* `--t`/`--target`: Targets to migrate. This flag is repeatable, and the
targets are accumulated.
* `--i`/`--initial`: Deletes `MODULE.bazel`, `resolved_deps.py`,
`migration_info.md` files and starts from scratch - Detect direct
dependencies, introduce them in MODULE.bazel and rerun generation of
resolved dependencies.
### Post-migration cleanup
* Delete `migration_info.md`, `resolved_deps.py` and `query_direct_deps`.
* Clean up comments from `MODULE.bazel` file which were used for the
migration, such as `# -- bazel_dep definitions -- #`.
## Migration Example
To see the migration script in action, consider the following scenario when
Python, Maven and Go dependencies are declared in `WORKSPACE` file.
Click here to see `WORKSPACE` file
```python theme={null}
workspace(name="example")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load(":my_custom_macro.bzl", "my_custom_macro")
http_archive(
name = "rules_cc",
sha256 = "b8b918a85f9144c01f6cfe0f45e4f2838c7413961a8ff23bc0c6cdf8bb07a3b6",
strip_prefix = "rules_cc-0.1.5",
urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.1.5/rules_cc-0.1.5.tar.gz"],
)
# Module dependency
# -------------------
http_archive(
name = "rules_shell",
sha256 = "3e114424a5c7e4fd43e0133cc6ecdfe54e45ae8affa14fadd839f29901424043",
strip_prefix = "rules_shell-0.4.0",
url = "https://github.com/bazelbuild/rules_shell/releases/download/v0.4.0/rules_shell-v0.4.0.tar.gz",
)
# Repo rule
# -------------------
http_archive(
name = "com_github_cockroachdb_cockroach",
sha256 = "6c3568ef244ce6b874694eeeecb83ed4f5d5dff6cf037c952ecde76828a6c502",
strip_prefix = "cockroach-22.1.6",
url = "https://github.com/cockroachdb/cockroach/archive/v22.1.6.tar.gz",
)
# Module extension
# -------------------
# Macro which invokes repository_rule
my_custom_macro(
name = "my_custom_repo",
)
# Go dependencies
# -------------------
http_archive(
name = "io_bazel_rules_go",
integrity = "sha256-M6zErg9wUC20uJPJ/B3Xqb+ZjCPn/yxFF3QdQEmpdvg=",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip",
"https://github.com/bazelbuild/rules_go/releases/download/v0.48.0/rules_go-v0.48.0.zip",
],
)
http_archive(
name = "bazel_gazelle",
integrity = "sha256-12v3pg/YsFBEQJDfooN6Tq+YKeEWVhjuNdzspcvfWNU=",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz",
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.37.0/bazel-gazelle-v0.37.0.tar.gz",
],
)
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
go_rules_dependencies()
go_register_toolchains(version = "1.23.1")
gazelle_dependencies()
go_repository(
name = "org_golang_x_net",
importpath = "golang.org/x/net",
sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=",
version = "v0.0.0-20190311183353-d8887717615a",
build_file_proto_mode = "disable",
build_naming_convention = "import",
)
# Python dependencies
# -------------------
http_archive(
name = "rules_python",
integrity = "sha256-qDdnnxOC8mlowe5vg5x9r5B5qlMSgGmh8oFd7KpjcwQ=",
strip_prefix = "rules_python-1.4.0",
url = "https://github.com/bazelbuild/rules_python/releases/download/1.4.0/rules_python-1.4.0.tar.gz",
)
load("@rules_python//python:repositories.bzl", "py_repositories")
py_repositories()
load("@rules_python//python:pip.bzl", "pip_parse")
pip_parse(
name = "my_python_deps",
requirements_lock = "@example//:requirements_lock.txt",
)
load("@my_python_deps//:requirements.bzl", "install_deps")
install_deps()
load("@rules_python//python:repositories.bzl", "python_register_toolchains")
python_register_toolchains(
name = "python_3_11",
python_version = "3.11",
)
# Maven dependencies
# __________________
RULES_JVM_EXTERNAL_TAG = "4.5"
RULES_JVM_EXTERNAL_SHA = "b17d7388feb9bfa7f2fa09031b32707df529f26c91ab9e5d909eb1676badd9a6"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
rules_jvm_external_setup()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
name = "px_deps",
artifacts = [
"org.antlr:antlr4:4.11.1",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
```
Moreover, to demonstrate usage of module extension, custom macro is invoked from
`WORKSPACE` and it is defined in `my_custom_macro.bzl`.
Click here to see `my_custom_macro.bzl` file
```python theme={null}
"""Repo rule and macro used for testing"""
def _test_repo_rule_impl(repository_ctx):
repository_ctx.file(
"BUILD",
content = """
genrule(
name = "foo",
outs = ["rule_name.out"],
cmd = "touch $@",
visibility = ["//visibility:public"],
)
"""
)
_test_repo_rule = repository_rule(
implementation = _test_repo_rule_impl,
)
def my_custom_macro(name):
_test_repo_rule(name = name)
```
The end goal is to have `MODULE.bazel` file and delete the `WORKSPACE` file,
without impacting the user experience.
The first step is to follow [How to Use the Migration Tool](#migration-tool-how-to-use), which mostly is checking the bazel version
(it must be Bazel 7) and adding an alias to the migration script.
Then, running `migrate2bzlmod -t=//...` outputs:
bazel 7.6.1
Generating ./resolved\_deps.py file - It might take a while...
RESOLVED: `rules_java` has been introduced as a Bazel module.
RESOLVED: `bazel_gazelle` has been introduced as a Bazel module.
RESOLVED: `io_bazel_rules_go` has been introduced as a Bazel module.
RESOLVED: `rules_python` has been introduced as a Bazel module.
IMPORTANT: 3.11 is used as a default python version. If you need a different version, please change it manually and then rerun the migration tool.
RESOLVED: `my_python_deps` has been introduced as python extension.
RESOLVED: `org_golang_x_net` has been introduced as go extension.
RESOLVED: `rules_jvm_external` has been introduced as a Bazel module.
RESOLVED: `org.antlr` has been introduced as maven extension.
RESOLVED: `rules_shell` has been introduced as a Bazel module.
Congratulations! All external repositories needed for building //... are available with Bzlmod!
IMPORTANT: Fix potential build time issues by running the following command:
bazel build --enable\_bzlmod --noenable\_workspace //...
IMPORTANT: `For details about the migration process, check migration_info.md file.`
which gives the following important information:
* Generates `./resolved_deps.py` file, which contains info about all external
repositories declared and loaded using your `WORKSPACE` file.
* `RESOLVED` keyword describes all dependencies which are resolved by the tool
and added to the `MODULE.bazel` file.
* `IMPORTANT` keyword describes significant information worth investing time.
* All dependencies have been resolved in this example, at least with
`--nobuild` flag.
* It is important to run the full build (command specified) and manually fix
potential errors (e.g. toolchain not registered correctly).
* `migration_info.md` file contains details about the migration. Check details
[at this section](#migration-tool-report-generation).
### Transformations
This section illustrates the migration of code from the `WORKSPACE` file to
`MODULE.bazel`.
**WORKSPACE - Bazel Module**
***
## Tips with debugging
This section provides useful commands and information to help debug issues that
may arise during the Bzlmod migration.
### Useful tips
* Override version - Not rarely it happens that upgrading the version of a
dependency causes troubles. Bzlmod could change the version of the
dependency due to the [MVS algorithm](/external/module#version-selection).
In order to use the same or similar version as it was in the WORKSPACE,
override it with
[single\_version\_override](/rules/lib/globals/module#single_version_override).
Note that this is useful for debugging differences between WORKSPACE and
Bzlmod, but you shouldn't rely on this feature in the long term.
`single_version_override(module_name = "{dep_name}", version = "{version}")`
* Use [bazel mod](/external/mod-command#syntax) command.
* Check the version of a specified repo with `show_repo`
command. For example:
`bazel mod show_repo @rules_python`
* Check information about a module extension with the `show_extension`
command. For example:
`bazel mod show_extension @rules_python//python/extensions:pip.bzl%pip`
* Use [vendor mode](/external/vendor) to create a local copy of a repo when
you want to monitor or control the source of the repo. For example:
`bazel vendor --enable_bzlmod --vendor_dir=vendor_src --repo=@protobuf`
### Migration Report Generation
This file is updated with each run of the migration script or it's generated
from scratch if it's the first run or if the [`--i` flag](#migration-script-flags) is used. The report contains:
* Command for local testing.
* List of direct dependencies (at least the ones which are directly used in
the project).
* For each dependency, a drop-down menu for checking where the repository was
declared in the `WORKSPACE` file, which is particularly useful for the
debugging. You can see it as:
> Click here to see where and how the repo was declared in the WORKSPACE
> file
* For each dependency, how it was implemented in `MODULE.bazel` file. From the
earlier [Migration Example](#migration-tool-example), that would look as:
1. Bazel module Dependency - `Migration of rules_python`
Found perfect name match in BCR: rules\_python
Found partially name matches in BCR: rules\_python\_gazelle\_plugin
It has been introduced as a Bazel module:
`bazel_dep(name = "rules_python", version = "1.6.1")`
* The script will automatically use the `perfect name match` if it finds
it. In case of an error, you can double check if the name was correctly
added.
2. Python extension - `Migration of my_python_deps`
* It has been introduced as a go module with the help of `go.mod`. If
`go.mod` and `go.sum` are not available, go module is added directly
to the `MODULE.bazel` file.
* `gazelle_override` is used for adding specific directives.
## Useful links
* Official pages for the external extensions
* [rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external/blob/master/docs/bzlmod.md)
* [rules\_go](https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md)
* [rules\_python](https://rules-python.readthedocs.io/en/latest/pypi/download.html)
* Community posts and videos
* [Migrating to Bazel Modules](https://blog.engflow.com/2025/01/16/migrating-to-bazel-modules-aka-bzlmod---module-extensions/index.html#migrating-to-bazel-modules-aka-bzlmod-module-extensions).
* [Moving to Bzlmod](https://www.youtube.com/watch?v=W9uXRYLVHUk).
* [How Uber Manages Go Dependencies with Bzlmod](https://www.youtube.com/watch?v=hIqzkUE_pSY).
## Feedback
If you would like to contribute, do so by creating an Issue or PR at
[bazel-central-registry](https://github.com/bazelbuild/bazel-central-registry).
# Mod command
Source: https://bazel.build/external/mod-command
***
## title: '`mod` Command'
The `mod` command provides a range of tools to help the user understand their
external dependency graph. It lets you visualize the dependency graph, find out
why a certain module or a version of a module is present in the graph, view the
repo definitions backing modules, inspect usages of module extensions and repos
they generate, among other functions.
## Syntax
```sh theme={null}
bazel mod [] [ [...]]
```
The available subcommands and their respective required arguments are:
* `tidy`: Formats `MODULE.bazel` and its included module files and updates
`use_repo` calls for supported module extensions. Also evaluates all
extensions in the dependency graph to update `MODULE.bazel.lock`.
* `graph`: Displays the full dependency graph of the project, starting from
the root module. If one or more modules are specified in `--from`, these
modules are shown directly under the root, and the graph is only expanded
starting from them (see [example](#mod-example1)).
* `deps ...`: Displays the resolved direct dependencies of each of the
specified modules, similarly to `graph`.
* `all_paths ...`: Displays all dependency paths from the --from modules
to the target modules. To simplify the output, only the first shortest path
is shown when multiple paths share the same suffix. For example, A -> B -> X
would be shown, but the longer A -> C -> B -> X would be omitted. In other
words, for every module Y that directly depends on the target module X, the
output contains only the shortest path going through Y to reach X.
* `path ...`: Has the same semantics as `all_paths`, but only display a
single path from one of the `--from` modules to one of the argument modules.
* `explain ...`: Shows all the places where the specified modules appear
in the dependency graph, along with the modules that directly depend on
them. The output of the `explain` command is essentially a pruned version of
the `all_paths` command, containing 1) the root module; 2) the root module's
direct dependencies that lead to the argument modules; 3) the argument
modules' direct dependents; and
4\) the argument modules themselves (see [example](#mod-example5)).
* `show_repo ...`: Displays the definition and location of the
specified repos (see [example](#mod-example6)). This does not cause the
repos to be materialized, use `bazel fetch` for that. Use `--all_repos` to
show definitions of all repos in the entire dependency graph, or
`--all_visible_repos` to show definitions of all repos visible from the
`--base_module`.
* `show_extension ...`: Displays information about each of the
specified extensions: a list of the generated repos along with the modules
that import them using `use_repo`, and a list of the usages of that
extension in each of the modules where it is used, containing the specified
tags and the `use_repo` calls (see [example](#mod-example8)).
`` refers to one or more modules or repos. It can be one of:
* The literal string ``: The root module representing your current
project.
* `@`: The module `` at version ``. For a module
with a non-registry override, use an underscore (`_`) as the ``.
* ``: All present versions of the module ``.
* `@`: The repo with the given [apparent name](/external/overview#apparent-repo-name) in the context of the `--base_module`.
* `@@`: The repo with the given [canonical name](/external/overview#canonical-repo-name).
In a context requiring specifying modules, ``s referring to repos that
correspond to modules (as opposed to extension-generated repos) can also be
used. Conversely, in a context requiring specifying repos, ``s referring to
modules can stand in for the corresponding repos.
`` must be of the form `%`.
The `` part must be a repo-relative label (for example,
`//pkg/path:file.bzl`).
### Graph command options
The following options only affect the subcommands that print graphs (`graph`,
`deps`, `all_paths`, `path`, and `explain`):
* `--from [,[,...]]` *default: ``*: The module(s) from which
the graph is expanded in `graph`, `all_paths`, `path`, and `explain`. Check
the subcommands' descriptions for more details.
* `--verbose` *default: "false"*: Include in the output graph extra
information about the version resolution of each module. If the module
version changed during resolution, show either which version replaced it or
what was the original version, the reason it was replaced, and which modules
requested the new version if the reason was [Minimal Version Selection](/external/module#version-selection).
* `--include_unused` *default: "false"*: Include in the output graph the
modules which were originally present in the dependency graph, but became
unused after module resolution.
* `--extension_info mode`: Include information about the module extension
usages as part of the output graph (see [example](#mod-example7)). `mode`
can be one of:
* `hidden` *(default)*: Don't show anything about extensions.
* `usages`: Show extensions under each module where they are used. They
are printed in the form of `$`.
* `repos`: In addition to `usages`, show the repo imported using
`use_repo` under each extension usage.
* `all`: In addition to `usages` and `repos`, also show
extension-generated repos that are not imported by any module. These
extra repos are shown under the first occurrence of their generating
extension in the output, and are connected with a dotted edge.
* `--extension_filter [,[,...]]`: If specified, the
output graph only includes modules that use the specified extensions, and
the paths that lead to those modules. Specifying an empty extension list (as
in `--extension_filter=`) is equivalent to specifying *all* extensions used
by any module in the dependency graph.
* `--depth `: The depth of the output graph. A depth of 1 only displays the
root and its direct dependencies. Defaults to 1 for `explain`, 2 for `deps`
and infinity for the others.
* `--cycles` *default: "false"*: Include cycle edges in the output graph.
* `--include_builtin` *default: "false"*: Include built-in modules (such as
`@bazel_tools`) in the output graph. This flag is disabled by default, as
built-in modules are implicitly depended on by every other module, which
greatly clutters the output.
* `--charset ` *default: utf8*: Specify the charset to use for text
output. Valid values are `"utf8"` and `"ascii"`. The only significant
difference is in the special characters used to draw the graph in the
`"text"` output format, which don't exist in the `"ascii"` charset.
Therefore, the `"ascii"` charset is present to also support the usage on
legacy platforms which cannot use Unicode.
* `--output mode`: Include information about the module extension usages as
part of the output graph. \`mode' can be one of:
* `text` *(default)*: A human-readable representation of the output graph
(flattened as a tree).
* `json`: Outputs the graph in the form of a JSON object (flattened as a
tree).
* `graph`: Outputs the graph in the Graphviz *dot* representation.
Tip: Use the following command to pipe the output through the *dot* engine
and export the graph representation as an SVG image.
```sh theme={null}
bazel mod graph --output graph | dot -Tsvg > /tmp/graph.svg
```
### show\_repo options
`show_repo` supports a different set of output formats:
* `--output mode`: Change how repository definitions are displayed.
`mode` can be one of:
* `text` *(default)*: Display repo definitions in Starlark.
* `streamed_proto`: Prints a
[length-delimited](https://protobuf.dev/programming-guides/encoding/#size-limit)
stream of
[`Repository`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffers.
* `streamed_jsonproto`: Similar to `--output streamed_proto`, prints a
stream of [`Repository`](https://github.com/bazelbuild/bazel/blob/master/src/main/protobuf/build.proto)
protocol buffers but in [NDJSON](https://github.com/ndjson/ndjson-spec) format.
### Other options
Other options include:
* `--base_module ` *default: ``*: Specify a module relative to
which apparent repo names in arguments are interpreted. Note that this
argument itself can be in the form of `@`; this is always
interpreted relative to the root module.
* `--extension_usages [,[,...]]`: Filters `show_extension` to only
display extension usages from the specified modules.
## Examples
Some possible usages of the `mod` command on a real Bazel project are showcased
below to give you a general idea on how you can use it to inspect your project's
external dependencies.
`MODULE.bazel` file:
```python theme={null}
module(
name = "my_project",
version = "1.0",
)
bazel_dep(name = "bazel_skylib", version = "1.1.1", repo_name = "skylib1")
bazel_dep(name = "bazel_skylib", version = "1.2.0", repo_name = "skylib2")
multiple_version_override(module_name = "bazel_skylib", versions = ["1.1.1", "1.2.0"])
bazel_dep(name = "stardoc", version = "0.5.0")
bazel_dep(name = "rules_java", version = "5.0.0")
toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains")
use_repo(toolchains, my_jdk="remotejdk17_linux")
```

Graph Before Resolution

Graph After Resolution
1. Display the whole dependency graph of your
project.
```sh theme={null}
bazel mod graph
```
```none theme={null}
(my_project@1.0)
├───bazel_skylib@1.1.1
│ └───platforms@0.0.4
├───bazel_skylib@1.2.0
│ └───platforms@0.0.4 ...
├───rules_java@5.0.0
│ ├───platforms@0.0.4 ...
│ ├───rules_cc@0.0.1
│ │ ├───bazel_skylib@1.1.1 ...
│ │ └───platforms@0.0.4 ...
│ └───rules_proto@4.0.0
│ ├───bazel_skylib@1.1.1 ...
│ └───rules_cc@0.0.1 ...
└───stardoc@0.5.0
├───bazel_skylib@1.1.1 ...
└───rules_java@5.0.0 ...
```
Note: The `...` symbol indicates that the node has already been expanded
somewhere else and was not expanded again to reduce noise.
2. Display the whole dependency graph (including
unused modules and with extra information about version resolution).
```sh theme={null}
bazel mod graph --include_unused --verbose
```
```none theme={null}
(my_project@1.0)
├───bazel_skylib@1.1.1
│ └───platforms@0.0.4
├───bazel_skylib@1.2.0
│ └───platforms@0.0.4 ...
├───rules_java@5.0.0
│ ├───platforms@0.0.4 ...
│ ├───rules_cc@0.0.1
│ │ ├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
│ │ ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
│ │ └───platforms@0.0.4 ...
│ └───rules_proto@4.0.0
│ ├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
│ ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
│ └───rules_cc@0.0.1 ...
└───stardoc@0.5.0
├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
├───rules_java@5.0.0 ... (was 4.0.0, cause , bazel_tools@_)
├───bazel_skylib@1.0.3 (to 1.1.1, cause multiple_version_override)
│ └───platforms@0.0.4 ...
└───rules_java@4.0.0 (to 5.0.0, cause , bazel_tools@_)
├───bazel_skylib@1.0.3 ... (to 1.1.1, cause multiple_version_override)
└───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
```
3. Display the dependency graph expanded from
some specific modules.
```sh theme={null}
bazel mod graph --from rules_java --include_unused
```
```none theme={null}
(my_project@1.0)
├───rules_java@5.0.0
│ ├───platforms@0.0.4
│ ├───rules_cc@0.0.1
│ │ ├───bazel_skylib@1.0.3 ... (unused)
│ │ ├───bazel_skylib@1.1.1 ...
│ │ └───platforms@0.0.4 ...
│ └───rules_proto@4.0.0
│ ├───bazel_skylib@1.0.3 ... (unused)
│ ├───bazel_skylib@1.1.1 ...
│ └───rules_cc@0.0.1 ...
└╌╌rules_java@4.0.0 (unused)
├───bazel_skylib@1.0.3 (unused)
│ └───platforms@0.0.4 ...
└───bazel_skylib@1.1.1
└───platforms@0.0.4 ...
```
Note: The dotted line is used to indicate an *indirect* (transitive)
dependency edge between two nodes.
4. Display all paths between two of your
modules.
```sh theme={null}
bazel mod all_paths bazel_skylib@1.1.1 --from rules_proto
```
```none theme={null}
(my_project@1.0)
└╌╌rules_proto@4.0.0
├───bazel_skylib@1.1.1
└───rules_cc@0.0.1
└───bazel_skylib@1.1.1 ...
```
5. See why and how your project depends on some
module(s).
```sh theme={null}
bazel mod explain @skylib1 --verbose --include_unused
```
```none theme={null}
(my_project@1.0)
├───bazel_skylib@1.1.1
├───rules_java@5.0.0
│ ├───rules_cc@0.0.1
│ │ └───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
│ └───rules_proto@4.0.0
│ ├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
│ └───rules_cc@0.0.1 ...
└───stardoc@0.5.0
├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
├╌╌rules_cc@0.0.1
│ └───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
└╌╌rules_proto@4.0.0
├───bazel_skylib@1.1.1 ... (was 1.0.3, cause multiple_version_override)
└───rules_cc@0.0.1 ...
```
6. See the underlying rule of some your modules'
repos.
```sh theme={null}
bazel mod show_repo rules_cc stardoc
```
`bazel mod show_repo` also works with repos imported by `use_repo` and repos
created with `use_repo_rule`. If `show_repo` is invoked with an apparent
repository name or `--all_visible_repos`, then the apparent repository name
is shown on a line prefixed with `##`.
```sh theme={null}
bazel mod show_repo @jq_linux_arm64
bazel mod show_repo --all_visible_repos
```
```none theme={null}
## rules_cc@0.0.1:
# Located at: /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/rules_cc+
#
http_archive(
name = "rules_cc+",
urls = ["https://bcr.bazel.build/test-mirror/github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz", "https://github.com/bazelbuild/rules_cc/releases/download/0.0.1/rules_cc-0.0.1.tar.gz"],
integrity = "sha256-Tcy/0iwN7xZMj0dFi9UODHFI89kgAs20WcKpamhJgkE=",
strip_prefix = "",
remote_patches = {"https://bcr.bazel.build/modules/rules_cc/0.0.1/patches/add_module_extension.patch": "sha256-g3+zmGs0YT2HKOVevZpN0Jet89Ylw90Cp9XsIAY8QqU="},
remote_patch_strip = 1,
)
# Rule http_archive defined at (most recent call last):
# /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in
## stardoc:
# Located at: /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/stardoc+
#
http_archive(
name = "stardoc+",
urls = ["https://bcr.bazel.build/test-mirror/github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz", "https://github.com/bazelbuild/stardoc/releases/download/0.5.0/stardoc-0.5.0.tar.gz"],
integrity = "sha256-yXlNzIAmow/2fPfPkeviRcopSyCwcYRdEsGSr+JDrXI=",
strip_prefix = "",
remote_patches = {},
remote_patch_strip = 0,
)
# Rule http_archive defined at (most recent call last):
# /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in
```
```none theme={null}
## @jq_linux_arm64:
load("@@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "+http_file+jq_linux_arm64",
executable = True,
integrity = "sha256-TdLYoGYd8LIvG7mh+YMPBrbzuPfZEhGh7118TwaotKU=",
urls = ["https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-arm64"],
)
```
```sh theme={null}
bazel mod graph --extension_info=usages
```
```none theme={null}
(my_project@1.0)
├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
├───rules_java@5.0.0 #
│ ├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
│ ├───rules_cc@0.0.1 #
│ │ └───$@@rules_cc.0.0.1//bzlmod:extensions.bzl%cc_configure
│ └───rules_proto@4.0.0
│ └───rules_cc@0.0.1 ...
└───stardoc@0.5.0
└───rules_java@5.0.0 ...
```
7. See what repositories are generated and
imported from some specific extension as part of the dependency graph.
```sh theme={null}
bazel mod show_extension @@rules_java+5.0.0//java:extensions.bzl%toolchains
```
```none theme={null}
(my_project@1.0)
├───$@@rules_java.5.0.0//java:extensions.bzl%toolchains
│ ├───remotejdk17_linux
│ ├╌╌remotejdk11_linux
│ ├╌╌remotejdk11_linux_aarch64
│ ├╌╌remotejdk11_linux_ppc64le
│ ├╌╌remotejdk11_linux_s390x
...(some lines omitted)...
├───rules_java@5.0.0 #
│ └───$@@rules_java.5.0.0//java:extensions.bzl%toolchains ...
│ ├───local_jdk
│ ├───remote_java_tools
│ ├───remote_java_tools_darwin
│ ├───remote_java_tools_linux
│ ├───remote_java_tools_windows
│ ├───remotejdk11_linux_aarch64_toolchain_config_repo
│ ├───remotejdk11_linux_ppc64le_toolchain_config_repo
...(some lines omitted)...
└───stardoc@0.5.0
└───rules_java@5.0.0 ...
```
8. See the list of generated repositories of an
extension and how that extension is used in each module.
```sh theme={null}
bazel mod graph --extension_info=all --extension_filter=@rules_java//java:extensions.bzl%toolchains
```
```none theme={null}
## @@rules_java.5.0.0//java:extensions.bzl%toolchains:
Fetched repositories:
- local_jdk (imported by bazel_tools@_, rules_java@5.0.0)
- remote_java_tools (imported by bazel_tools@_, rules_java@5.0.0)
- remote_java_tools_darwin (imported by bazel_tools@_, rules_java@5.0.0)
- remote_java_tools_linux (imported by bazel_tools@_, rules_java@5.0.0)
- remote_java_tools_windows (imported by bazel_tools@_, rules_java@5.0.0)
- remotejdk11_linux_aarch64_toolchain_config_repo (imported by rules_java@5.0.0)
- remotejdk11_linux_ppc64le_toolchain_config_repo (imported by rules_java@5.0.0)
...(some lines omitted)...
- remotejdk17_linux (imported by )
- remotejdk11_linux
- remotejdk11_linux_aarch64
- remotejdk11_linux_ppc64le
- remotejdk11_linux_s390x
- remotejdk11_macos
...(some lines omitted)...
# Usage in at /MODULE.bazel:14:27 with the specified attributes:
use_repo(
toolchains,
my_jdk="remotejdk17_linux",
)
# Usage in bazel_tools@_ at bazel_tools@_/MODULE.bazel:23:32 with the specified attributes:
use_repo(
toolchains,
"local_jdk",
"remote_java_tools",
"remote_java_tools_linux",
"remote_java_tools_windows",
"remote_java_tools_darwin",
)
# Usage in rules_java@5.0.0 at rules_java@5.0.0/MODULE.bazel:30:27 with the specified attributes:
use_repo(
toolchains,
"remote_java_tools",
"remote_java_tools_linux",
"remote_java_tools_windows",
"remote_java_tools_darwin",
"local_jdk",
"remotejdk11_linux_toolchain_config_repo",
"remotejdk11_macos_toolchain_config_repo",
"remotejdk11_macos_aarch64_toolchain_config_repo",
...(some lines omitted)...
)
```
9. See the underlying rule of some
extension-generated repositories.
```sh theme={null}
bazel mod show_repo --base_module=rules_java @remote_java_tools
```
```none theme={null}
## @remote_java_tools:
#
http_archive(
name = "rules_java++toolchains+remote_java_tools",
urls = ["https://mirror.bazel.build/bazel_java_tools/releases/java/v11.5/java_tools-v11.5.zip", "https://github.com/bazelbuild/java_tools/releases/download/java_v11.5/java_tools-v11.5.zip"],
sha256 = "b763ee80e5754e593fd6d5be6d7343f905bc8b73d661d36d842b024ca11b6793",
)
# Rule http_archive defined at (most recent call last):
# /home/user/.cache/bazel/_bazel_user/6e893e0f5a92cc4cf5909a6e4b2770f9/external/bazel_tools/tools/build_defs/repo/http.bzl:355:31 in
```
# Bazel modules
Source: https://bazel.build/external/module
A Bazel **module** is a Bazel project that can have multiple versions, each of
which publishes metadata about other modules that it depends on. This is
analogous to familiar concepts in other dependency management systems, such as a
Maven *artifact*, an npm *package*, a Go *module*, or a Cargo *crate*.
A module must have a `MODULE.bazel` file at its repo root. This file is the
module's manifest, declaring its name, version, list of direct dependencies, and
other information. For a basic example:
```python theme={null}
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
```
See the [full list](/rules/lib/globals/module) of directives available in
`MODULE.bazel` files.
To perform module resolution, Bazel starts by reading the root module's
`MODULE.bazel` file, and then repeatedly requests any dependency's
`MODULE.bazel` file from a [Bazel registry](/external/registry) until it
discovers the entire dependency graph.
By default, Bazel then [selects](#version-selection) one version of each module
to use. Bazel represents each module with a repo, and consults the registry
again to learn how to define each of the repos.
## Version format
Bazel has a diverse ecosystem and projects use various versioning schemes. The
most popular by far is [SemVer](https://semver.org), but there are
also prominent projects using different schemes such as
[Abseil](https://github.com/abseil/abseil-cpp/releases), whose
versions are date-based, for example `20210324.2`).
For this reason, Bazel adopts a more relaxed version of the SemVer spec. The
differences include:
* SemVer prescribes that the "release" part of the version must consist of 3
segments: `MAJOR.MINOR.PATCH`. In Bazel, this requirement is loosened so
that any number of segments is allowed.
* In SemVer, each of the segments in the "release" part must be digits only.
In Bazel, this is loosened to allow letters too, and the comparison
semantics match the "identifiers" in the "prerelease" part.
* Additionally, the semantics of major, minor, and patch version increases are
not enforced.
Any valid SemVer version is a valid Bazel module version. Additionally, two
SemVer versions `a` and `b` compare `a < b` if and only if the same holds when
they're compared as Bazel module versions.
Finally, to learn more about module versioning, [see the `MODULE.bazel` FAQ](/external/faq#module-versioning-best-practices).
## Version selection
Consider the diamond dependency problem, a staple in the versioned dependency
management space. Suppose you have the dependency graph:
```
A 1.0
/ \
B 1.0 C 1.1
| |
D 1.0 D 1.1
```
Which version of `D` should be used? To resolve this question, Bazel uses the
[Minimal Version Selection](https://research.swtch.com/vgo-mvs)
(MVS) algorithm introduced in the Go module system. MVS assumes that all new
versions of a module are backwards compatible, and so picks the highest version
specified by any dependent (`D 1.1` in our example). It's called "minimal"
because `D 1.1` is the earliest version that could satisfy our requirements —
even if `D 1.2` or newer exists, we don't select them. Using MVS creates a
version selection process that is *high-fidelity* and *reproducible*.
### Yanked versions
The registry can declare certain versions as *yanked* if they should be avoided
(such as for security vulnerabilities). Bazel throws an error when selecting a
yanked version of a module. To fix this error, either upgrade to a newer,
non-yanked version, or use the
[`--allow_yanked_versions`](/reference/command-line-reference#flag--allow_yanked_versions)
flag to explicitly allow the yanked version.
## Overrides
Specify overrides in the `MODULE.bazel` file to alter the behavior of Bazel
module resolution. Only the root module's overrides take effect — if a module is
used as a dependency, its overrides are ignored.
Each override is specified for a certain module name, affecting all of its
versions in the dependency graph. Although only the root module's overrides take
effect, they can be for transitive dependencies that the root module does not
directly depend on.
### Single-version override
The [`single_version_override`](/rules/lib/globals/module#single_version_override)
serves multiple purposes:
* With the `version` attribute, you can pin a dependency to a specific
version, regardless of which versions of the dependency are requested in the
dependency graph.
* With the `registry` attribute, you can force this dependency to come from a
specific registry, instead of following the normal [registry selection](/external/registry#selecting_registries) process.
* With the `patch*` attributes, you can specify a set of patches to apply to
the downloaded module.
These attributes are all optional and can be mixed and matched with each other.
### Multiple-version override
A [`multiple_version_override`](/rules/lib/globals/module#multiple_version_override)
can be specified to allow multiple versions of the same module to coexist in the
resolved dependency graph.
If there are multiple versions of the same module remaining in the dependency
graph, Bazel will pick the nearest higher allowed version for each dependent.
For example, if versions `1.1`, `1.3`, `1.5`, `1.7`, and `2.0` exist in the
dependency graph before resolution:
* A multiple-version override allowing `1.3`, `1.7`, and `2.0` results in
`1.1` being upgraded to `1.3`, `1.5` being upgraded to `1.7`, and other
versions remaining the same.
* A multiple-version override allowing `1.9` and `2.0` results in an error, as
`1.9` is not present in the dependency graph before resolution.
Additionally, users can also override the registry using the `registry`
attribute, similarly to single-version overrides.
### Non-registry overrides
Non-registry overrides completely remove a module from version resolution. Bazel
does not request these `MODULE.bazel` files from a registry, but instead from
the repo itself.
Bazel supports the following non-registry overrides:
* [`archive_override`](/rules/lib/globals/module#archive_override)
* [`git_override`](/rules/lib/globals/module#git_override)
* [`local_path_override`](/rules/lib/globals/module#local_path_override)
Note that setting a version value in the source archive `MODULE.bazel` can have
downsides when the module is being overridden with a non-registry override. To
learn more about this [see the `MODULE.bazel` FAQ](/external/faq#module-versioning-best-practices).
### Command-line overrides
Some overrides can also be specified on the command line, without editing the
root module's `MODULE.bazel` file:
* [`--override_module`](/reference/command-line-reference#flag--override_module)
overrides a module that is already in the dependency graph with a local
directory, like `local_path_override`.
* [`--inject_module`](/reference/command-line-reference#flag--inject_module)
adds a new module from a local directory as a dependency of the root
module, as if the root module contained a `bazel_dep` together with a
`local_path_override`. The module's own `MODULE.bazel` file is honored, so
its dependencies, toolchains, and execution platforms are added to the
build. This is useful for injecting machine-specific configuration, such as
remote execution platforms, into a project you don't want to modify.
Note that these flags may still cause the project's
[lockfile](/external/lockfile) to change: for example, the registry files of
any new dependencies they bring in are recorded in `MODULE.bazel.lock`. You may
also need to pass the flag
[`--lockfile_mode=update`](/reference/command-line-reference#flag--lockfile_mode).
With `--lockfile_mode=error`, the build would fail if the changed modules
require changes to the lockfile.
## Define repos that don't represent Bazel modules
With `bazel_dep`, you can define repos that represent other Bazel modules.
Sometimes there is a need to define a repo that does *not* represent a Bazel
module; for example, one that contains a plain JSON file to be read as data.
In this case, you could use the [`use_repo_rule` directive](/rules/lib/globals/module#use_repo_rule) to directly define a repo
by invoking a repo rule. This repo will only be visible to the module it's
defined in.
Under the hood, this is implemented using the same mechanism as [module extensions](/external/extension), which lets you define repos with more
flexibility.
## Repository names and strict deps
The [apparent name](/external/overview#apparent-repo-name) of a repo backing a
module to its direct dependents defaults to its module name, unless the
`repo_name` attribute of the [`bazel_dep`](/rules/lib/globals/module#bazel_dep)
directive says otherwise. Note that this means a module can only find its direct
dependencies. This helps prevent accidental breakages due to changes in
transitive dependencies.
The [canonical name](/external/overview#canonical-repo-name) of a repo backing a
module is either `module_name+version` (for example, `bazel_skylib+1.0.3`) or `module_name+` (for example, `bazel_features+`), depending on whether there are
multiple versions of the module in the entire dependency graph (see
[`multiple_version_override`](/rules/lib/globals/module#multiple_version_override)).
Note that **the canonical name format** is not an API you should depend on and
**is subject to change at any time**. Instead of hard-coding the canonical name,
use a supported way to get it directly from Bazel:
* In BUILD and `.bzl` files, use
[`Label.repo_name`](/rules/lib/builtins/Label#repo_name) on a `Label` instance
constructed from a label string given by the apparent name of the repo, e.g.,
`Label("@bazel_skylib").repo_name`.
* When looking up runfiles, use
[`$(rlocationpath ...)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)
or one of the runfiles libraries in
`@bazel_tools//tools/{bash,cpp,java}/runfiles` or, for a ruleset `rules_foo`,
in `@rules_foo//foo/runfiles`.
* When interacting with Bazel from an external tool such as an IDE or language
server, use the `bazel mod dump_repo_mapping` command to get the mapping from
apparent names to canonical names for a given set of repositories.
[Module extensions](/external/extension) can also introduce additional repos
into the visible scope of a module.
# External dependencies overview
Source: https://bazel.build/external/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
Bazel's external dependency system works on the basis of [*Bazel modules*](#module), each of which is a versioned Bazel project, and
[*repositories*](#repository) (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:
```python theme={null}
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*](/external/registry) — by default, the [Bazel Central Registry](https://bcr.bazel.build/). 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*](/external/extension) 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*](#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
Bazel's external dependency system offers a wide range of benefits.
### Automatic Dependency Resolution
* **Deterministic Version Resolution**: Bazel adopts the deterministic
[MVS](/external/module#version-selection) version resolution algorithm,
minimizing conflicts and addressing diamond dependency issues.
* **Simplified Dependency Management**: `MODULE.bazel` declares only direct
dependencies, while transitive dependencies are automatically resolved,
providing a clearer overview of the project's dependencies.
* **[Strict Dependency visibility](/external/module#repository_names_and_strict_deps)**:
Only direct dependencies are visible, ensuring correctness and
predictability.
### Ecosystem Integration
* **[Bazel Central Registry](https://registry.bazel.build/)**: 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](https://github.com/bazel-contrib/rules_jvm_external/blob/master/docs/bzlmod.md)
for Maven,
* [rules\_python](https://rules-python.readthedocs.io/en/latest/pypi-dependencies.html#using-bzlmod)
for PyPi,
* [bazel-gazelle](https://github.com/bazel-contrib/rules_go/blob/master/docs/go/core/bzlmod.md#external-dependencies)
for Go Modules,
* [rules\_rust](https://bazelbuild.github.io/rules_rust/crate_universe_bzlmod.html)
for Cargo.
### Advanced Features
* **[Module Extensions](/external/extension)**: The
[`use_repo_rule`](/rules/lib/globals/module#use_repo_rule) and module
extension features allow flexible use of custom repository rules and
resolution logic to introduce any non-Bazel dependencies.
* **[`bazel mod` Command](/external/mod-command)**: 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](/external/vendor)**: Pre-fetch the exact external dependencies you
need to facilitate offline builds.
* **[Lockfile](/external/lockfile)**: The lockfile improves build reproducibility and
accelerates dependency resolution.
* **(Upcoming) [BCR Provenance Attestations](https://github.com/bazelbuild/bazel-central-registry/discussions/2721)**:
Strengthen supply chain security by ensuring verified provenance of
dependencies.
## Concepts
This section gives more detail on concepts related to external dependencies.
### 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](/external/module).
### 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](#repo.bazel)), 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
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
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
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
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 repo
`alice`, but might have the apparent name `mickey` in the context of the repo
`bob`. 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
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 a
`java_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](/external/repo) for more information about how to write
your own repository rules.
The most common repo rules by far are
[`http_archive`](/rules/lib/repo/http#http_archive), which downloads an archive
from a URL and extracts it, and
[`local_repository`](/rules/lib/repo/local#local_repository), which symlinks a
local directory that is already a Bazel repository.
### Fetch a 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](/reference/command-line-reference#fetch-options) for more
information about controlling fetch.
### Directory layout
After being fetched, the repo can be found in the external directory, which is
printed by `bazel info external_directory`, under its canonical name.
You can run the following command to see the contents of the repo with the
canonical name `canonical_name`:
```posix-terminal theme={null}
ls $(bazel info external_directory)/ canonical_name
```
### REPO.bazel file
The [`REPO.bazel`](/rules/lib/globals/repo) 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 no
`load` statements are supported. The `repo()` function takes the same arguments as the [`package()` function](/reference/be/functions#package) 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:
```python theme={null}
repo(
default_package_metadata = ["//:my_license"],
)
```
## The legacy 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 the
`WORKSPACE` file:
```python theme={null}
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
In the years after the `WORKSPACE` system was introduced, users reported many
pain points, including:
* Bazel does not evaluate the `WORKSPACE` files of any dependencies, so all
transitive dependencies must be defined in the `WORKSPACE` file 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 their `WORKSPACE` files.
* This has its own problems: macros cannot `load` other `.bzl` files, 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 `WORKSPACE` file sequentially. Additionally,
dependencies are specified using `http_archive` with URLs, without any
version information. This means that there is no reliable way to perform
version resolution in the case of diamond dependencies (`A` depends on
`B` and `C`; `B` and `C` both depend on different versions of `D`).
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](/external/migration) on how to migrate
to Bzlmod.
### External links on Bzlmod
* [Bzlmod usage examples in bazelbuild/examples](https://github.com/bazelbuild/examples/tree/main/bzlmod)
* [Bazel External Dependencies Overhaul](https://docs.google.com/document/d/1moQfNcEIttsk6vYanNKIy3ZuK53hQUFq1b1r0rmsYVg/edit)
(original Bzlmod design doc)
* [BazelCon 2021 talk on Bzlmod](https://www.youtube.com/watch?v=TxOCKtU39Fs)
* [Bazel Community Day talk on Bzlmod](https://www.youtube.com/watch?v=MB6xxis9gWI)
# Bazel registries
Source: https://bazel.build/external/registry
Bazel discovers dependencies by requesting their information from Bazel
*registries*: databases of Bazel modules. Bazel only supports one type of
registries — [*index registries*](#index_registry) — local directories or static
HTTP servers following a specific format.
## Index registry
An index registry is a local directory or a static HTTP server containing
information about a list of modules — including their homepage, maintainers, the
`MODULE.bazel` file of each version, and how to fetch the source of each
version. Notably, it does *not* need to serve the source archives itself.
An index registry must have the following format:
* [`/bazel_registry.json`](#bazel-registry-json): An optional JSON file
containing metadata for the registry.
* `/modules`: A directory containing a subdirectory for each module in this
registry
* `/modules/$MODULE`: A directory containing a subdirectory for each version
of the module named `$MODULE`, as well as the [`metadata.json` file](#metadata-json) containing metadata for this module.
* `/modules/$MODULE/$VERSION`: A directory containing the following files:
* `MODULE.bazel`: The `MODULE.bazel` file of this module version. Note
that this is the `MODULE.bazel` file read during Bazel's external
dependency resolution, *not* the one from the source archive (unless
there's a [non-registry override](/external/module#non-registry_overrides)). Also note that it's
best to use this file to set the version of a release and avoid doing so
in the source archive `MODULE.bazel` file. To learn more about module
versioning, [see the FAQ](/external/faq#module-versioning-best-practices).
* [`source.json`](#source-json): A JSON file containing information on how
to fetch the source of this module version
* `patches/`: An optional directory containing patch files, only used when
`source.json` has "archive" type
* `overlay/`: An optional directory containing overlay files, only used
when `source.json` has "archive" type
### `bazel_registry.json`
`bazel_registry.json` is an optional file that specifies metadata applying to
the entire registry. It can contain the following fields:
* `mirrors`: an array of strings, specifying the list of mirrors to use for
source archives.
* The mirrored URL is a concatenation of the mirror itself, and the
source URL of the module specified by its `source.json` file sans the
protocol. For example, if a module's source URL is
`https://foo.com/bar/baz`, and `mirrors` contains
`["https://mirror1.com/", "https://example.com/mirror2/"]`, then the
URLs Bazel will try in order are `https://mirror1.com/foo.com/bar/baz`,
`https://example.com/mirror2/foo.com/bar/baz`, and finally the original
source URL itself `https://foo.com/bar/baz`.
* `module_base_path`: a string, specifying the base path for modules with
`local_path` type in the `source.json` file
### `metadata.json`
`metadata.json` is an optional JSON file containing information about the
module, with the following fields:
* `versions`: An array of strings, each denoting a version of the module
available in this registry. This array should match the children of the
module directory.
* `yanked_versions`: A JSON object specifying the [*yanked* versions](/external/module#yanked_versions) of this module. The keys
should be versions to yank, and the values should be descriptions of
why the version is yanked, ideally containing a link to more
information.
Note that the BCR requires more information in the `metadata.json` file.
### `source.json`
`source.json` is a required JSON file containing information about how to fetch
a specific version of a module. The schema of this file depends on its `type`
field, which defaults to `archive`.
* If `type` is `archive` (the default), this module version is backed by an
[`http_archive`](/rules/lib/repo/http#http_archive) repo rule; it's fetched
by downloading an archive from a given URL and extracting its contents. It
supports the following fields:
* `url`: A string, the URL of the source archive
* `mirror_urls`: A list of string, the mirror URLs of the source archive.
The URLs are tried in order after `url` as backups.
* `integrity`: A string, the [Subresource
Integrity][subresource-integrity] checksum of the archive
* `strip_prefix`: A string, the directory prefix to strip when extracting
the source archive
* `overlay`: A JSON object containing overlay files to layer on top of the
extracted archive. The patch files are located under the
`/modules/$MODULE/$VERSION/overlay` directory. The keys are the
overlay file names, and the values are the integrity checksum of
the overlay files. The overlays are applied before the patch files.
* `patches`: A JSON object containing patch files to apply to the
extracted archive. The patch files are located under the
`/modules/$MODULE/$VERSION/patches` directory. The keys are the
patch file names, and the values are the integrity checksum of
the patch files. The patches are applied after the overlay files and in
the order they appear in `patches`.
* `patch_strip`: A number; the same as the `--strip` argument of Unix
`patch`.
* `archive_type`: A string, the archive type of the downloaded file (Same
as [`type` on `http_archive`](/rules/lib/repo/http#http_archive-type)).
* If `type` is `git_repository`, this module version is backed by a
[`git_repository`](/rules/lib/repo/git#git_repository) repo rule; it's
fetched by cloning a Git repository.
* The following fields are supported, and are directly forwarded to the
underlying `git_repository` repo rule: `remote`, `commit`,
`shallow_since`, `tag`, `init_submodules`, `verbose`, and
`strip_prefix`, `patch_strip`.
* `patches`: A JSON object containing patch files to apply to the
cloned repository. The patch files are located under the
`/modules/$MODULE/$VERSION/patches` directory. The keys are the
patch file names, and the values are the integrity checksum of
the patch files. The patches are applied in the order they appear in
`patches`.
* If `type` is `local_path`, this module version is backed by a
[`local_repository`](/rules/lib/repo/local#local_repository) repo rule;
it's symlinked to a directory on local disk. It supports the following
field:
* `path`: The local path to the repo, calculated as following:
* If `path` is an absolute path, it stays as it is
* If `path` is a relative path and `module_base_path` is an
absolute path, it resolves to `/`
* If `path` and `module_base_path` are both relative paths, it
resolves to `//`.
Registry must be hosted locally and used by
`--registry=file://`. Otherwise, Bazel will
throw an error
## Bazel Central Registry
The Bazel Central Registry (BCR) at [https://bcr.bazel.build/](https://bcr.bazel.build/) is an index
registry with contents backed by the GitHub repo
[`bazelbuild/bazel-central-registry`][bcr-repo]. You can browse its contents
using the web frontend at [https://registry.bazel.build/](https://registry.bazel.build/).
The Bazel community maintains the BCR, and contributors are welcome to submit
pull requests. See the [BCR contribution
guidelines][bcr-contribution-guidelines].
In addition to following the format of a normal index registry, the BCR requires
a `presubmit.yml` file for each module version
(`/modules/$MODULE/$VERSION/presubmit.yml`). This file specifies a few essential
build and test targets that you can use to check the validity of this module
version. The BCR's CI pipelines also uses this to ensure interoperability
between modules.
## Selecting registries
The repeatable Bazel flag `--registry` can be used to specify the list of
registries to request modules from, so you can set up your project to fetch
dependencies from a third-party or internal registry. Earlier registries take
precedence. For convenience, you can put a list of `--registry` flags in the
`.bazelrc` file of your project.
If your registry is hosted on GitHub (for example, as a fork of
`bazelbuild/bazel-central-registry`) then your `--registry` value needs a raw
GitHub address under `raw.githubusercontent.com`. For example, on the `main`
branch of the `my-org` fork, you would set
`--registry=https://raw.githubusercontent.com/my-org/bazel-central-registry/main/`.
Using the `--registry` flag stops the Bazel Central Registry from being used by
default, but you can add it back by adding `--registry=https://bcr.bazel.build`.
You can use a registry on local disk with `--registry=file:///path/to/registry`.
If you want Bazel to watch the registry for changes, also pass
`--watch_registry=file:///path/to/registry`, but beware that this incurs some
overhead on every subsequent Bazel command.
[bcr-contribution-guidelines]: https://github.com/bazelbuild/bazel-central-registry/blob/main/docs/README.md
[bcr-repo]: https://github.com/bazelbuild/bazel-central-registry
[subresource-integrity]: https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description
# Repository Rules
Source: https://bazel.build/external/repo
This page covers how to define repository rules and provides examples for more
details.
An [external repository](/external/overview#repository) is a directory tree,
containing source files usable in a Bazel build, which is generated on demand by
running its corresponding **repo rule**. Repos can be defined in a multitude of
ways, but ultimately, each repo is defined by invoking a repo rule, just as
build targets are defined by invoking build rules. They can be used to depend on
third-party libraries (such as Maven packaged libraries) but also to generate
`BUILD` files specific to the host Bazel is running on.
## Repository rule definition
In a `.bzl` file, use the
[repository\_rule](/rules/lib/globals/bzl#repository_rule) function to define a
new repo rule and store it in a global variable. After a repo rule is defined,
it can be invoked as a function to define repos. This invocation is usually
performed from inside a [module extension](/external/extension) implementation
function.
The two major components of a repo rule definition are its attribute schema and
implementation function. The attribute schema determines the names and types of
attributes passed to a repo rule invocation, and the implementation function is
run when the repo needs to be fetched.
## Attributes
Attributes are arguments passed to the repo rule invocation. The schema of
attributes accepted by a repo rule is specified using the `attrs` argument when
the repo rule is defined with a call to `repository_rule`. An example defining
`url` and `sha256` attributes as strings:
```python theme={null}
http_archive = repository_rule(
implementation=_impl,
attrs={
"url": attr.string(mandatory=True),
"sha256": attr.string(mandatory=True),
}
)
```
To access an attribute within the implementation function, use
`repository_ctx.attr.`:
```python theme={null}
def _impl(repository_ctx):
url = repository_ctx.attr.url
checksum = repository_ctx.attr.sha256
```
All `repository_rule`s have the implicitly defined attribute `name`. This is a
string attribute that behaves somewhat magically: when specified as an input to
a repo rule invocation, it takes an apparent repo name; but when read from the
repo rule's implementation function using `repository_ctx.attr.name`, it returns
the canonical repo name.
## Implementation function
Every repo rule requires an `implementation` function. It contains the actual
logic of the rule and is executed strictly in the Loading Phase.
The function has exactly one input parameter, `repository_ctx`. The function
returns either `None` to signify that the rule is reproducible given the
specified parameters, or a dict with a set of parameters for that rule that
would turn that rule into a reproducible one generating the same repo. For
example, for a rule tracking a git repository that would mean returning a
specific commit identifier instead of a floating branch that was originally
specified.
The input parameter `repository_ctx` can be used to access attribute values, and
non-hermetic functions (finding a binary, executing a binary, creating a file in
the repository or downloading a file from the Internet). See [the API docs](/rules/lib/builtins/repository_ctx) for more context. Example:
```python theme={null}
def _impl(repository_ctx):
repository_ctx.symlink(repository_ctx.attr.path, "")
local_repository = repository_rule(
implementation=_impl,
...)
```
## When is the implementation function executed?
The implementation function of a repo rule is executed when Bazel needs a target
from that repository, for example when another target (in another repo) depends
on it or if it is mentioned on the command line. The implementation function is
then expected to create the repo in the file system. This is called "fetching"
the repo.
In contrast to regular targets, repos are not necessarily re-fetched when
something changes that would cause the repo to be different. This is because
there are things that Bazel either cannot detect changes to or it would cause
too much overhead on every build (for example, things that are fetched from the
network). Therefore, repos are re-fetched only if one of the following things
changes:
* The attributes passed to the repo rule invocation.
* The Starlark code comprising the implementation of the repo rule.
* The value of any environment variable passed to `repository_ctx`'s
`getenv()` method or declared with the `environ` attribute of the
[`repository_rule`](/rules/lib/globals/bzl#repository_rule). The values of
these environment variables can be hard-wired on the command line with the
[`--repo_env`](/reference/command-line-reference#flag--repo_env) flag.
* The existence, contents, and type of any paths being
[`watch`ed](/rules/lib/builtins/repository_ctx#watch) in the implementation
function of the repo rule.
* Certain other methods of `repository_ctx` with a `watch` parameter, such
as `read()`, `execute()`, and `extract()`, can also cause paths to be
watched.
* Similarly, [`repository_ctx.watch_tree`](/rules/lib/builtins/repository_ctx#watch_tree)
and [`path.readdir`](/rules/lib/builtins/path#readdir) can cause paths
to be watched in other ways.
* When `bazel fetch --force` is executed.
There are two parameters of `repository_rule` that control when the repositories
are re-fetched:
* If the `configure` flag is set, the repository is re-fetched on `bazel
fetch --force --configure` (non-`configure` repositories are not
re-fetched).
* If the `local` flag is set, in addition to the above cases, the repo is also
re-fetched when the Bazel server restarts.
## Forcing refetch of external repos
Sometimes, an external repo can become outdated without any change to its
definition or dependencies. For example, a repo fetching sources might follow a
particular branch of a third-party repository, and new commits are available on
that branch. In this case, you can ask bazel to refetch all external repos
unconditionally by calling `bazel fetch --force --all`.
Moreover, some repo rules inspect the local machine and might become outdated if
the local machine was upgraded. Here you can ask Bazel to only refetch those
external repos where the [`repository_rule`](/rules/lib/globals#repository_rule)
definition has the `configure` attribute set, use `bazel fetch --force --configure`.
## Examples
* [C++ auto-configured toolchain](https://cs.opensource.google/bazel/bazel/+/master:tools/cpp/cc_configure.bzl;drc=644b7d41748e09eff9e47cbab2be2263bb71f29a;l=176):
it uses a repo rule to automatically create the C++ configuration files for
Bazel by looking for the local C++ compiler, the environment and the flags
the C++ compiler supports.
* [Go repositories](https://github.com/bazelbuild/rules_go/blob/67bc217b6210a0922d76d252472b87e9a6118fdf/go/private/go_repositories.bzl#L195)
uses several `repository_rule` to defines the list of dependencies needed to
use the Go rules.
* [rules\_jvm\_external](https://github.com/bazelbuild/rules_jvm_external)
creates an external repository called `@maven` by default that generates
build targets for every Maven artifact in the transitive dependency tree.
# Vendor Mode
Source: https://bazel.build/external/vendor
Vendor mode is a feature that lets you create a local copy of
external dependencies. This is useful for offline builds, or when you want to
control the source of an external dependency.
## Enable vendor mode
You can enable vendor mode by specifying `--vendor_dir` flag.
For example, by adding it to your `.bazelrc` file:
```none theme={null}
# Enable vendor mode with vendor directory under /vendor_src
common --vendor_dir=vendor_src
```
The vendor directory can be either a relative path to your workspace root or an
absolute path.
## Vendor a specific external repository
You can use the `vendor` command with the `--repo` flag to specify which repo
to vendor, it accepts both [canonical repo name](/external/overview#canonical-repo-name) and [apparent repo name](/external/overview#apparent-repo-name).
For example, running:
```none theme={null}
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
```
or
```none theme={null}
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
```
will both get rules\_cc to be vendored under
`/vendor_src/rules_cc+`.
## Vendor external dependencies for given targets
To vendor all external dependencies required for building given target patterns,
you can run `bazel vendor `.
For example
```none theme={null}
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
```
will vendor all repos required for building the `//src/main:hello-world` target
and all targets under `//src/test/...` with the current configuration.
Under the hood, it's doing a `bazel build --nobuild` command to analyze the
target patterns, therefore build flags could be applied to this command and
affect the result.
### Build the target offline
With the external dependencies vendored, you can build the target offline by
```none theme={null}
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
```
The build should work in a clean build environment without network access and
repository cache.
Therefore, you should be able to check in the vendored source and build the same
targets offline on another machine.
Note: If you make changes to the targets to build, the external dependencies,
the build configuration, or the Bazel version, you may need to re-vendor to make
sure offline build still works.
## Vendor all external dependencies
To vendor all repos in your transitive external dependencies graph, you can
run:
```none theme={null}
bazel vendor --vendor_dir=vendor_src
```
Note that vendoring all dependencies has a few **disadvantages**:
* Fetching all repos, including those introduced transitively, can be time-consuming.
* The vendor directory can become very large.
* Some repos may fail to fetch if they are not compatible with the current platform or environment.
Therefore, consider vendoring for specific targets first.
### Vendor dependencies for lockfile updates
Updating the lockfile, e.g. with `bazel mod tidy` or `deps`, evaluates every
module extension in the dependency graph, including extensions that are only
used by dependencies, and also needs buildozer. Neither is reachable from build
targets, so `bazel vendor //...` does not include them. Pass `--lockfile_deps`
to vendor them in addition to the dependencies of the given targets:
```none theme={null}
bazel vendor --lockfile_deps //...
```
Afterwards, the lockfile can be updated with fetching disabled:
```none theme={null}
bazel mod tidy --vendor_dir=vendor_src --nofetch
```
Without target patterns, `bazel vendor --lockfile_deps` vendors only the
dependencies required to update the lockfile.
## Configure vendor mode with VENDOR.bazel
You can control how given repos are handled with the VENDOR.bazel file located
under the vendor directory.
There are two directives available, both accepting a list of
[canonical repo names](/external/overview#canonical-repo-name) as arguments:
* `ignore()`: to completely ignore a repository from vendor mode.
* `pin()`: to pin a repository to its current vendored source as if there is a
`--override_repository` flag for this repo. Bazel will NOT update the vendored
source for this repo while running the vendor command unless it's unpinned.
The user can modify and maintain the vendored source for this repo manually.
For example
```python theme={null}
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
```
With this configuration
* Both repos will be excluded from subsequent vendor commands.
* Repo `bazel_skylib` will be overridden to the source located under the
vendor directory.
* The user can safely modify the vendored source of `bazel_skylib`.
* To re-vendor `bazel_skylib`, the user has to disable the pin statement
first.
Note: Repository rules with
[`local`](/rules/lib/globals/bzl#repository_rule.local) or
[`configure`](/rules/lib/globals/bzl#repository_rule.configure) set to true are
always excluded from vendoring.
## Understand how vendor mode works
Bazel fetches external dependencies of a project under `$(bazel info
external_directory)`. Vendoring external dependencies means moving out
relevant files and directories to the given vendor directory and use the
vendored source for later builds.
The content being vendored includes:
* The repo directory
* The repo marker file
During a build, if the vendored marker file is up-to-date or the repo is
pinned in the VENDOR.bazel file, then Bazel uses the vendored source by creating
a symlink to it under `$(bazel info external_directory)` instead of actually
running the repository rule. Otherwise, a warning is printed and Bazel will
fallback to fetching the latest version of the repo.
Note: Bazel assumes the vendored source is not changed by users unless the repo
is pinned in the VENDOR.bazel file. If a user does change the vendored source
without pinning the repo, the changed vendored source will be used, but it will
be overwritten if its existing marker file is
outdated and the repo is vendored again.
### Vendor registry files
Bazel has to perform the Bazel module resolution in order to fetch external
dependencies, which may require accessing registry files through internet. To
achieve offline build, Bazel vendors all registry files fetched from
network under the `/_registries` directory.
### Vendor symlinks
External repositories may contain symlinks pointing to other files or
directories. To make sure symlinks work correctly, Bazel uses the following
strategy to rewrite symlinks in the vendored source:
* Create a symlink `/bazel-external` that points to `$(bazel info
external_directory)`. It is refreshed by every Bazel command automatically.
* For the vendored source, rewrite all symlinks that originally point to a
path under `$(bazel info external_directory)` to a relative path under
`/bazel-external`.
For example, if the original symlink is
```none theme={null}
/repo_foo+/link => $(bazel info external_directory)/repo_bar+/file
```
It will be rewritten to
```none theme={null}
/repo_foo+/link => ../../bazel-external/repo_bar+/file
```
where
```none theme={null}
/bazel-external => $(bazel info external_directory) # This might be new if output base is changed
```
Since `/bazel-external` is generated by Bazel automatically, it's
recommended to add it to `.gitignore` or equivalent to avoid checking it in.
With this strategy, symlinks in the vendored source should work correctly even
after the vendored source is moved to another location or the bazel output base
is changed.
Note: symlinks that point to an absolute path outside of `$(bazel info
external_directory)` are not rewritten. Therefore, it could still break
cross-machine compatibility.
Note: On Windows, vendoring symlinks only works with
[`--windows_enable_symlinks`][windows_enable_symlinks]
flag enabled.
[windows_enable_symlinks]: /reference/command-line-reference#flag--windows_enable_symlinks
# rule_attributes
Source: https://bazel.build/rules/lib/builtins/rule_attributes
Information about attributes of a rule an aspect is applied to.
## Members
* [attr](#attr)
* [exec\_groups](#exec_groups)
* [executable](#executable)
* [file](#file)
* [files](#files)
* [kind](#kind)
* [toolchains](#toolchains)
* [var](#var)
## attr
```
struct rule_attributes.attr
```
A struct to access the values of the [attributes](https://bazel.build/extending/rules#attributes). The values are provided by the user (if not, a default value is used). The attributes of the struct and the types of their values correspond to the keys and values of the [`attrs` dict](../globals/bzl#rule.attrs) provided to the [`rule` function](../globals/bzl#rule). [See example of use](https://github.com/bazelbuild/examples/blob/main/rules/attributes/printer.bzl).
## exec\_groups
```
ExecGroupCollection rule_attributes.exec_groups
```
A collection of the execution groups available for the rule the aspect is applied to, indexed by their names.
## executable
```
struct rule_attributes.executable
```
A `struct` containing executable files defined in [label type attributes](../toplevel/attr#label) marked as [`executable=True`](../toplevel/attr#label.executable). The struct fields correspond to the attribute names. Each value in the struct is either a [`File`](../builtins/File) or `None`. If an optional attribute is not specified in the rule then the corresponding struct value is `None`. If a label type is not marked as `executable=True`, no corresponding struct field is generated. [See example of use](https://github.com/bazelbuild/examples/blob/main/rules/actions_run/execute.bzl).
## file
```
struct rule_attributes.file
```
A `struct` containing files defined in [label type attributes](../toplevel/attr#label) marked as [`allow_single_file`](../toplevel/attr#label.allow_single_file). The struct fields correspond to the attribute names. The struct value is always a [`File`](../builtins/File) or `None`. If an optional attribute is not specified in the rule then the corresponding struct value is `None`. If a label type is not marked as `allow_single_file`, no corresponding struct field is generated. It is a shortcut for:
```
list(ctx.attr..files)[0]
```
In other words, use `file` to access the (singular) [default output](https://bazel.build/extending/rules#requesting_output_files) of a dependency. [See example of use](https://github.com/bazelbuild/examples/blob/main/rules/expand_template/hello.bzl).
## files
```
struct rule_attributes.files
```
A `struct` containing files defined in [label](../toplevel/attr#label) or [label list](../toplevel/attr#label_list) type attributes. The struct fields correspond to the attribute names. The struct values are `list` of [`File`](../builtins/File)s. It is a shortcut for:
```
[f for t in ctx.attr. for f in t.files]
```
In other words, use `files` to access the [default outputs](https://bazel.build/extending/rules#requesting_output_files) of a dependency. [See example of use](https://github.com/bazelbuild/examples/blob/main/rules/depsets/foo.bzl).
## kind
```
string rule_attributes.kind
```
The kind of a rule, such as 'cc\_library'
## toolchains
```
ToolchainContext rule_attributes.toolchains
```
Toolchains for the default exec group of the rule the aspect is applied to.
## var
```
dict rule_attributes.var
```
Dictionary (String to String) of configuration variables.
# runfiles
Source: https://bazel.build/rules/lib/builtins/runfiles
A container of information regarding a set of files required at runtime by an executable. This object should be passed via [`DefaultInfo`](../providers/DefaultInfo) in order to tell the build system about the runfiles needed by the outputs produced by the rule.
See [runfiles guide](https://bazel.build/extending/rules#runfiles) for details.
## Members
* [empty\_filenames](#empty_filenames)
* [files](#files)
* [merge](#merge)
* [merge\_all](#merge_all)
* [root\_symlinks](#root_symlinks)
* [symlinks](#symlinks)
## empty\_filenames
```
depset runfiles.empty_filenames
```
Returns names of empty files to create.
## files
```
depset runfiles.files
```
Returns the set of runfiles as files.
## merge
```
runfiles runfiles.merge(other)
```
Returns a new runfiles object that includes all the contents of this one and the argument.
*Note:* When you have many runfiles objects to merge, use [`merge_all()`](#merge_all) rather than calling `merge` in a loop. This avoids constructing deep depset structures which can cause build failures.
### Parameters
| Parameter | Description |
| - | - |
| `other` | [runfiles](../builtins/runfiles); required The runfiles object to merge into this. |
## merge\_all
```
runfiles runfiles.merge_all(other)
```
Returns a new runfiles object that includes all the contents of this one and of the runfiles objects in the argument.
### Parameters
| Parameter | Description |
| - | - |
| `other` | [sequence](../core/list) of [runfiles](../builtins/runfiles)s; required The sequence of runfiles objects to merge into this. |
## root\_symlinks
```
depset runfiles.root_symlinks
```
Returns the set of root symlinks.
## symlinks
```
depset runfiles.symlinks
```
Returns the set of symlinks.
# struct
Source: https://bazel.build/rules/lib/builtins/struct
A generic object with fields.
Structs fields cannot be reassigned once the struct is created. Two structs are equal if they have the same fields and if corresponding field values are equal.
## Members
* [struct](#struct)
## struct
```
struct struct(**kwargs)
```
Creates an immutable struct using the keyword arguments as attributes. It is used to group multiple values together. Example:
```
s = struct(x = 2, y = 3)
return s.x + getattr(s, "y") # returns 5
```
### Parameters
| Parameter | Description |
| - | - |
| `kwargs` | default is `{}` |
# subrule_ctx
Source: https://bazel.build/rules/lib/builtins/subrule_ctx
A context object passed to the implementation function of a subrule.
## Members
* [actions](#actions)
* [fragments](#fragments)
* [label](#label)
* [toolchains](#toolchains)
## actions
```
actions subrule_ctx.actions
```
Contains methods for declaring output files and the actions that produce them
## fragments
```
fragments subrule_ctx.fragments
```
Allows access to configuration fragments in target configuration.
## label
```
Label subrule_ctx.label
```
The label of the target currently being analyzed
## toolchains
```
ToolchainContext subrule_ctx.toolchains
```
Contains methods for declaring output files and the actions that produce them
# tag_class
Source: https://bazel.build/rules/lib/builtins/tag_class
Defines a schema of attributes for a tag, created by [`tag_class()`](../globals/bzl#tag_class).
# template_ctx
Source: https://bazel.build/rules/lib/builtins/template_ctx
A context object that is passed to the action template expansion function.
## Members
* [args](#args)
* [declare\_file](#declare_file)
* [declare\_subdirectory](#declare_subdirectory)
* [run](#run)
## args
```
Args template_ctx.args()
```
Returns an Args object that can be used to build memory-efficient command lines.
## declare\_file
```
File template_ctx.declare_file(filename, *, directory)
```
Declares that implementation creates a file with the given filename within the specified directory.
Remember that in addition to declaring a file, you must separately create an action that emits the file. Creating that action will require passing the returned `File` object to the action's construction function.
### Parameters
| Parameter | Description |
| - | - |
| `filename` | [string](../core/string); required The relative path of the file within the directory. |
| `directory` | [File](../builtins/File); required The directory in which the file should be created. |
## declare\_subdirectory
```
File template_ctx.declare_subdirectory(subdirectory, *, directory)
```
Declares that implementation creates a subdirectory with the given name within the specified directory.
Remember that in addition to declaring a subdirectory, you must separately create an action that emits the subdirectory. Creating that action will require passing the returned `File` object to the action's construction function.
### Parameters
| Parameter | Description |
| - | - |
| `subdirectory` | [string](../core/string); required The relative path of the subdirectory within the directory. |
| `directory` | [File](../builtins/File); required The directory in which the subdirectory should be created. |
## run
```
None template_ctx.run(*, outputs, inputs=[], executable, tools=None, arguments=[], progress_message=None)
```
Creates an action that runs an executable.
### Parameters
| Parameter | Description |
| - | - |
| `outputs` | [sequence](../core/list) of [File](../builtins/File)s; required List of the output files of the action. |
| `inputs` | [sequence](../core/list) of [File](../builtins/File)s; or [depset](../builtins/depset); default is `[]` List or depset of the input files of the action. |
| `executable` | [File](../builtins/File); or [string](../core/string); or [FilesToRunProvider](../providers/FilesToRunProvider); required The executable file to be called by the action. |
| `tools` | [sequence](../core/list.html); or [depset](../builtins/depset.html); or `None`; default is `None` List or [`depset`](../builtins/depset.html) of any tools needed by the action. Tools are executable inputs that may have their own runfiles which are automatically made available to the action. When a list is provided, it can be a heterogenous collection of:
`File`s
`FilesToRunProvider` instances
`depset`s of `File`s
`File`s from [`ctx.executable`](../builtins/ctx#executable) and `FilesToRunProvider`s which are directly in the list will have their runfiles automatically added. All tools are implicitly added as inputs. |
| `arguments` | [sequence](../core/list); default is `[]` Command line arguments of the action. Must be a list of strings or [`actions.args()`](#args) objects. |
| `progress_message` | [string](../core/string); or `None`; default is `None` Progress message to show to the user during the build. |
# toolchain_type
Source: https://bazel.build/rules/lib/builtins/toolchain_type
A data type describing a dependency on a specific toolchain type.
## Members
* [mandatory](#mandatory)
* [toolchain\_type](#toolchain_type)
## mandatory
```
bool toolchain_type.mandatory
```
Whether the toolchain type is mandatory or optional.
## toolchain\_type
```
Label toolchain_type.toolchain_type
```
The toolchain type that is required.
# transition
Source: https://bazel.build/rules/lib/builtins/transition
Represents a configuration transition across a dependency edge. For example, if `//package:foo` depends on `//package:bar` with a configuration transition, then the configuration of `//package:bar` (and its dependencies) will be `//package:foo`'s configuration plus the changes specified by the transition function.
## Members
* [transition](#transition)
* [and\_then](#and_then)
## transition
```
transition transition(*, implementation, inputs, outputs)
```
A transition that reads a set of input build settings and writes a set of output build settings.
Example:
```
def _transition_impl(settings, attr):
# This transition just reads the current CPU value as a demonstration.
# A real transition could incorporate this into its followup logic.
current_cpu = settings["//command_line_option:cpu"]
return {"//command_line_option:compilation_mode": "dbg"}
build_in_debug_mode = transition(
implementation = _transition_impl,
inputs = ["//command_line_option:cpu"],
outputs = ["//command_line_option:compilation_mode"],
)
```
For more details see [here](https://bazel.build/rules/config#user-defined-transitions).
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | callable; required The function implementing this transition. This function always has two parameters: `settings` and `attr`. The `settings` param is a dictionary whose set of keys is defined by the inputs parameter. So, for each build setting `--//foo=bar`, if `inputs` contains `//foo`, `settings` will have an entry `settings['//foo']='bar'`. The `attr` param is a reference to `ctx.attr`. This gives the implementation function access to the rule's attributes to make attribute-parameterized transitions possible. This function must return a `dict` from build setting identifier to build setting value; this represents the configuration transition: for each entry in the returned `dict`, the transition updates that setting to the new value. All other settings are unchanged. This function can also return a `list` of `dict`s or a `dict` of `dict`s in the case of a split transition. |
| `inputs` | [sequence](../core/list) of [string](../core/string)s; required List of build settings that can be read by this transition. This becomes the key set of the settings parameter of the implementation function parameter. |
| `outputs` | [sequence](../core/list) of [string](../core/string)s; required List of build settings that can be written by this transition. This must be a superset of the key set of the dictionary returned by this transition. |
## and\_then
```
transition transition.and_then(transition)
```
Returns a new transition that applies this transition followed by the given one. The second transition reads the build settings produced by this one; the original transitions are left unchanged. The result is itself a transition and may be composed further.
A composition may be used as a rule or attribute transition wherever its component transitions could be used. At most one of the composed transitions may target the exec configuration (e.g. `config.exec`). When two transitions in the chain split the configuration, the result has the cross product of their splits; the key for each combined split is the comma-separated concatenation of the component keys.
### Parameters
| Parameter | Description |
| - | - |
| `transition` | [transition](../builtins/transition); required The transition to apply after this one. |
# wasm_exec_result
Source: https://bazel.build/rules/lib/builtins/wasm_exec_result
The result of executing a WebAssembly function with
`repository_ctx.execute_wasm()`. It contains the function's
return value and output buffer.
If execution failed before the function returned then the return code will be negative
and the `error_message` field will be set.
## Members
* [error\_message](#error_message)
* [output](#output)
* [return\_code](#return_code)
## error\_message
```
string wasm_exec_result.error_message
```
Contains an error message if execution failed before the function returned.
## output
```
string wasm_exec_result.output
```
The content of the output buffer returned by the WebAssembly function.
## return\_code
```
long wasm_exec_result.return_code
```
The return value of the WebAssembly function, or a negative value if execution
was terminated before the function returned.
# wasm_module
Source: https://bazel.build/rules/lib/builtins/wasm_module
A WebAssembly module loaded by `repository_ctx.load_wasm()`.
## Members
* [path](#path)
## path
```
unknown wasm_module.path
```
The path this WebAssembly module was loaded from.
# Core Starlark data types
Source: https://bazel.build/rules/lib/core
This section lists the data types of the [Starlark core language](https://github.com/bazelbuild/starlark/blob/master/spec.md#built-in-constants-and-functions). With some exceptions, these type names are not valid Starlark symbols; instances of them may be acquired through different means.
* [bool](/rules/lib/core/bool)
* [builtin\_function\_or\_method](/rules/lib/core/builtin_function_or_method)
* [dict](/rules/lib/core/dict)
* [float](/rules/lib/core/float)
* [function](/rules/lib/core/function)
* [int](/rules/lib/core/int)
* [json](/rules/lib/core/json)
* [list](/rules/lib/core/list)
* [range](/rules/lib/core/range)
* [set](/rules/lib/core/set)
* [string](/rules/lib/core/string)
* [tuple](/rules/lib/core/tuple)
# bool
Source: https://bazel.build/rules/lib/core/bool
A type to represent booleans. There are only two possible values: True and False. Any value can be converted to a boolean using the [bool](../globals/all#bool) function.
# builtin_function_or_method
Source: https://bazel.build/rules/lib/core/builtin_function_or_method
The type of a built-in function, defined by Java code.
# dict
Source: https://bazel.build/rules/lib/core/dict
dict is a built-in type representing an associative mapping or *dictionary*. A dictionary supports indexing using `d[k]` and key membership testing using `k in d`; both operations take constant time. Unfrozen dictionaries are mutable, and may be updated by assigning to `d[k]` or by calling certain methods. Dictionaries are iterable; iteration yields the sequence of keys in insertion order. Iteration order is unaffected by updating the value associated with an existing key, but is affected by removing then reinserting a key.
```
d = {0: "x", 2: "z", 1: "y"}
[k for k in d] # [0, 2, 1]
d.pop(2)
d[0], d[2] = "a", "b"
0 in d, "a" in d # (True, False)
[(k, v) for k, v in d.items()] # [(0, "a"), (1, "y"), (2, "b")]
```
There are four ways to construct a dictionary:
1. A dictionary expression `{k: v, ...}` yields a new dictionary with the specified key/value entries, inserted in the order they appear in the expression. Evaluation fails if any two key expressions yield the same value.- A dictionary comprehension `{k: v for vars in seq}` yields a new dictionary into which each key/value pair is inserted in loop iteration order. Duplicates are permitted: the first insertion of a given key determines its position in the sequence, and the last determines its associated value.
```
{k: v for k, v in (("a", 0), ("b", 1), ("a", 2))} # {"a": 2, "b": 1}
{i: 2*i for i in range(3)} # {0: 0, 1: 2, 2: 4}
```
* A call to the built-in [dict](../globals/all#dict) function returns a dictionary containing the specified entries, which are inserted in argument order, positional arguments before named. As with comprehensions, duplicate keys are permitted.- The union expression `x | y` yields a new dictionary by combining two existing dictionaries. If the two dictionaries have a key `k` in common, the right hand side dictionary's value of the key (in other words, `y[k]`) wins. The `|=` variant of the union operator modifies a dictionary in-place. Example:
```
d = {"foo": "FOO", "bar": "BAR"} | {"foo": "FOO2", "baz": "BAZ"}
# d == {"foo": "FOO2", "bar": "BAR", "baz": "BAZ"}
d = {"a": 1, "b": 2}
d |= {"b": 3, "c": 4}
# d == {"a": 1, "b": 3, "c": 4}
```
## Members
* [clear](#clear)
* [get](#get)
* [items](#items)
* [keys](#keys)
* [pop](#pop)
* [popitem](#popitem)
* [setdefault](#setdefault)
* [update](#update)
* [values](#values)
## clear
```
None dict.clear()
```
Remove all items from the dictionary.
## get
```
unknown dict.get(key, default=None)
```
Returns the value for `key` if `key` is in the dictionary, else `default`. If `default` is not given, it defaults to `None`, so that this method never throws an error.
### Parameters
| Parameter | Description |
| - | - |
| `key` | required |
| `default` | default is `None` The default value to use (instead of None) if the key is not found. |
## items
```
list dict.items()
```
Returns the list of key-value tuples:
```
{2: "a", 4: "b", 1: "c"}.items() == [(2, "a"), (4, "b"), (1, "c")]
```
## keys
```
list dict.keys()
```
Returns the list of keys:
```
{2: "a", 4: "b", 1: "c"}.keys() == [2, 4, 1]
```
## pop
```
unknown dict.pop(key, default=unbound)
```
Removes a `key` from the dict, and returns the associated value. If no entry with that key was found, remove nothing and return the specified `default` value; if no default value was specified, fail instead.
### Parameters
| Parameter | Description |
| - | - |
| `key` | required The key. |
| `default` | default is `unbound` a default value if the key is absent. |
## popitem
```
tuple dict.popitem()
```
Remove and return the first `(key, value)` pair from the dictionary. `popitem` is useful to destructively iterate over a dictionary, as often used in set algorithms. If the dictionary is empty, the `popitem` call fails.
## setdefault
```
unknown dict.setdefault(key, default=None)
```
If `key` is in the dictionary, return its value. If not, insert key with a value of `default` and return `default`. `default` defaults to `None`.
### Parameters
| Parameter | Description |
| - | - |
| `key` | required The key. |
| `default` | default is `None` a default value if the key is absent. |
## update
```
None dict.update(pairs=[], **kwargs)
```
Updates the dictionary first with the optional positional argument, `pairs`, then with the optional keyword arguments
If the positional argument is present, it must be a dict, iterable, or None.
If it is a dict, then its key/value pairs are inserted into this dict. If it is an iterable, it must provide a sequence of pairs (or other iterables of length 2), each of which is treated as a key/value pair to be inserted.
Each keyword argument `name=value` causes the name/value pair to be inserted into this dict.
### Parameters
| Parameter | Description |
| - | - |
| `pairs` | default is `[]` Either a dictionary or a list of entries. Entries must be tuples or lists with exactly two elements: key, value. |
| `kwargs` | required Dictionary of additional entries. |
## values
```
list dict.values()
```
Returns the list of values:
```
{2: "a", 4: "b", 1: "c"}.values() == ["a", "b", "c"]
```
# float
Source: https://bazel.build/rules/lib/core/float
The type of floating-point numbers in Starlark.
# function
Source: https://bazel.build/rules/lib/core/function
The type of functions declared in Starlark.
# int
Source: https://bazel.build/rules/lib/core/int
The type of integers in Starlark. Starlark integers may be of any magnitude; arithmetic is exact. Examples of integer expressions:
```
153
0x2A # hexadecimal literal
0o54 # octal literal
23 * 2 + 5
100 / -7
100 % -7 # -5 (unlike in some other languages)
int("18")
```
# json
Source: https://bazel.build/rules/lib/core/json
Module json is a Starlark module of JSON-related functions.
## Members
* [decode](#decode)
* [encode](#encode)
* [encode\_indent](#encode_indent)
* [indent](#indent)
## decode
```
unknown json.decode(x, default=unbound)
```
The decode function has one required positional parameter: a JSON string.
It returns the Starlark value that the string denotes.
* `"null"`, `"true"` and `"false"` are parsed as `None`, `True`, and `False`.\* Numbers are parsed as int, or as a float if they contain a decimal point or an exponent. Although JSON has no syntax for non-finite values, very large values may be decoded as infinity.\* a JSON object is parsed as a new unfrozen Starlark dict. If the same key string occurs more than once in the object, the last value for the key is kept.\* a JSON array is parsed as new unfrozen Starlark list.
If `x` is not a valid JSON encoding and the optional `default` parameter is specified (including specified as `None`), this function returns the `default` value.
If `x` is not a valid JSON encoding and the optional `default` parameter is *not* specified, this function fails.
### Parameters
| Parameter | Description |
| - | - |
| `x` | [string](../core/string); required JSON string to decode. |
| `default` | default is `unbound` If specified, the value to return when `x` cannot be decoded. |
## encode
```
string json.encode(x)
```
The encode function accepts one required positional argument, which it converts to JSON by cases:
* None, True, and False are converted to 'null', 'true', and 'false', respectively.\* An int, no matter how large, is encoded as a decimal integer. Some decoders may not be able to decode very large integers.\* A float is encoded using a decimal point or an exponent or both, even if its numeric value is an integer. It is an error to encode a non-finite floating-point value.\* A string value is encoded as a JSON string literal that denotes the value. Each unpaired surrogate is replaced by U+FFFD.\* A dict is encoded as a JSON object, in lexicographical key order. It is an error if any key is not a string.\* A list or tuple is encoded as a JSON array.\* A struct-like value is encoded as a JSON object, in field name order.
An application-defined type may define its own JSON encoding.
Encoding any other value yields an error.
### Parameters
| Parameter | Description |
| - | - |
| `x` | required |
## encode\_indent
```
string json.encode_indent(x, *, prefix='', indent='\t')
```
The encode\_indent function is equivalent to `json.indent(json.encode(x), ...)`. See `indent` for description of formatting parameters.
### Parameters
| Parameter | Description |
| - | - |
| `x` | required |
| `prefix` | [string](../core/string); default is `''` |
| `indent` | [string](../core/string); default is `'\t'` |
## indent
```
string json.indent(s, *, prefix='', indent='\t')
```
The indent function returns the indented form of a valid JSON-encoded string.
Each array element or object field appears on a new line, beginning with the prefix string followed by one or more copies of the indent string, according to its nesting depth.
The function accepts one required positional parameter, the JSON string,
and two optional keyword-only string parameters, prefix and indent,
that specify a prefix of each new line, and the unit of indentation.
If the input is not valid, the function may fail or return invalid output.
### Parameters
| Parameter | Description |
| - | - |
| `s` | [string](../core/string); required |
| `prefix` | [string](../core/string); default is `''` |
| `indent` | [string](../core/string); default is `'\t'` |
# list
Source: https://bazel.build/rules/lib/core/list
The built-in list type. Example list expressions:
```
x = [1, 2, 3]
```
Accessing elements is possible using indexing (starts from `0`):
```
e = x[1] # e == 2
```
Lists support the `+` operator to concatenate two lists. Example:
```
x = [1, 2] + [3, 4] # x == [1, 2, 3, 4]
x = ["a", "b"]
x += ["c"] # x == ["a", "b", "c"]
```
Similar to strings, lists support slice operations:
```
['a', 'b', 'c', 'd'][1:3] # ['b', 'c']
['a', 'b', 'c', 'd'][::2] # ['a', 'c']
['a', 'b', 'c', 'd'][3:0:-1] # ['d', 'c', 'b']
```
Lists are mutable, as in Python.
## Members
* [append](#append)
* [clear](#clear)
* [extend](#extend)
* [index](#index)
* [insert](#insert)
* [pop](#pop)
* [remove](#remove)
## append
```
None list.append(item)
```
Adds an item to the end of the list.
### Parameters
| Parameter | Description |
| - | - |
| `item` | required |
## clear
```
None list.clear()
```
Removes all the elements of the list.
## extend
```
None list.extend(items)
```
Adds all items to the end of the list.
### Parameters
| Parameter | Description |
| - | - |
| `items` | iterable; required |
## index
```
int list.index(x, start=unbound, end=unbound)
```
Returns the index in the list of the first item whose value is x. It is an error if there is no such item. If `start` and `end` are given, they restrict the range searched in the same manner as slicing.
### Parameters
| Parameter | Description |
| - | - |
| `x` | required |
| `start` | [int](../core/int); default is `unbound` The start index of the list portion to inspect. |
| `end` | [int](../core/int); default is `unbound` The end index of the list portion to inspect. |
## insert
```
None list.insert(index, item)
```
Inserts an item at a given position.
### Parameters
| Parameter | Description |
| - | - |
| `index` | [int](../core/int); required The index the item will be at after insertion. If the index is out of range, it's transformed into an effective index in the range from 0 to the list's previous length, inclusive, in the same manner as for the start index of a slice operator. |
| `item` | required The item. |
## pop
```
unknown list.pop(i=-1)
```
Removes the item at the given position in the list, and returns it. If no `index` is specified, it removes and returns the last item in the list.
### Parameters
| Parameter | Description |
| - | - |
| `i` | [int](../core/int); default is `-1` The index of the item. |
## remove
```
None list.remove(x)
```
Removes the first item from the list whose value is x. It is an error if there is no such item.
### Parameters
| Parameter | Description |
| - | - |
| `x` | required The object to remove. |
# range
Source: https://bazel.build/rules/lib/core/range
A language built-in type to support ranges. Example of range literal:
```
x = range(1, 10, 3)
```
Accessing elements is possible using indexing (starts from `0`):
```
e = x[1] # e == 2
```
Ranges do not support the `+` operator for concatenation.Similar to strings, ranges support slice operations:
```
range(10)[1:3] # range(1, 3)
range(10)[::2] # range(0, 10, 2)
range(10)[3:0:-1] # range(3, 0, -1)
```
Ranges are immutable, as in Python 3.
# set
Source: https://bazel.build/rules/lib/core/set
The built-in set type. A set is a mutable collection of unique values – the set's
*elements*. The [type name](../globals/all#type) of a set is `"set"`.
Sets provide constant-time operations to insert, remove, or check for the presence of a value.
Sets are implemented using a hash table, and therefore, just like keys of a
[dictionary](../dict), elements of a set must be hashable. A value may be used as an
element of a set if and only if it may be used as a key of a dictionary.
Sets may be constructed using the [`set()`](../globals/all#set) built-in
function, which returns a new set containing the unique elements of its optional argument, which
must be an iterable. Calling `set()` without an argument constructs an empty set. Sets
have no literal syntax.
The `in` and `not in` operations check whether a value is (or is not) in a
set:
```
s = set(["a", "b", "c"])
"a" in s # True
"z" in s # False
```
A set is iterable, and thus may be used as the operand of a `for` loop, a list
comprehension, and the various built-in functions that operate on iterables. Its length can be
retrieved using the [`len()`](../globals/all#len) built-in function, and the
order of iteration is the order in which elements were first added to the set:
```
s = set(["z", "y", "z", "y"])
len(s) # prints 2
s.add("x")
len(s) # prints 3
for e in s:
print e # prints "z", "y", "x"
```
A set used in Boolean context is true if and only if it is non-empty.
```
s = set()
"non-empty" if s else "empty" # "empty"
t = set(["x", "y"])
"non-empty" if t else "empty" # "non-empty"
```
Sets may be compared for equality or inequality using `==` and `!=`. A set
`s` is equal to `t` if and only if `t` is a set containing the same
elements; iteration order is not significant. In particular, a set is *not* equal to the list
of its elements. Sets are not ordered with respect to other sets, and an attempt to compare two sets
using `<`, `<=`, `>`, `>=`, or to sort a
sequence of sets, will fail.
```
set() == set() # True
set() != [] # True
set([1, 2]) == set([2, 1]) # True
set([1, 2]) != [1, 2] # True
```
The `|` operation on two sets returns the union of the two sets: a set containing the
elements found in either one or both of the original sets.
```
set([1, 2]) | set([3, 2]) # set([1, 2, 3])
```
The `&` operation on two sets returns the intersection of the two sets: a set
containing only the elements found in both of the original sets.
```
set([1, 2]) & set([2, 3]) # set([2])
set([1, 2]) & set([3, 4]) # set()
```
The `-` operation on two sets returns the difference of the two sets: a set containing
the elements found in the left-hand side set but not the right-hand side set.
```
set([1, 2]) - set([2, 3]) # set([1])
set([1, 2]) - set([3, 4]) # set([1, 2])
```
The `^` operation on two sets returns the symmetric difference of the two sets: a set
containing the elements found in exactly one of the two original sets, but not in both.
```
set([1, 2]) ^ set([2, 3]) # set([1, 3])
set([1, 2]) ^ set([3, 4]) # set([1, 2, 3, 4])
```
In each of the above operations, the elements of the resulting set retain their order from the
two operand sets, with all elements that were drawn from the left-hand side ordered before any
element that was only present in the right-hand side.
The corresponding augmented assignments, `|=`, `&=`, `-=`,
and `^=`, modify the left-hand set in place.
```
s = set([1, 2])
s |= set([2, 3, 4]) # s now equals set([1, 2, 3, 4])
s &= set([0, 1, 2, 3]) # s now equals set([1, 2, 3])
s -= set([0, 1]) # s now equals set([2, 3])
s ^= set([3, 4]) # s now equals set([2, 4])
```
Like all mutable values in Starlark, a set can be frozen, and once frozen, all subsequent
operations that attempt to update it will fail.
## Members
* [add](#add)
* [clear](#clear)
* [difference](#difference)
* [difference\_update](#difference_update)
* [discard](#discard)
* [intersection](#intersection)
* [intersection\_update](#intersection_update)
* [isdisjoint](#isdisjoint)
* [issubset](#issubset)
* [issuperset](#issuperset)
* [pop](#pop)
* [remove](#remove)
* [symmetric\_difference](#symmetric_difference)
* [symmetric\_difference\_update](#symmetric_difference_update)
* [union](#union)
* [update](#update)
## add
```
None set.add(element)
```
Adds an element to the set.
It is permissible to `add` a value already present in the set; this leaves the set
unchanged.
If you need to add multiple elements to a set, see [`update`](#update) or
the `|=` augmented assignment operation.
### Parameters
| Parameter | Description |
| - | - |
| `element` | required Element to add. |
## clear
```
None set.clear()
```
Removes all the elements of the set.
## difference
```
set set.difference(*others)
```
Returns a new mutable set containing the difference of this set with others.
If `s` and `t` are sets, `s.difference(t)` is equivalent to
`s - t`; however, note that the `-` operation requires both sides to be sets,
while the `difference` method also accepts sequences and dicts.
It is permissible to call `difference` without any arguments; this returns a copy of
the set.
For example,
```
set([1, 2, 3]).difference([2]) # set([1, 3])
set([1, 2, 3]).difference([0, 1], [3, 4]) # set([2])
```
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
## difference\_update
```
None set.difference_update(*others)
```
Removes any elements found in any others from this set.
If `s` and `t` are sets, `s.difference_update(t)` is equivalent
to `s -= t`; however, note that the `-=` augmented assignment requires both
sides to be sets, while the `difference_update` method also accepts sequences and dicts.
It is permissible to call `difference_update` without any arguments; this leaves the
set unchanged.
For example,
```
s = set([1, 2, 3, 4])
s.difference_update([2]) # None; s is set([1, 3, 4])
s.difference_update([0, 1], [4, 5]) # None; s is set([3])
```
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
## discard
```
None set.discard(element)
```
Removes an element from the set if it is present.
It is permissible to `discard` a value not present in the set; this leaves the set
unchanged. If you want to fail on an attempt to remove a non-present element, use
[`remove`](#remove) instead. If you need to remove multiple elements from a
set, see [`difference_update`](#difference_update) or the `-=`
augmented assignment operation.
For example,
```
s = set(["x", "y"])
s.discard("y") # None; s == set(["x"])
s.discard("y") # None; s == set(["x"])
```
### Parameters
| Parameter | Description |
| - | - |
| `element` | required Element to discard. Must be hashable. |
## intersection
```
set set.intersection(*others)
```
Returns a new mutable set containing the intersection of this set with others.
If `s` and `t` are sets, `s.intersection(t)` is equivalent to
`s & t`; however, note that the `&` operation requires both sides to
be sets, while the `intersection` method also accepts sequences and dicts.
It is permissible to call `intersection` without any arguments; this returns a copy of
the set.
For example,
```
set([1, 2]).intersection([2, 3]) # set([2])
set([1, 2, 3]).intersection([0, 1], [1, 2]) # set([1])
```
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
## intersection\_update
```
None set.intersection_update(*others)
```
Removes any elements not found in all others from this set.
If `s` and `t` are sets, `s.intersection_update(t)` is
equivalent to `s &= t`; however, note that the `&=` augmented
assignment requires both sides to be sets, while the `intersection_update` method also
accepts sequences and dicts.
It is permissible to call `intersection_update` without any arguments; this leaves the
set unchanged.
For example,
```
s = set([1, 2, 3, 4])
s.intersection_update([0, 1, 2]) # None; s is set([1, 2])
s.intersection_update([0, 1], [1, 2]) # None; s is set([1])
```
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
## isdisjoint
```
bool set.isdisjoint(other)
```
Returns true if this set has no elements in common with another.
For example,
```
set([1, 2]).isdisjoint([3, 4]) # True
set().isdisjoint(set()) # True
set([1, 2]).isdisjoint([2, 3]) # False
```
### Parameters
| Parameter | Description |
| - | - |
| `other` | required A collection of hashable elements. |
## issubset
```
bool set.issubset(other)
```
Returns true of this set is a subset of another.
Note that a set is always considered to be a subset of itself.
For example,
```
set([1, 2]).issubset([1, 2, 3]) # True
set([1, 2]).issubset([1, 2]) # True
set([1, 2]).issubset([2, 3]) # False
```
### Parameters
| Parameter | Description |
| - | - |
| `other` | required A collection of hashable elements. |
## issuperset
```
bool set.issuperset(other)
```
Returns true of this set is a superset of another.
Note that a set is always considered to be a superset of itself.
For example,
```
set([1, 2, 3]).issuperset([1, 2]) # True
set([1, 2, 3]).issuperset([1, 2, 3]) # True
set([1, 2, 3]).issuperset([2, 3, 4]) # False
```
### Parameters
| Parameter | Description |
| - | - |
| `other` | required A collection of hashable elements. |
## pop
```
unknown set.pop()
```
Removes and returns the first element of the set (in iteration order, which is the order in which
elements were first added to the set).
Fails if the set is empty.
For example,
```
s = set([3, 1, 2])
s.pop() # 3; s == set([1, 2])
s.pop() # 1; s == set([2])
s.pop() # 2; s == set()
s.pop() # error: empty set
```
## remove
```
None set.remove(element)
```
Removes an element, which must be present in the set, from the set.
`remove` fails if the element was not present in the set. If you don't want to fail on
an attempt to remove a non-present element, use [`discard`](#discard) instead.
If you need to remove multiple elements from a set, see
[`difference_update`](#difference_update) or the `-=` augmented
assignment operation.
### Parameters
| Parameter | Description |
| - | - |
| `element` | required Element to remove. Must be an element of the set (and hashable). |
## symmetric\_difference
```
set set.symmetric_difference(other)
```
Returns a new mutable set containing the symmetric difference of this set with another collection of
hashable elements.
If `s` and `t` are sets, `s.symmetric_difference(t)` is
equivalent to `s ^ t`; however, note that the `^` operation requires both
sides to be sets, while the `symmetric_difference` method also accepts a sequence or a
dict.
For example,
```
set([1, 2]).symmetric_difference([2, 3]) # set([1, 3])
```
### Parameters
| Parameter | Description |
| - | - |
| `other` | required A collection of hashable elements. |
## symmetric\_difference\_update
```
None set.symmetric_difference_update(other)
```
Returns a new mutable set containing the symmetric difference of this set with another collection of
hashable elements.
If `s` and `t` are sets, `s.symmetric_difference_update(t)` is
equivalent to `s ^= t`; however, note that the`^=` augmented assignment requires both
sides to be sets, while the `symmetric_difference_update` method also accepts a sequence
or a dict.
For example,
```
s = set([1, 2])
s.symmetric_difference_update([2, 3]) # None; s == set([1, 3])
```
### Parameters
| Parameter | Description |
| - | - |
| `other` | required A collection of hashable elements. |
## union
```
set set.union(*others)
```
Returns a new mutable set containing the union of this set with others.
If `s` and `t` are sets, `s.union(t)` is equivalent to
`s | t`; however, note that the `|` operation requires both sides to be sets,
while the `union` method also accepts sequences and dicts.
It is permissible to call `union` without any arguments; this returns a copy of the
set.
For example,
```
set([1, 2]).union([2, 3]) # set([1, 2, 3])
set([1, 2]).union([2, 3], {3: "a", 4: "b"}) # set([1, 2, 3, 4])
```
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
## update
```
None set.update(*others)
```
Adds the elements found in others to this set.
For example,
```
s = set()
s.update([1, 2]) # None; s is set([1, 2])
s.update([2, 3], [3, 4]) # None; s is set([1, 2, 3, 4])
```
If `s` and `t` are sets, `s.update(t)` is equivalent to
`s |= t`; however, note that the `|=` augmented assignment requires both sides
to be sets, while the `update` method also accepts sequences and dicts.
It is permissible to call `update` without any arguments; this leaves the set
unchanged.
### Parameters
| Parameter | Description |
| - | - |
| `others` | required Collections of hashable elements. |
# string
Source: https://bazel.build/rules/lib/core/string
A language built-in type to support strings. Examples of string literals:
```
a = 'abc\ndef'
b = "ab'cd"
c = """multiline string"""
# Strings support slicing (negative index starts from the end):
x = "hello"[2:4] # "ll"
y = "hello"[1:-1] # "ell"
z = "hello"[:4] # "hell"
# Slice steps can be used, too:
s = "hello"[::2] # "hlo"
t = "hello"[3:0:-1] # "lle"
```
Strings are not directly iterable, use the `.elems()` method to iterate over their characters. Examples:
```
"bc" in "abcd" # evaluates to True
x = [c for c in "abc".elems()] # x == ["a", "b", "c"]
```
Implicit concatenation of strings is not allowed; use the `+` operator instead. Comparison operators perform a lexicographical comparison; use `==` to test for equality.
## Members
* [capitalize](#capitalize)
* [count](#count)
* [elems](#elems)
* [endswith](#endswith)
* [find](#find)
* [format](#format)
* [index](#index)
* [isalnum](#isalnum)
* [isalpha](#isalpha)
* [isdigit](#isdigit)
* [islower](#islower)
* [isspace](#isspace)
* [istitle](#istitle)
* [isupper](#isupper)
* [join](#join)
* [lower](#lower)
* [lstrip](#lstrip)
* [partition](#partition)
* [removeprefix](#removeprefix)
* [removesuffix](#removesuffix)
* [replace](#replace)
* [rfind](#rfind)
* [rindex](#rindex)
* [rpartition](#rpartition)
* [rsplit](#rsplit)
* [rstrip](#rstrip)
* [split](#split)
* [splitlines](#splitlines)
* [startswith](#startswith)
* [strip](#strip)
* [title](#title)
* [upper](#upper)
## capitalize
```
string string.capitalize()
```
Returns a copy of the string with its first character (if any) capitalized and the rest lowercased. This method does not support non-ascii characters.
## count
```
int string.count(sub, start=0, end=None)
```
Returns the number of (non-overlapping) occurrences of substring `sub` in string, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); required |
| `start` | [int](../core/int); or `None`; default is `0` |
| `end` | [int](../core/int); or `None`; default is `None` optional position before which to restrict to search. |
## elems
```
sequence string.elems()
```
Returns an iterable value containing successive 1-element substrings of the string. Equivalent to `[s[i] for i in range(len(s))]`, except that the returned value might not be a list.
## endswith
```
bool string.endswith(sub, start=0, end=None)
```
Returns True if the string ends with `sub`, otherwise False, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); or [tuple](../core/tuple) of [string](../core/string)s; required The suffix (or tuple of alternative suffixes) to match. |
| `start` | [int](../core/int); or `None`; default is `0` Test beginning at this position. |
| `end` | [int](../core/int); or `None`; default is `None` optional position at which to stop comparing. |
## find
```
int string.find(sub, start=0, end=None)
```
Returns the first index where `sub` is found, or -1 if no such index exists, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); required The substring to find. |
| `start` | [int](../core/int); or `None`; default is `0` Restrict to search from this position. |
| `end` | [int](../core/int); or `None`; default is `None` optional position before which to restrict to search. |
## format
```
string string.format(*args, **kwargs)
```
Perform string interpolation. Format strings contain replacement fields surrounded by curly braces `{}`. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output.If you need to include a brace character in the literal text, it can be escaped by doubling: `{{` and `}}`A replacement field can be either a name, a number, or empty. Values are converted to strings using the [str](../globals/all#str) function.
```
# Access in order:
"{} < {}".format(4, 5) == "4 < 5"
# Access by position:
"{1}, {0}".format(2, 1) == "1, 2"
# Access by name:
"x{key}x".format(key = 2) == "x2x"
```
### Parameters
| Parameter | Description |
| - | - |
| `args` | default is `()` List of arguments. |
| `kwargs` | default is `{}` Dictionary of arguments. |
## index
```
int string.index(sub, start=0, end=None)
```
Returns the first index where `sub` is found, or raises an error if no such index exists, optionally restricting to `[start:end]``start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); required The substring to find. |
| `start` | [int](../core/int); or `None`; default is `0` Restrict to search from this position. |
| `end` | [int](../core/int); or `None`; default is `None` optional position before which to restrict to search. |
## isalnum
```
bool string.isalnum()
```
Returns True if all characters in the string are alphanumeric (\[a-zA-Z0-9]) and there is at least one character.
## isalpha
```
bool string.isalpha()
```
Returns True if all characters in the string are alphabetic (\[a-zA-Z]) and there is at least one character.
## isdigit
```
bool string.isdigit()
```
Returns True if all characters in the string are digits (\[0-9]) and there is at least one character.
## islower
```
bool string.islower()
```
Returns True if all cased characters in the string are lowercase and there is at least one character.
## isspace
```
bool string.isspace()
```
Returns True if all characters are white space characters and the string contains at least one character.
## istitle
```
bool string.istitle()
```
Returns True if the string is in title case and it contains at least one character. This means that every uppercase character must follow an uncased one (e.g. whitespace) and every lowercase character must follow a cased one (e.g. uppercase or lowercase).
## isupper
```
bool string.isupper()
```
Returns True if all cased characters in the string are uppercase and there is at least one character.
## join
```
string string.join(elements)
```
Returns a string in which the string elements of the argument have been joined by this string as a separator. Example:
```
"|".join(["a", "b", "c"]) == "a|b|c"
```
### Parameters
| Parameter | Description |
| - | - |
| `elements` | iterable of [string](../core/string)s; required |
## lower
```
string string.lower()
```
Returns the lower case version of this string.
## lstrip
```
string string.lstrip(chars=None)
```
Returns a copy of the string where leading characters that appear in `chars` are removed. Note that `chars` is not a prefix: all combinations of its value are removed:
```
"abcba".lstrip("ba") == "cba"
```
### Parameters
| Parameter | Description |
| - | - |
| `chars` | [string](../core/string); or `None`; default is `None` The characters to remove, or all whitespace if None. |
## partition
```
tuple string.partition(sep)
```
Splits the input string at the first occurrence of the separator `sep` and returns the resulting partition as a three-element tuple of the form (before, separator, after). If the input string does not contain the separator, partition returns (self, '', '').
### Parameters
| Parameter | Description |
| - | - |
| `sep` | [string](../core/string); required The string to split on. |
## removeprefix
```
string string.removeprefix(prefix)
```
If the string starts with `prefix`, returns a new string with the prefix removed. Otherwise, returns the string.
### Parameters
| Parameter | Description |
| - | - |
| `prefix` | [string](../core/string); required The prefix to remove if present. |
## removesuffix
```
string string.removesuffix(suffix)
```
If the string ends with `suffix`, returns a new string with the suffix removed. Otherwise, returns the string.
### Parameters
| Parameter | Description |
| - | - |
| `suffix` | [string](../core/string); required The suffix to remove if present. |
## replace
```
string string.replace(old, new, count=-1)
```
Returns a copy of the string in which the occurrences of `old` have been replaced with `new`, optionally restricting the number of replacements to `count`.
### Parameters
| Parameter | Description |
| - | - |
| `old` | [string](../core/string); required The string to be replaced. |
| `new` | [string](../core/string); required The string to replace with. |
| `count` | [int](../core/int); default is `-1` The maximum number of replacements. If omitted, or if the value is negative, there is no limit. |
## rfind
```
int string.rfind(sub, start=0, end=None)
```
Returns the last index where `sub` is found, or -1 if no such index exists, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); required The substring to find. |
| `start` | [int](../core/int); or `None`; default is `0` Restrict to search from this position. |
| `end` | [int](../core/int); or `None`; default is `None` optional position before which to restrict to search. |
## rindex
```
int string.rindex(sub, start=0, end=None)
```
Returns the last index where `sub` is found, or raises an error if no such index exists, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); required The substring to find. |
| `start` | [int](../core/int); or `None`; default is `0` Restrict to search from this position. |
| `end` | [int](../core/int); or `None`; default is `None` optional position before which to restrict to search. |
## rpartition
```
tuple string.rpartition(sep)
```
Splits the input string at the last occurrence of the separator `sep` and returns the resulting partition as a three-element tuple of the form (before, separator, after). If the input string does not contain the separator, rpartition returns ('', '', self).
### Parameters
| Parameter | Description |
| - | - |
| `sep` | [string](../core/string); required The string to split on. |
## rsplit
```
list string.rsplit(sep, maxsplit=unbound)
```
Returns a list of all the words in the string, using `sep` as the separator, optionally limiting the number of splits to `maxsplit`. Except for splitting from the right, this method behaves like split().
### Parameters
| Parameter | Description |
| - | - |
| `sep` | [string](../core/string); required The string to split on. |
| `maxsplit` | [int](../core/int); default is `unbound` The maximum number of splits. |
## rstrip
```
string string.rstrip(chars=None)
```
Returns a copy of the string where trailing characters that appear in `chars` are removed. Note that `chars` is not a suffix: all combinations of its value are removed:
```
"abcbaa".rstrip("ab") == "abc"
```
### Parameters
| Parameter | Description |
| - | - |
| `chars` | [string](../core/string); or `None`; default is `None` The characters to remove, or all whitespace if None. |
## split
```
list string.split(sep, maxsplit=unbound)
```
Returns a list of all the words in the string, using `sep` as the separator, optionally limiting the number of splits to `maxsplit`.
### Parameters
| Parameter | Description |
| - | - |
| `sep` | [string](../core/string); required The string to split on. |
| `maxsplit` | [int](../core/int); default is `unbound` The maximum number of splits. |
## splitlines
```
sequence string.splitlines(keepends=False)
```
Splits the string at line boundaries ('\n', '\r\n', '\r') and returns the result as a new mutable list.
### Parameters
| Parameter | Description |
| - | - |
| `keepends` | [bool](../core/bool); default is `False` Whether the line breaks should be included in the resulting list. |
## startswith
```
bool string.startswith(sub, start=0, end=None)
```
Returns True if the string starts with `sub`, otherwise False, optionally restricting to `[start:end]`, `start` being inclusive and `end` being exclusive.
### Parameters
| Parameter | Description |
| - | - |
| `sub` | [string](../core/string); or [tuple](../core/tuple) of [string](../core/string)s; required The prefix (or tuple of alternative prefixes) to match. |
| `start` | [int](../core/int); or `None`; default is `0` Test beginning at this position. |
| `end` | [int](../core/int); or `None`; default is `None` Stop comparing at this position. |
## strip
```
string string.strip(chars=None)
```
Returns a copy of the string where leading or trailing characters that appear in `chars` are removed. Note that `chars` is neither a prefix nor a suffix: all combinations of its value are removed:
```
"aabcbcbaa".strip("ab") == "cbc"
```
### Parameters
| Parameter | Description |
| - | - |
| `chars` | [string](../core/string); or `None`; default is `None` The characters to remove, or all whitespace if None. |
## title
```
string string.title()
```
Converts the input string into title case, i.e. every word starts with an uppercase letter while the remaining letters are lowercase. In this context, a word means strictly a sequence of letters. This method does not support supplementary Unicode characters.
## upper
```
string string.upper()
```
Returns the upper case version of this string.
# tuple
Source: https://bazel.build/rules/lib/core/tuple
The built-in tuple type. Example tuple expressions:
```
x = (1, 2, 3)
```
Accessing elements is possible using indexing (starts from `0`):
```
e = x[1] # e == 2
```
Lists support the `+` operator to concatenate two tuples. Example:
```
x = (1, 2) + (3, 4) # x == (1, 2, 3, 4)
x = ("a", "b")
x += ("c",) # x == ("a", "b", "c")
```
Similar to lists, tuples support slice operations:
```
('a', 'b', 'c', 'd')[1:3] # ('b', 'c')
('a', 'b', 'c', 'd')[::2] # ('a', 'c')
('a', 'b', 'c', 'd')[3:0:-1] # ('d', 'c', 'b')
```
Tuples are immutable, therefore `x[1] = "a"` is not supported.
# Configuration Fragments
Source: https://bazel.build/rules/lib/fragments
Configuration fragments give rules access to language-specific parts of [configuration](builtins/configuration).
Rule implementations can get them using `ctx.fragments.[fragment name]`
* [apple](/rules/lib/fragments/apple)
* [bazel\_android](/rules/lib/fragments/bazel_android)
* [coverage](/rules/lib/fragments/coverage)
* [cpp](/rules/lib/fragments/cpp)
* [java](/rules/lib/fragments/java)
* [objc](/rules/lib/fragments/objc)
* [platform](/rules/lib/fragments/platform)
* [proto](/rules/lib/fragments/proto)
# apple
Source: https://bazel.build/rules/lib/fragments/apple
A configuration fragment for Apple platforms.
## Members
* [single\_arch\_cpu](#single_arch_cpu)
* [single\_arch\_platform](#single_arch_platform)
## single\_arch\_cpu
```
string apple.single_arch_cpu
```
The single "effective" architecture for this configuration (e.g., `i386` or `arm64`) in the context of rule logic that is only concerned with a single architecture (such as `objc_library`, which registers single-architecture compile actions).
## single\_arch\_platform
```
apple_platform apple.single_arch_platform
```
The platform of the current configuration. This should only be invoked in a context where only a single architecture may be supported; consider [multi\_arch\_platform](#multi_arch_platform) for other cases.
# bazel_android
Source: https://bazel.build/rules/lib/fragments/bazel_android
## Members
* [merge\_android\_manifest\_permissions](#merge_android_manifest_permissions)
## merge\_android\_manifest\_permissions
```
bool bazel_android.merge_android_manifest_permissions
```
The value of --merge\_android\_manifest\_permissions flag.
# coverage
Source: https://bazel.build/rules/lib/fragments/coverage
A configuration fragment representing the coverage configuration.
## Members
* [output\_generator](#output_generator)
## output\_generator
```
Label coverage.output_generator
```
Returns the label pointed to by the [`--coverage_output_generator`](https://bazel.build/reference/command-line-reference#flag--coverage_output_generator) option if coverage collection is enabled, otherwise returns `None`. Can be accessed with [`configuration_field`](../globals/bzl#configuration_field):
```
attr.label(
default = configuration_field(
fragment = "coverage",
name = "output_generator"
)
)
```
May return `None`.
# cpp
Source: https://bazel.build/rules/lib/fragments/cpp
A configuration fragment for C++.
## Members
* [apple\_generate\_dsym](#apple_generate_dsym)
* [conlyopts](#conlyopts)
* [copts](#copts)
* [custom\_malloc](#custom_malloc)
* [cxxopts](#cxxopts)
* [linkopts](#linkopts)
* [objc\_generate\_linkmap](#objc_generate_linkmap)
* [objc\_should\_strip\_binary](#objc_should_strip_binary)
* [objccopts](#objccopts)
## apple\_generate\_dsym
```
bool cpp.apple_generate_dsym
```
Whether to generate Apple debug symbol(.dSYM) artifacts.
## conlyopts
```
list cpp.conlyopts
```
The flags passed to Bazel by [`--conlyopt`](/docs/user-manual#flag--conlyopt) option.
## copts
```
list cpp.copts
```
The flags passed to Bazel by [`--copt`](/docs/user-manual#flag--copt) option.
## custom\_malloc
```
Label cpp.custom_malloc
```
Returns label pointed to by [`--custom_malloc`](/docs/user-manual#flag--custom_malloc) option. Can be accessed with [`configuration_field`](../globals/bzl#configuration_field):
```
attr.label(
default = configuration_field(
fragment = "cpp",
name = "custom_malloc"
)
)
```
May return `None`.
## cxxopts
```
list cpp.cxxopts
```
The flags passed to Bazel by [`--cxxopt`](/docs/user-manual#flag--cxxopt) option.
## linkopts
```
list cpp.linkopts
```
The flags passed to Bazel by [`--linkopt`](/docs/user-manual#flag--linkopt) option.
## objc\_generate\_linkmap
```
bool cpp.objc_generate_linkmap
```
(Apple-only) Whether to generate linkmap artifacts.
## objc\_should\_strip\_binary
```
bool cpp.objc_should_strip_binary
```
(Apple-only) whether to perform symbol and dead-code strippings on linked binaries.
## objccopts
```
list cpp.objccopts
```
The flags passed to Bazel by [`--objccopt`](/docs/user-manual#flag--objccopt) option.
# java
Source: https://bazel.build/rules/lib/fragments/java
A java compiler configuration.
## Members
* [bytecode\_optimization\_pass\_actions](#bytecode_optimization_pass_actions)
* [bytecode\_optimizer\_mnemonic](#bytecode_optimizer_mnemonic)
* [default\_javac\_flags](#default_javac_flags)
* [default\_javac\_flags\_depset](#default_javac_flags_depset)
* [default\_jvm\_opts](#default_jvm_opts)
* [disallow\_java\_import\_exports](#disallow_java_import_exports)
* [multi\_release\_deploy\_jars](#multi_release_deploy_jars)
* [one\_version\_enforcement\_level](#one_version_enforcement_level)
* [plugins](#plugins)
* [run\_android\_lint](#run_android_lint)
* [split\_bytecode\_optimization\_pass](#split_bytecode_optimization_pass)
* [strict\_java\_deps](#strict_java_deps)
* [use\_header\_compilation\_direct\_deps](#use_header_compilation_direct_deps)
* [use\_ijars](#use_ijars)
## bytecode\_optimization\_pass\_actions
```
int java.bytecode_optimization_pass_actions
```
This specifies the number of actions to divide the OPTIMIZATION stage of the bytecode optimizer into. Note that if split\_bytecode\_optimization\_pass is set, this will only change behavior if it is > 2.
## bytecode\_optimizer\_mnemonic
```
string java.bytecode_optimizer_mnemonic
```
The mnemonic for the bytecode optimizer.
## default\_javac\_flags
```
list java.default_javac_flags
```
The default flags for the Java compiler.
## default\_javac\_flags\_depset
```
depset java.default_javac_flags_depset
```
The default flags for the Java compiler.
## default\_jvm\_opts
```
list java.default_jvm_opts
```
Additional options to pass to the Java VM for each java\_binary target
## disallow\_java\_import\_exports
```
bool java.disallow_java_import_exports()
```
Returns true if java\_import exports are not allowed.
## multi\_release\_deploy\_jars
```
bool java.multi_release_deploy_jars
```
Always true. Java deploy jars preserve multi-release entries.
## one\_version\_enforcement\_level
```
string java.one_version_enforcement_level
```
The value of the --experimental\_one\_version\_enforcement flag.
## plugins
```
list java.plugins
```
A list containing the labels provided with --plugins, if any.
## run\_android\_lint
```
bool java.run_android_lint
```
The value of the --experimental\_run\_android\_lint\_on\_java\_rules flag.
## split\_bytecode\_optimization\_pass
```
bool java.split_bytecode_optimization_pass
```
Returns whether the OPTIMIZATION stage of the bytecode optimizer will be split across two actions.
## strict\_java\_deps
```
string java.strict_java_deps
```
The value of the strict\_java\_deps flag.
## use\_header\_compilation\_direct\_deps
```
bool java.use_header_compilation_direct_deps()
```
Returns true if Java header compilation should use separate outputs for direct deps.
## use\_ijars
```
bool java.use_ijars()
```
Returns true iff Java compilation should use ijars.
# objc
Source: https://bazel.build/rules/lib/fragments/objc
A configuration fragment for Objective-C.
## Members
* [alwayslink\_by\_default](#alwayslink_by_default)
* [builtin\_objc\_strip\_action](#builtin_objc_strip_action)
* [copts\_for\_current\_compilation\_mode](#copts_for_current_compilation_mode)
* [disallow\_sdk\_frameworks\_attributes](#disallow_sdk_frameworks_attributes)
* [strip\_executable\_safely](#strip_executable_safely)
* [uses\_device\_debug\_entitlements](#uses_device_debug_entitlements)
## alwayslink\_by\_default
```
bool objc.alwayslink_by_default
```
Returns whether objc\_library and objc\_import should default to alwayslink=True.
## builtin\_objc\_strip\_action
```
bool objc.builtin_objc_strip_action
```
Returns whether to emit a strip action as part of objc linking.
## copts\_for\_current\_compilation\_mode
```
list objc.copts_for_current_compilation_mode
```
Returns a list of default options to use for compiling Objective-C in the current mode.
## disallow\_sdk\_frameworks\_attributes
```
bool objc.disallow_sdk_frameworks_attributes
```
Returns whether sdk\_frameworks and weak\_sdk\_frameworks are disallowed attributes.
## strip\_executable\_safely
```
bool objc.strip_executable_safely
```
Returns whether executable strip action should use flag -x, which does not break dynamic symbol resolution.
## uses\_device\_debug\_entitlements
```
bool objc.uses_device_debug_entitlements
```
Returns whether device debug entitlements should be included when signing an application.
# platform
Source: https://bazel.build/rules/lib/fragments/platform
The platform configuration.
## Members
* [host\_platform](#host_platform)
* [platform](#platform)
## host\_platform
```
Label platform.host_platform
```
The current host platform
## platform
```
Label platform.platform
```
The current target platform
# proto
Source: https://bazel.build/rules/lib/fragments/proto
A configuration fragment representing protocol buffers.
# Global functions
Source: https://bazel.build/rules/lib/globals
This section lists the global functions available in Starlark. The list of available functions differs depending on the file type (whether a BUILD file, or a .bzl file, etc).
* [.bzl files](/rules/lib/globals/bzl)
* [All Bazel files](/rules/lib/globals/all)
* [BUILD files](/rules/lib/globals/build)
* [MODULE.bazel files](/rules/lib/globals/module)
* [REPO.bazel files](/rules/lib/globals/repo)
* [VENDOR.bazel files](/rules/lib/globals/vendor)
# All Bazel files
Source: https://bazel.build/rules/lib/globals/all
Methods available in all Bazel files, including .bzl files, BUILD, MODULE.bazel, VENDOR.bazel, and WORKSPACE.
## Members
* [abs](#abs)
* [all](#all)
* [any](#any)
* [bool](#bool)
* [dict](#dict)
* [dir](#dir)
* [enumerate](#enumerate)
* [fail](#fail)
* [float](#float)
* [getattr](#getattr)
* [hasattr](#hasattr)
* [hash](#hash)
* [int](#int)
* [len](#len)
* [list](#list)
* [max](#max)
* [min](#min)
* [print](#print)
* [range](#range)
* [repr](#repr)
* [reversed](#reversed)
* [set](#set)
* [sorted](#sorted)
* [str](#str)
* [tuple](#tuple)
* [type](#type)
* [zip](#zip)
## abs
```
unknown abs(x)
```
Returns the absolute value of a number (a non-negative number with the same magnitude).
```
abs(-2.3) == 2.3
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | [int](../core/int); or [float](../core/float); required A number (int or float) |
## all
```
bool all(elements)
```
Returns true if all elements evaluate to True or if the collection is empty. Elements are converted to boolean using the [bool](#bool) function.
```
all(["hello", 3, True]) == True
all([-1, 0, 1]) == False
```
### Parameters
| Parameter | Description |
| - | - |
| `elements` | iterable; required A collection of elements. |
## any
```
bool any(elements)
```
Returns true if at least one element evaluates to True. Elements are converted to boolean using the [bool](#bool) function.
```
any([-1, 0, 1]) == True
any([False, 0, ""]) == False
```
### Parameters
| Parameter | Description |
| - | - |
| `elements` | iterable; required A collection of elements. |
## bool
```
bool bool(x=False)
```
Constructor for the bool type. It returns `False` if the object is `None`, `False`, an empty string (`""`), the number `0`, or an empty collection (e.g. `()`, `[]`). Otherwise, it returns `True`.
### Parameters
| Parameter | Description |
| - | - |
| `x` | default is `False` The variable to convert. |
## dict
```
dict dict(pairs=[], **kwargs)
```
Creates a [dictionary](../core/dict) from an optional positional argument and an optional set of keyword arguments. In the case where the same key is given multiple times, the last value will be used. Entries supplied via keyword arguments are considered to come after entries supplied via the positional argument.
### Parameters
| Parameter | Description |
| - | - |
| `pairs` | default is `[]` A dict, or an iterable whose elements are each of length 2 (key, value). |
| `kwargs` | required Dictionary of additional entries. |
## dir
```
list dir(x)
```
Returns a list of strings: the names of the attributes and methods of the parameter object.
### Parameters
| Parameter | Description |
| - | - |
| `x` | required The object to check. |
## enumerate
```
list enumerate(list, start=0)
```
Returns a list of pairs (two-element tuples), with the index (int) and the item from the input sequence.
```
enumerate([24, 21, 84]) == [(0, 24), (1, 21), (2, 84)]
```
### Parameters
| Parameter | Description |
| - | - |
| `list` | required input sequence. |
| `start` | [int](../core/int); default is `0` start index. |
## fail
```
None fail(*args, msg=None, attr=None, sep=" ", stack_trace=True)
```
Causes execution to fail with an error.
### Parameters
| Parameter | Description |
| - | - |
| `msg` | default is `None` Deprecated: use positional arguments instead. This argument acts like an implicit leading positional argument. |
| `attr` | [string](../core/string); or `None`; default is `None` Deprecated. Causes an optional prefix containing this string to be added to the error message. |
| `sep` | [string](../core/string); default is `" "` The separator string between the objects, default is space (" "). |
| `stack_trace` | [bool](../core/bool); default is `True` If False stack trace is elided from failure for friendlier user messages |
| `args` | required A list of values, formatted with debugPrint (which is equivalent to str by default) and joined with sep (defaults to " "), that appear in the error message. |
## float
```
float float(x=unbound)
```
Returns x as a float value.
* If `x` is already a float, `float` returns it unchanged.\* If `x` is a bool, `float` returns 1.0 for True and 0.0 for False.\* If `x` is an int, `float` returns the nearest finite floating-point value to x, or an error if the magnitude is too large.\* If `x` is a string, it must be a valid floating-point literal, or be equal (ignoring case) to `NaN`, `Inf`, or `Infinity`, optionally preceded by a `+` or `-` sign.
Any other value causes an error. With no argument, `float()` returns 0.0.
### Parameters
| Parameter | Description |
| - | - |
| `x` | [string](../core/string); or [bool](../core/bool); or [int](../core/int); or [float](../core/float); default is `unbound` The value to convert. |
## getattr
```
unknown getattr(x, name, default=unbound)
```
Returns the struct's field of the given name if it exists. If not, it either returns `default` (if specified) or raises an error. `getattr(x, "foobar")` is equivalent to `x.foobar`.
```
getattr(ctx.attr, "myattr")
getattr(ctx.attr, "myattr", "mydefault")
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | required The struct whose attribute is accessed. |
| `name` | [string](../core/string); required The name of the struct attribute. |
| `default` | default is `unbound` The default value to return in case the struct doesn't have an attribute of the given name. |
## hasattr
```
bool hasattr(x, name)
```
Returns True if the object `x` has an attribute or method of the given `name`, otherwise False. Example:
```
hasattr(ctx.attr, "myattr")
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | required |
| `name` | [string](../core/string); required The name of the attribute. |
## hash
```
int hash(value)
```
Return a hash value for a string. This is computed deterministically using the same algorithm as Java's `String.hashCode()`, namely:
```
s[0] * (31^(n-1)) + s[1] * (31^(n-2)) + ... + s[n-1]
```
Hashing of values besides strings is not currently supported.
### Parameters
| Parameter | Description |
| - | - |
| `value` | [string](../core/string); required String value to hash. |
## int
```
int int(x, base=unbound)
```
Returns x as an int value.
* If `x` is already an int, `int` returns it unchanged.\* If `x` is a bool, `int` returns 1 for True and 0 for False.\* If `x` is a string, it must have the format ``. `` is either `"+"`, `"-"`, or empty (interpreted as positive). `` are a sequence of digits from 0 up to `base` - 1, where the letters a-z (or equivalently, A-Z) are used as digits for 10-35. In the case where `base` is 2/8/16, `` is optional and may be 0b/0o/0x (or equivalently, 0B/0O/0X) respectively; if the `base` is any other value besides these bases or the special value 0, the prefix must be empty. In the case where `base` is 0, the string is interpreted as an integer literal, in the sense that one of the bases 2/8/10/16 is chosen depending on which prefix if any is used. If `base` is 0, no prefix is used, and there is more than one digit, the leading digit cannot be 0; this is to avoid confusion between octal and decimal. The magnitude of the number represented by the string must be within the allowed range for the int type.\* If `x` is a float, `int` returns the integer value of the float, rounding towards zero. It is an error if x is non-finite (NaN or infinity).
This function fails if `x` is any other type, or if the value is a string not satisfying the above format. Unlike Python's `int` function, this function does not allow zero arguments, and does not allow extraneous whitespace for string arguments.
Examples:
```
int("123") == 123
int("-123") == -123
int("+123") == 123
int("FF", 16) == 255
int("0xFF", 16) == 255
int("10", 0) == 10
int("-0x10", 0) == -16
int("123.456") == 123
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | [string](../core/string); or [bool](../core/bool); or [int](../core/int); or [float](../core/float); required The string to convert. |
| `base` | [int](../core/int); default is `unbound` The base used to interpret a string value; defaults to 10. Must be between 2 and 36 (inclusive), or 0 to detect the base as if `x` were an integer literal. This parameter must not be supplied if the value is not a string. |
## len
```
int len(x)
```
Returns the length of a string, sequence (such as a list or tuple), dict, set, or other iterable.
### Parameters
| Parameter | Description |
| - | - |
| `x` | iterable; or [string](../core/string); required The value whose length to report. |
## list
```
list list(x=[])
```
Returns a new list with the same elements as the given iterable value.
```
list([1, 2]) == [1, 2]
list((2, 3, 2)) == [2, 3, 2]
list({5: "a", 2: "b", 4: "c"}) == [5, 2, 4]
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | iterable; default is `[]` The object to convert. |
## max
```
unknown max(*args, key=None)
```
Returns the largest one of all given arguments. If only one positional argument is provided, it must be a non-empty iterable.It is an error if elements are not comparable (for example int with string), or if no arguments are given.
```
max(2, 5, 4) == 5
max([5, 6, 3]) == 6
max("two", "three", "four", key = len) =="three" # the longest
max([1, -1, -2, 2], key = abs) == -2 # the first encountered with maximal key value
```
### Parameters
| Parameter | Description |
| - | - |
| `key` | callable; or `None`; default is `None` An optional function applied to each element before comparison. Must not mutate the args sequence. |
| `args` | required The elements to be checked. |
## min
```
unknown min(*args, key=None)
```
Returns the smallest one of all given arguments. If only one positional argument is provided, it must be a non-empty iterable. It is an error if elements are not comparable (for example int with string), or if no arguments are given.
```
min(2, 5, 4) == 2
min([5, 6, 3]) == 3
min("six", "three", "four", key = len) == "six" # the shortest
min([2, -2, -1, 1], key = abs) == -1 # the first encountered with minimal key value
```
### Parameters
| Parameter | Description |
| - | - |
| `key` | callable; or `None`; default is `None` An optional function applied to each element before comparison. Must not mutate the args sequence. |
| `args` | required The elements to be checked. |
## print
```
None print(*args, sep=" ")
```
Prints `args` as debug output. It will be prefixed with the string `"DEBUG"` and the location (file and line number) of this call. The exact way in which the arguments are converted to strings is unspecified and may change at any time. In particular, it may be different from (and more detailed than) the formatting done by [`str()`](#str) and [`repr()`](#repr).
Using `print` in production code is discouraged due to the spam it creates for users. For deprecations, prefer a hard error using [`fail()`](#fail) whenever possible.
### Parameters
| Parameter | Description |
| - | - |
| `sep` | [string](../core/string); default is `" "` The separator string between the objects, default is space (" "). |
| `args` | required The objects to print. |
## range
```
sequence range(start_or_stop, stop=unbound, step=1)
```
Creates a list where items go from `start` to `stop`, using a `step` increment. If a single argument is provided, items will range from 0 to that element.
```
range(4) == [0, 1, 2, 3]
range(3, 9, 2) == [3, 5, 7]
range(3, 0, -1) == [3, 2, 1]
```
### Parameters
| Parameter | Description |
| - | - |
| `start_or_stop` | [int](../core/int); required Value of the start element if stop is provided, otherwise value of stop and the actual start is 0 |
| `stop` | [int](../core/int); default is `unbound` optional index of the first item *not* to be included in the resulting list; generation of the list stops before `stop` is reached. |
| `step` | [int](../core/int); default is `1` The increment (default is 1). It may be negative. |
## repr
```
string repr(x)
```
Converts any object to a string representation. This is useful for debugging.
```
repr("ab") == '"ab"'
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | required |
## reversed
```
list reversed(sequence)
```
Returns a new, unfrozen list that contains the elements of the original iterable sequence in reversed order.
```
reversed([3, 5, 4]) == [4, 5, 3]
```
### Parameters
| Parameter | Description |
| - | - |
| `sequence` | iterable; required The iterable sequence (e.g. list) to be reversed. |
## set
```
set set(elements=[])
```
Creates a new [set](../core/set) containing the unique elements of a given
iterable, preserving iteration order.
If called with no argument, `set()` returns a new empty set.
For example,
```
set() # an empty set
set([3, 1, 1, 2]) # set([3, 1, 2]), a set of three elements
set({"k1": "v1", "k2": "v2"}) # set(["k1", "k2"]), a set of two elements
```
### Parameters
| Parameter | Description |
| - | - |
| `elements` | iterable; default is `[]` An iterable of hashable values. |
## sorted
```
list sorted(iterable, key=None, *, reverse=False)
```
Returns a new sorted list containing all the elements of the supplied iterable sequence. An error may occur if any pair of elements x, y may not be compared using x \< y. The elements are sorted into ascending order, unless the reverse argument is True, in which case the order is descending.
Sorting is stable: elements that compare equal retain their original relative order.
```
sorted([3, 5, 4]) == [3, 4, 5]
sorted([3, 5, 4], reverse = True) == [5, 4, 3]
sorted(["two", "three", "four"], key = len) == ["two", "four", "three"] # sort by length
```
### Parameters
| Parameter | Description |
| - | - |
| `iterable` | iterable; required The iterable sequence to sort. |
| `key` | callable; or `None`; default is `None` An optional function applied to each element before comparison. |
| `reverse` | [bool](../core/bool); default is `False` Return results in descending order. |
## str
```
string str(x)
```
Converts any object to string. This is useful for debugging.
```
str("ab") == "ab"
str(8) == "8"
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | required The object to convert. |
## tuple
```
tuple tuple(x=())
```
Returns a tuple with the same elements as the given iterable value.
```
tuple([1, 2]) == (1, 2)
tuple((2, 3, 2)) == (2, 3, 2)
tuple({5: "a", 2: "b", 4: "c"}) == (5, 2, 4)
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | iterable; default is `()` The object to convert. |
## type
```
string type(x)
```
Returns the type name of its argument. This is useful for debugging and type-checking. Examples:
```
type(2) == "int"
type([1]) == "list"
type(struct(a = 2)) == "struct"
```
This function might change in the future. To write Python-compatible code and be future-proof, use it only to compare return values:
```
if type(x) == type([]): # if x is a list
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | required The object to check type of. |
## zip
```
list zip(*args)
```
Returns a `list` of `tuple`s, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The list has the size of the shortest input. With a single iterable argument, it returns a list of 1-tuples. With no arguments, it returns an empty list. Examples:
```
zip() # == []
zip([1, 2]) # == [(1,), (2,)]
zip([1, 2], [3, 4]) # == [(1, 3), (2, 4)]
zip([1, 2], [3, 4, 5]) # == [(1, 3), (2, 4)]
```
### Parameters
| Parameter | Description |
| - | - |
| `args` | required lists to zip. |
# BUILD files
Source: https://bazel.build/rules/lib/globals/build
Methods available in BUILD files. See also the Build Encyclopedia for extra [functions](/reference/be/functions) and build rules, which can also be used in BUILD files.
## Members
* [depset](#depset)
* [existing\_rule](#existing_rule)
* [existing\_rules](#existing_rules)
* [exports\_files](#exports_files)
* [glob](#glob)
* [module\_name](#module_name)
* [module\_version](#module_version)
* [package](#package)
* [package\_default\_visibility](#package_default_visibility)
* [package\_group](#package_group)
* [package\_name](#package_name)
* [package\_relative\_label](#package_relative_label)
* [repo\_name](#repo_name)
* [repository\_name](#repository_name)
* [select](#select)
* [subpackages](#subpackages)
## depset
```
depset depset(direct=None, order="default", *, transitive=None)
```
Creates a [depset](../builtins/depset). The `direct` parameter is a list of direct elements of the depset, and `transitive` parameter is a list of depsets whose elements become indirect elements of the created depset. The order in which elements are returned when the depset is converted to a list is specified by the `order` parameter. See the [Depsets overview](https://bazel.build/extending/depsets) for more information.
All elements (direct and indirect) of a depset must be of the same type, as obtained by the expression [`type(x)`](../globals/all#type).
Because a hash-based set is used to eliminate duplicates during iteration, all elements of a depset should be hashable. However, this invariant is not currently checked consistently in all constructors. Use the --incompatible\_always\_check\_depset\_elements flag to enable consistent checking; this will be the default behavior in future releases; see [Issue 10313](https://github.com/bazelbuild/bazel/issues/10313).
In addition, elements must currently be immutable, though this restriction will be relaxed in future.
The order of the created depset should be *compatible* with the order of its `transitive` depsets. `"default"` order is compatible with any other order, all other orders are only compatible with themselves.
### Parameters
| Parameter | Description |
| - | - |
| `direct` | [sequence](../core/list); or `None`; default is `None` A list of *direct* elements of a depset. |
| `order` | [string](../core/string); default is `"default"` The traversal strategy for the new depset. See [here](../builtins/depset) for the possible values. |
| `transitive` | [sequence](../core/list) of [depset](../builtins/depset)s; or `None`; default is `None` A list of depsets whose elements will become indirect elements of the depset. |
## existing\_rule
```
unknown existing_rule(name)
```
Returns an immutable dict-like object that describes the attributes of a rule instantiated in this thread's package, or `None` if no rule instance of that name exists.
Here, an *immutable dict-like object* means a deeply immutable object `x` supporting dict-like iteration, `len(x)`, `name in x`, `x[name]`, `x.get(name)`, `x.items()`, `x.keys()`, and `x.values()`.
The result contains an entry for each attribute, with the exception of private ones (whose names do not start with a letter) and a few unrepresentable legacy attribute types. In addition, the dict contains entries for the rule instance's `name` and `kind` (for example, `'cc_binary'`).
The values of the result represent attribute values as follows:
* Attributes of type str, int, and bool are represented as is.
* Labels are converted to strings of the form `':foo'` for targets in the same package or `'//pkg:name'` for targets in a different package.
* Lists are represented as tuples, and dicts are converted to new, mutable dicts. Their elements are recursively converted in the same fashion.
* `select` values are returned with their contents transformed as described above.
* Attributes for which no value was specified during rule instantiation and whose default value is computed are excluded from the result. (Computed defaults cannot be computed until the analysis phase.).
If possible, use this function only in [implementation functions of rule finalizer symbolic macros](https://bazel.build/extending/macros#finalizers). Use of this function in other contexts is not recommened, and will be disabled in a future Bazel release; it makes `BUILD` files brittle and order-dependent. Also, beware that it differs subtly from the two other conversions of rule attribute values from internal form to Starlark: one used by computed defaults, the other used by `ctx.attr.foo`.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required The name of the target. |
## existing\_rules
```
unknown existing_rules()
```
Returns an immutable dict-like object describing the rules so far instantiated in this thread's package. Each entry of the dict-like object maps the name of the rule instance to the result that would be returned by `existing_rule(name)`.
Here, an *immutable dict-like object* means a deeply immutable object `x` supporting dict-like iteration, `len(x)`, `name in x`, `x[name]`, `x.get(name)`, `x.items()`, `x.keys()`, and `x.values()`.
If possible, use this function only in [implementation functions of rule finalizer symbolic macros](https://bazel.build/extending/macros#finalizers). Use of this function in other contexts is not recommened, and will be disabled in a future Bazel release; it makes `BUILD` files brittle and order-dependent.
## exports\_files
```
None exports_files(srcs, visibility=None, licenses=None)
```
Specifies a list of files belonging to this package that are exported to other packages.
### Parameters
| Parameter | Description |
| - | - |
| `srcs` | [sequence](../core/list) of [string](../core/string)s; required The list of files to export. |
| `visibility` | [sequence](../core/list); or `None`; default is `None` A visibility declaration can to be specified. The files will be visible to the targets specified. If no visibility is specified, the files will be visible to every package. |
| `licenses` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Licenses to be specified. |
## glob
```
sequence glob(include=[], exclude=[], exclude_directories=1, allow_empty=unbound)
```
Glob returns a new, mutable, sorted list of every file in the current package that:
* Matches at least one pattern in `include`.
* Does not match any of the patterns in `exclude` (default `[]`).
If the `exclude_directories` argument is enabled (set to `1`), files of type directory will be omitted from the results (default `1`).
### Parameters
| Parameter | Description |
| - | - |
| `include` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to include. |
| `exclude` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to exclude. |
| `exclude_directories` | [int](../core/int); default is `1` A flag whether to exclude directories or not. |
| `allow_empty` | default is `unbound` Whether we allow glob patterns to match nothing. If `allow_empty` is False, each individual include pattern must match something and also the final result must be non-empty (after the matches of the `exclude` patterns are excluded). |
## module\_name
```
string module_name()
```
The name of the Bazel module associated with the repo this package is in. If this package is from a repo defined in WORKSPACE instead of MODULE.bazel, this is empty. For repos generated by module extensions, this is the name of the module hosting the extension. It's the same as the `module.name` field seen in `module_ctx.modules`.
May return `None`.
## module\_version
```
string module_version()
```
The version of the Bazel module associated with the repo this package is in. If this package is from a repo defined in WORKSPACE instead of MODULE.bazel, this is empty. For repos generated by module extensions, this is the version of the module hosting the extension. It's the same as the `module.version` field seen in `module_ctx.modules`.
May return `None`.
## package
```
unknown package(**kwargs)
```
Declares metadata that applies to every rule in the package. It must be called at most once within a package (BUILD file). If called, it should be the first call in the BUILD file, right after the `load()` statements.
### Parameters
| Parameter | Description |
| - | - |
| `kwargs` | required See the [`package()`](/reference/be/functions#package) function in the Build Encyclopedia for applicable arguments. |
## package\_default\_visibility
```
List package_default_visibility()
```
Returns the default visibility of the package being evaluated. This is the value of the `default_visibility` parameter of `package()`, extended to include the package itself.
## package\_group
```
None package_group(*, name, packages=[], includes=[])
```
This function defines a set of packages and assigns a label to the group. The label can be referenced in `visibility` attributes.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required The unique name for this rule. |
| `packages` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A complete enumeration of packages in this group. |
| `includes` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Other package groups that are included in this one. |
## package\_name
```
string package_name()
```
The name of the package being evaluated, without the repository name. For example, in the BUILD file `some/package/BUILD`, its value will be `some/package`. If the BUILD file calls a function defined in a .bzl file, `package_name()` will match the caller BUILD file package. The value will always be an empty string for the root package.
## package\_relative\_label
```
Label package_relative_label(input)
```
Converts the input string into a [Label](../builtins/Label) object, in the context of the package currently being initialized (that is, the `BUILD` file for which the current macro is executing). If the input is already a `Label`, it is returned unchanged.
This function may only be called while evaluating a BUILD file and the macros it directly or indirectly calls; it may not be called in (for instance) a rule implementation function.
The result of this function is the same `Label` value as would be produced by passing the given string to a label-valued attribute of a target declared in the BUILD file.
*Usage note:* The difference between this function and [`Label()`](../builtins/Label#Label) is that `Label()` uses the context of the package of the `.bzl` file that called it, not the package of the `BUILD` file. Use `Label()` when you need to refer to a fixed target that is hardcoded into the macro, such as a compiler. Use `package_relative_label()` when you need to normalize a label string supplied by the BUILD file to a `Label` object. (There is no way to convert a string to a `Label` in the context of a package other than the BUILD file or the calling .bzl file. For that reason, outer macros should always prefer to pass Label objects to inner macros rather than label strings.)[`ctx.package_relative_label()`](ctx#package_relative_label) provides the same functionality within a rule or aspect implementation function.
### Parameters
| Parameter | Description |
| - | - |
| `input` | [string](../core/string); or [Label](../builtins/Label); required The input label string or Label object. If a Label object is passed, it's returned as is. |
## repo\_name
```
string repo_name()
```
The canonical name of the repository containing the package currently being evaluated, with no leading at-signs.
## repository\_name
```
string repository_name()
```
**Experimental**. This API is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--+incompatible_enable_deprecated_label_apis`
**Deprecated.** Prefer to use [`repo_name`](#repo_name) instead, which doesn't contain the spurious leading at-sign, but behaves identically otherwise.
The canonical name of the repository containing the package currently being evaluated, with a single at-sign (`@`) prefixed. For example, in packages that are called into existence by the WORKSPACE stanza `local_repository(name='local', path=...)` it will be set to `@local`. In packages in the main repository, it will be set to `@`.
## select
```
select select(x, no_match_error='')
```
`select()` is the helper function that makes a rule attribute [configurable](/reference/be/common-definitions#configurable-attributes). See [build encyclopedia](/reference/be/functions#select) for details.
### Parameters
| Parameter | Description |
| - | - |
| `x` | [dict](../core/dict); required |
| `no_match_error` | [string](../core/string); default is `''` Optional custom error to report if no condition matches. |
## subpackages
```
sequence subpackages(*, include, exclude=[], allow_empty=False)
```
Returns a new mutable list of every direct subpackage of the current package, regardless of file-system directory depth. List returned is sorted and contains the names of subpackages relative to the current package. It is advised to prefer using the methods in bazel\_skylib.subpackages module rather than calling this function directly.
### Parameters
| Parameter | Description |
| - | - |
| `include` | [sequence](../core/list) of [string](../core/string)s; required The list of glob patterns to include in subpackages scan. |
| `exclude` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to exclude from subpackages scan. |
| `allow_empty` | [bool](../core/bool); default is `False` Whether we fail if the call returns an empty list. By default empty list indicates potential error in BUILD file where the call to subpackages() is superflous. Setting to true allows this function to succeed in that case. |
# .bzl files
Source: https://bazel.build/rules/lib/globals/bzl
Global methods available in all .bzl files.
## Members
* [analysis\_test\_transition](#analysis_test_transition)
* [aspect](#aspect)
* [configuration\_field](#configuration_field)
* [depset](#depset)
* [exec\_group](#exec_group)
* [exec\_transition](#exec_transition)
* [macro](#macro)
* [materializer\_rule](#materializer_rule)
* [module\_extension](#module_extension)
* [provider](#provider)
* [repository\_rule](#repository_rule)
* [rule](#rule)
* [select](#select)
* [subrule](#subrule)
* [tag\_class](#tag_class)
* [visibility](#visibility)
## analysis\_test\_transition
```
transition analysis_test_transition(*, settings)
```
Creates a configuration transition to be applied on an analysis-test rule's dependencies. This transition may only be applied on attributes of rules with `analysis_test = True`. Such rules are restricted in capabilities (for example, the size of their dependency tree is limited), so transitions created using this function are limited in potential scope as compared to transitions created using [`transition()`](../builtins/transition).
This function is primarily designed to facilitate the [Analysis Test Framework](https://bazel.build/rules/testing) core library. See its documentation (or its implementation) for best practices.
### Parameters
| Parameter | Description |
| - | - |
| `settings` | [dict](../core/dict); required A dictionary containing information about configuration settings which should be set by this configuration transition. Keys are build setting labels and values are their new post-transition values. All other settings are unchanged. Use this to declare specific configuration settings that an analysis test requires to be set in order to pass. |
## aspect
```
Aspect aspect(implementation, attr_aspects=[], toolchains_aspects=[], attrs={}, required_providers=[], required_aspect_providers=[], required_aspect_hints_providers=[], provides=[], requires=[], propagation_predicate=None, fragments=[], host_fragments=[], toolchains=[], doc=None, *, apply_to_generating_rules=False, exec_compatible_with=[], exec_groups=None, subrules=[])
```
Creates a new aspect. The result of this function must be stored in a global value. Please see the [introduction to Aspects](https://bazel.build/extending/aspects) for more details.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | [function](../core/function); required A Starlark function that implements this aspect, with exactly two parameters: [Target](../builtins/Target) (the target to which the aspect is applied) and [ctx](../builtins/ctx) (the rule context which the target is created from). Attributes of the target are available via the `ctx.rule` field. This function is evaluated during the analysis phase for each application of an aspect to a target. |
| `attr_aspects` | [sequence](../core/list) of [string](../core/string)s; or [function](../core/function); default is `[]` Accepts a list of attribute names or \[Experimental] a function that returns the list of attribute names. The aspect propagates along dependencies specified in the attributes of a target with these names. Common values here include `deps` and `exports`. The list can also contain a single string `"*"` to propagate along all dependencies of a target. |
| `toolchains_aspects` | [sequence](../core/list); or [function](../core/function); default is `[]` Accepts a list of toolchain types or \[Experimental] a function that returns the list of toolchain types. The aspect propagates to target toolchains which match these toolchain types. |
| `attrs` | [dict](../core/dict); default is `{}` A dictionary declaring all the attributes of the aspect. It maps from an attribute name to an attribute object, like `attr.label` or `attr.string` (see [`attr`](../toplevel/attr) module). Aspect attributes are available to implementation function as fields of `ctx` parameter. Implicit attributes starting with `_` must have default values, and have type `label` or `label_list`. Explicit attributes must have type `string`, and must use the `values` restriction. Explicit attributes restrict the aspect to only be used with rules that have attributes of the same name, type, and valid values according to the restriction. Declared attributes will convert `None` to the default value. |
| `required_providers` | [sequence](../core/list); default is `[]` This attribute allows the aspect to limit its propagation to only the targets whose rules advertise its required providers. The value must be a list containing either individual providers or lists of providers but not both. For example, `[[FooInfo], [BarInfo], [BazInfo, QuxInfo]]` is a valid value while `[FooInfo, BarInfo, [BazInfo, QuxInfo]]` is not valid. An unnested list of providers will automatically be converted to a list containing one list of providers. That is, `[FooInfo, BarInfo]` will automatically be converted to `[[FooInfo, BarInfo]]`. To make some rule (e.g. `some_rule`) targets visible to an aspect, `some_rule` must advertise all providers from at least one of the required providers lists. For example, if the `required_providers` of an aspect are `[[FooInfo], [BarInfo], [BazInfo, QuxInfo]]`, this aspect can see `some_rule` targets if and only if `some_rule` provides `FooInfo`, *or* `BarInfo`, *or* both `BazInfo` *and* `QuxInfo`. |
| `required_aspect_providers` | [sequence](../core/list); default is `[]` This attribute allows this aspect to inspect other aspects. The value must be a list containing either individual providers or lists of providers but not both. For example, `[[FooInfo], [BarInfo], [BazInfo, QuxInfo]]` is a valid value while `[FooInfo, BarInfo, [BazInfo, QuxInfo]]` is not valid. An unnested list of providers will automatically be converted to a list containing one list of providers. That is, `[FooInfo, BarInfo]` will automatically be converted to `[[FooInfo, BarInfo]]`. To make another aspect (e.g. `other_aspect`) visible to this aspect, `other_aspect` must provide all providers from at least one of the lists. In the example of `[[FooInfo], [BarInfo], [BazInfo, QuxInfo]]`, this aspect can see `other_aspect` if and only if `other_aspect` provides `FooInfo`, *or* `BarInfo`, *or* both `BazInfo` *and* `QuxInfo`. |
| `required_aspect_hints_providers` | [sequence](../core/list); default is `[]` This attribute is used to match aspects to targets that appear in the `aspect_hints` attribute. With the `--incompatible_require_matching_aspect_hints_providers` flag enabled, the `aspect_hints` attribute is evaluated differently from other attributes: A target `T` in the `aspect_hints` attribute of a target `P` is added as a dependency of `P` only if the rule class of `T` declares providers that satisfy the `required_aspect_hints_providers` of one or more aspects being applied to `P`. This avoids analysis time, memory usage, configuration mismatches, conformance test failures, etc. for targets that are not actually needed by any aspect. The target's providers to be matched against an aspect's `required_aspect_hints_providers` must be declared in the rule class (via the `provides` argument of `rule()`) so that targets and aspects can be matched without actually evaluating the target. That is, it is not sufficient to just return the provider from the rule implementation function. The value of `required_aspect_hints_providers` must be a list containing either individual providers or lists of providers but not both. For example, `[[FooInfo], [BarInfo], [BazInfo, QuxInfo]]` is a valid value while `[FooInfo, BarInfo, [BazInfo, QuxInfo]]` is not valid. An unnested list of providers will automatically be converted to a list containing one list of providers. That is, `[FooInfo, BarInfo]` will automatically be converted to `[[FooInfo, BarInfo]]`. |
| `provides` | [sequence](../core/list); default is `[]` A list of providers that the implementation function must return. It is an error if the implementation function omits any of the types of providers listed here from its return value. However, the implementation function may return additional providers not listed here. Each element of the list is an `*Info` object returned by [`provider()`](../globals/bzl#provider). When a target of the rule is used as a dependency for a target that declares a required provider, it is not necessary to specify that provider here. It is enough that the implementation function returns it. However, it is considered best practice to specify it, even though this is not required. The [`required_providers`](../globals/bzl#aspect.required_providers) field of an [aspect](../globals/bzl#aspect) does, however, require that providers are specified here. |
| `requires` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` List of aspects required to be propagated before this aspect. |
| `propagation_predicate` | [function](../core/function); or `None`; default is `None` Experimental: a function that returns a boolean value indicating whether the aspect should be propagated to a target. |
| `fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of names of configuration fragments that the aspect requires in target configuration. |
| `host_fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of names of configuration fragments that the aspect requires in host configuration. |
| `toolchains` | [sequence](../core/list); default is `[]` If set, the set of toolchains this aspect requires. The list can contain String, Label, or StarlarkToolchainTypeApi objects, in any combination. Toolchains will be found by checking the current platform, and provided to the aspect implementation via `ctx.toolchain`. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the aspect that can be extracted by documentation generating tools. |
| `apply_to_generating_rules` | [bool](../core/bool); default is `False` If true, the aspect will, when applied to an output file, instead apply to the output file's generating rule. For example, suppose an aspect propagates transitively through attribute `deps` and it is applied to target `alpha`. Suppose `alpha` has `deps = [':beta_output']`, where `beta_output` is a declared output of a target `beta`. Suppose `beta` has a target `charlie` as one of its `deps`. If `apply_to_generating_rules=True` for the aspect, then the aspect will propagate through `alpha`, `beta`, and `charlie`. If False, then the aspect will propagate only to `alpha`. False by default. |
| `exec_compatible_with` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A list of constraints on the execution platform that apply to all instances of this aspect. |
| `exec_groups` | [dict](../core/dict); or `None`; default is `None` Dict of execution group name (string) to [`exec_group`s](../globals/bzl#exec_group). If set, allows aspects to run actions on multiple execution platforms within a single instance. See [execution groups documentation](/reference/exec-groups) for more info. |
| `subrules` | [sequence](../core/list) of [Subrule](../builtins/Subrule)s; default is `[]` Experimental: list of subrules used by this aspect. |
## configuration\_field
```
LateBoundDefault configuration_field(fragment, name)
```
References a late-bound default value for an attribute of type [label](../toplevel/attr#label). A value is 'late-bound' if it requires the configuration to be built before determining the value. Any attribute using this as a value must [be private](https://bazel.build/extending/rules#private-attributes).
Example usage:
Defining a rule attribute:
```
'_foo': attr.label(default=configuration_field(fragment='java', name='toolchain'))
```
Accessing in rule implementation:
```
def _rule_impl(ctx):
foo_info = ctx.attr._foo
...
```
### Parameters
| Parameter | Description |
| - | - |
| `fragment` | [string](../core/string); required |
| `name` | [string](../core/string); required |
## depset
```
depset depset(direct=None, order="default", *, transitive=None)
```
Creates a [depset](../builtins/depset). The `direct` parameter is a list of direct elements of the depset, and `transitive` parameter is a list of depsets whose elements become indirect elements of the created depset. The order in which elements are returned when the depset is converted to a list is specified by the `order` parameter. See the [Depsets overview](https://bazel.build/extending/depsets) for more information.
All elements (direct and indirect) of a depset must be of the same type, as obtained by the expression [`type(x)`](../globals/all#type).
Because a hash-based set is used to eliminate duplicates during iteration, all elements of a depset should be hashable. However, this invariant is not currently checked consistently in all constructors. Use the --incompatible\_always\_check\_depset\_elements flag to enable consistent checking; this will be the default behavior in future releases; see [Issue 10313](https://github.com/bazelbuild/bazel/issues/10313).
In addition, elements must currently be immutable, though this restriction will be relaxed in future.
The order of the created depset should be *compatible* with the order of its `transitive` depsets. `"default"` order is compatible with any other order, all other orders are only compatible with themselves.
### Parameters
| Parameter | Description |
| - | - |
| `direct` | [sequence](../core/list); or `None`; default is `None` A list of *direct* elements of a depset. |
| `order` | [string](../core/string); default is `"default"` The traversal strategy for the new depset. See [here](../builtins/depset) for the possible values. |
| `transitive` | [sequence](../core/list) of [depset](../builtins/depset)s; or `None`; default is `None` A list of depsets whose elements will become indirect elements of the depset. |
## exec\_group
```
exec_group exec_group(*, toolchains=[], exec_compatible_with=[])
```
Creates an [execution group](/reference/exec-groups) which can be used to create actions for a specific execution platform during rule implementation.
### Parameters
| Parameter | Description |
| - | - |
| `toolchains` | [sequence](../core/list); default is `[]` The set of toolchains this execution group requires. The list can contain String, Label, or StarlarkToolchainTypeApi objects, in any combination. |
| `exec_compatible_with` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A list of constraints on the execution platform. |
## exec\_transition
```
transition exec_transition(*, implementation, inputs, outputs)
```
A specialized version of [`transition()`](../builtins/transition) used to define the exec transition. See its documentation (or its implementation) for best practices. Only usable from the Bazel builtins.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | callable; required |
| `inputs` | [sequence](../core/list) of [string](../core/string)s; required |
| `outputs` | [sequence](../core/list) of [string](../core/string)s; required |
## macro
```
macro macro(*, implementation, attrs={}, inherit_attrs=None, finalizer=False, doc=None)
```
Defines a symbolic macro, which may be called in `BUILD` files or macros (legacy or
symbolic) to define targets – possibly multiple ones.
The value returned by `macro(...)` must be assigned to a global variable in a .bzl
file; the name of the global variable will be the macro symbol's name.
See [Macros](https://bazel.build/extending/macros) for a comprehensive guide on how to use symbolic
macros.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | [function](../core/function.html); required The Starlark function implementing this macro. The values of the macro's attributes are passed to the implementation function as keyword arguments. The implementation function must have at least two named parameters, `name` and `visibility`, and if the macro inherits attributes (see `inherit_attrs` below), it must have a `**kwargs` residual keyword parameter. By convention, the implementation function should have a named parameter for any attribute that the macro needs to examine, modify, or pass to non-"main" targets, while the "bulk" inherited attributes which will be passed to the "main" target unchanged are passed as `**kwargs`. The implementation function must not return a value. Instead, the implementation function *declares targets* by calling rule or macro symbols. The name of any target or inner symbolic macro declared by a symbolic macro (including by any Starlark function that the macro's implementation function transitively calls) must either equal `name` (this is referred to as the "main" target) or start with `name`, followed by a separator chracter (`"_"`, `"-"`, or `"."`) and a string suffix. (Targets violating this naming scheme are allowed to be declared, but cannot be built, configured, or depended upon.) By default, targets declared by a symbolic macro (including by any Starlark function that the macro's implementation function transitively calls) are visible only in the package containing the .bzl file defining the macro. To declare targets visible externally, *including to the caller of the symbolic macro*, the implementation function must set `visibility` appropriately – typically, by passing `visibility = visibility` to the rule or macro symbol being called. The following APIs are unavailable within a macro implementation function and any Starlark function it transitively calls:
(allowed in rule finalizers only, see `finalizer` below) [`native.existing_rules()`](../toplevel/native#existing_rules), [`native.existing_rule()`](../toplevel/native#existing_rule)
|
| `attrs` | [dict](../core/dict); default is `{}` A dictionary of the attributes this macro supports, analogous to [rule.attrs](#rule.attrs). Keys are attribute names, and values are either attribute objects like `attr.label_list(...)` (see the [attr](../toplevel/attr) module), or `None`. A `None` entry means that the macro does not have an attribute by that name, even if it would have otherwise inherited one via `inherit_attrs` (see below). The special `name` attribute is predeclared and must not be included in the dictionary. The `visibility` attribute name is reserved and must not be included in the dictionary. Attributes whose names start with `_` are private -- they cannot be passed at the call site of the rule. Such attributes can be assigned a default value (as in `attr.label(default="//pkg:foo")`) to create an implicit dependency on a label. To limit memory usage, there is a cap on the number of attributes that may be declared. |
| `inherit_attrs` | [rule](../builtins/rule.html); or [macro](../builtins/macro.html); or [string](../core/string.html); or `None`; default is `None` A rule symbol, macro symbol, or the name of a built-in common attribute list (see below) from which the macro should inherit attributes. If `inherit_attrs` is set to the string `"common"`, the macro will inherit [common rule attribute definitions](/reference/be/common-definitions#common-attributes) used by all Starlark rules. Note that if the return value of `rule()` or `macro()` was not assigned to a global variable in a .bzl file, then such a value has not been registered as a rule or macro symbol, and therefore cannot be used for `inherit_attrs`. The inheritance mechanism works as follows:
The special `name` and `visibility` attributes are never inherited;
Hidden attributes (ones whose name starts with `"_"`) are never inherited;
Attributes whose names are already defined in the `attrs` dictionary are never inherited (the entry in `attrs` takes precedence; note that an entry may be set to `None` to ensure that no attribute by that name gets defined on the macro);
All other attributes are inherited from the rule or macro and effectively merged into the `attrs` dict.
When a non-mandatory attribute is inherited, the default value of the attribute is overridden to be `None`, regardless of what it was specified in the original rule or macro. This ensures that when the macro forwards the attribute's value to an instance of the wrapped rule or macro – such as by passing in the unmodified `**kwargs` – a value that was absent from the outer macro's call will also be absent in the inner rule or macro's call (since passing `None` to an attribute is treated the same as omitting the attribute). This is important because omitting an attribute has subtly different semantics from passing its apparent default value. In particular, omitted attributes are not shown in some `bazel query` output formats, and computed defaults only execute when the value is omitted. If the macro needs to examine or modify an inherited attribute – for example, to add a value to an inherited `tags` attribute – you must make sure to handle the `None` case in the macro's implementation function. For example, the following macro inherits all attributes from `native.cc_library`, except for `cxxopts` (which is removed from the attribute list) and `copts` (which is given a new definition). It also takes care to checks for the default `None` value of the inherited `tags` attribute before appending an additional tag. `def _my_cc_library_impl(name, visibility, tags, **kwargs): # Append a tag; tags attr was inherited from native.cc_library, and # therefore is None unless explicitly set by the caller of my_cc_library() my_tags = (tags or []) + ["my_custom_tag"] native.cc_library( name = name, visibility = visibility, tags = my_tags, **kwargs ) my_cc_library = macro( implementation = _my_cc_library_impl, inherit_attrs = native.cc_library, attrs = { "cxxopts": None, "copts": attr.string_list(default = ["-D_FOO"]), }, )` If `inherit_attrs` is set, the macro's implementation function *must* have a `**kwargs` residual keyword parameter. By convention, a macro should pass inherited, non-overridden attributes unchanged to the "main" rule or macro symbol which the macro is wrapping. Typically, most inherited attributes will not have a parameter in the implementation function's parameter list, and will simply be passed via `**kwargs`. It can be convenient for the implementation function to have explicit parameters for some inherited attributes (most commonly, `tags` and `testonly`) if the macro needs to pass those attributes to both "main" and non-"main" targets – but if the macro also needs to examine or manipulate those attributes, you must take care to handle the `None` default value of non-mandatory inherited attributes. |
| `finalizer` | [bool](../core/bool); default is `False` Whether this macro is a rule finalizer, which is a macro that, regardless of its position in a `BUILD` file, is evaluated at the end of package loading, after all non-finalizer targets have been defined. Unlike ordinary symbolic macros, rule finalizers may call [`native.existing_rule()`](../toplevel/native#existing_rule) and [`native.existing_rules()`](../toplevel/native#existing_rules) to query the set of *non-finalizer* rule targets defined in the current package. Note that `native.existing_rule()` and `native.existing_rules()` cannot access the targets defined by any rule finalizer, including this one. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the macro that can be extracted by documentation generating tools. |
## materializer\_rule
```
callable materializer_rule(*, implementation, attrs={}, doc=None, allow_real_deps=False)
```
Creates a new materializer rule, which can be called from a BUILD file or a macro to create materializer targets.
Materializer targets are used to dynamically select dependencies at analysis time. Targets which depend on a materializer target will see the materialized dependencies, rather than the materializer target itself.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | [function](../core/function); required The Starlark function implementing this materializer rule. It must have exactly one parameter: [ctx](../builtins/ctx). This function is called during the analysis phase for each instance of the rule. Materializer rules return exactly one and only one MaterializedDepsInfo provider which specifies the dependencies to materialize in place of any instance of this rule in the attributes of another target. |
| `attrs` | [dict](../core/dict); default is `{}` A dictionary to declare all the attributes of the rule. It maps from an attribute name to an attribute object (see [`attr`](../toplevel/attr) module). Attributes starting with `_` are private, and can be used to add an implicit dependency on a label. The attribute `name` is implicitly added and must not be specified. Attributes `visibility`, `deprecation`, `tags`, `testonly`, and `features` are implicitly added and cannot be overridden. Most rules need only a handful of attributes. To limit memory usage, there is a cap on the number of attributes that may be declared. Declared attributes will convert `None` to the default value. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the rule that can be extracted by documentation generating tools. |
| `allow_real_deps` | [bool](../core/bool); default is `False` Whether to allow instances of this materializer rule to have real dependencies (non-dormant deps / non-for\_dependency\_resolution). Subject to allowlist. |
## module\_extension
```
unknown module_extension(implementation, *, tag_classes={}, doc=None, environ=[], os_dependent=False, arch_dependent=False, facts_version=0)
```
Creates a new module extension. Store it in a global value, so that it can be exported and used in a MODULE.bazel file with `use_extension`.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | callable; required The function that implements this module extension. Must take a single parameter, `module_ctx`. The function is called once at the beginning of a build to determine the set of available repos. |
| `tag_classes` | [dict](../core/dict); default is `{}` A dictionary to declare all the tag classes used by the extension. It maps from the name of the tag class to a `tag_class` object. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the module extension that can be extracted by documentation generating tools. |
| `environ` | [sequence](../core/list) of [string](../core/string)s; default is `[]` **Deprecated**. This parameter has been deprecated. Migrate to `module_ctx.getenv` instead. Provides a list of environment variable that this module extension depends on. If an environment variable in that list changes, the extension will be re-evaluated. See also `--experimental_strict_repo_env`. |
| `os_dependent` | [bool](../core/bool); default is `False` Indicates whether this extension is OS-dependent or not |
| `arch_dependent` | [bool](../core/bool); default is `False` Indicates whether this extension is architecture-dependent or not |
| `facts_version` | [int](../core/int); default is `0` The schema version of the `facts` dict returned by this extension's implementation function via `extension_metadata`. The version is persisted in the lockfile alongside the facts and compared against the current value before the extension runs: if they differ, the persisted facts are discarded and the extension is invoked with an empty `module_ctx.facts`. Increment this value whenever the extension changes the schema of the facts in a backwards-incompatible way so that older facts are not interpreted with the new schema. |
## provider
```
unknown provider(doc=None, *, fields=None, init=None)
```
Defines a provider symbol. The resulting value of this function must be stored in a global value to be usable in a rule or aspect implementation. Providers can be instantiated by calling the resulting value as a function, or used directly as an index key for retrieving an instance of that provider from a target. Example:
```
MyInfo = provider()
...
def _my_library_impl(ctx):
...
my_info = MyInfo(x = 2, y = 3)
# my_info.x == 2
# my_info.y == 3
...
```
See [Rules (Providers)](https://bazel.build/extending/rules#providers) for a comprehensive guide on how to use providers.
Returns a [`Provider`](../builtins/Provider) callable value if `init` is not specified.
If `init` is specified, returns a tuple of 2 elements: a [`Provider`](../builtins/Provider) callable value and a *raw constructor* callable value. See [Rules (Custom initialization of custom providers)](https://bazel.build/extending/rules#custom_initialization_of_providers) and the discussion of the `init` parameter below for details.
### Parameters
| Parameter | Description |
| - | - |
| `doc` | [string](../core/string); or `None`; default is `None` |
| `fields` | [sequence](../core/list.html) of [string](../core/string.html)s; or [dict](../core/dict.html); or `None`; default is `None` If specified, restricts the set of allowed fields. Possible values are:
list of fields: `provider(fields = ['a', 'b'])`
dictionary field name -> documentation: `provider( fields = { 'a' : 'Documentation for a', 'b' : 'Documentation for b' })`
All fields are optional.It is *strongly recommended* to specify this parameter, as defining a field schema allows Bazel to store provider instances more compactly. |
| `init` | callable; or `None`; default is `None` An optional callback for preprocessing and validating the provider's field values during instantiation. If `init` is specified, `provider()` returns a tuple of 2 elements: the normal provider symbol and a *raw constructor*.A precise description follows; see [Rules (Custom initialization of providers)](https://bazel.build/extending/rules#custom_initialization_of_providers) for an intuitive discussion and use cases.Let `P` be the provider symbol created by calling `provider()`. Conceptually, an instance of `P` is generated by calling a default constructor function `c(*args, **kwargs)`, which does the following:
If `args` is non-empty, an error occurs.
If the `fields` parameter was specified when `provider()` was called, and if `kwargs` contains any key that was not listed in `fields`, an error occurs.
Otherwise, `c` returns a new instance that has, for each `k: v` entry in `kwargs`, a field named `k` with value `v`.
In the case where an `init` callback is *not* given, a call to the symbol `P` itself acts as a call to the default constructor function `c`; in other words, `P(*args, **kwargs)` returns `c(*args, **kwargs)`. For example,`MyInfo = provider() m = MyInfo(foo = 1)`will straightforwardly make it so that `m` is a `MyInfo` instance with `m.foo == 1`.But in the case where `init` is specified, the call `P(*args, **kwargs)` will perform the following steps instead:
The callback is invoked as `init(*args, **kwargs)`, that is, with the exact same positional and keyword arguments as were passed to `P`.
The return value of `init` is expected to be a dictionary, `d`, whose keys are field name strings. If it is not, an error occurs.
A new instance of `P` is generated as if by calling the default constructor with `d`'s entries as keyword arguments, as in `c(**d)`.
NB: the above steps imply that an error occurs if `*args` or `**kwargs` does not match `init`'s signature, or the evaluation of `init`'s body fails (perhaps intentionally via a call to [`fail()`](../globals/all.html#fail)), or if the return value of `init` is not a dictionary with the expected schema.In this way, the `init` callback generalizes normal provider construction by allowing positional arguments and arbitrary logic for preprocessing and validation. It does *not* enable circumventing the list of allowed `fields`.When `init` is specified, the return value of `provider()` becomes a tuple `(P, r)`, where `r` is the *raw constructor*. In fact, the behavior of `r` is exactly that of the default constructor function `c` discussed above. Typically, `r` is bound to a variable whose name is prefixed with an underscore, so that only the current .bzl file has direct access to it:`MyInfo, _new_myinfo = provider(init = ...)` |
## repository\_rule
```
callable repository_rule(implementation, *, attrs=None, local=False, environ=[], configure=False, remotable=False, doc=None)
```
Creates a new repository rule. Store it in a global value, so that it can be loaded and called from a [`module_extension()`](#module_extension) implementation function, or used by [`use_repo_rule()`](../globals/module#use_repo_rule).
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | callable; required |
| `attrs` | [dict](../core/dict); or `None`; default is `None` |
| `local` | [bool](../core/bool); default is `False` Indicate that this rule fetches everything from the local system and should be reevaluated at every fetch. |
| `environ` | [sequence](../core/list) of [string](../core/string)s; default is `[]` **Deprecated**. This parameter has been deprecated. Migrate to `repository_ctx.getenv` instead. Provides a list of environment variable that this repository rule depends on. If an environment variable in that list change, the repository will be refetched. See also `--experimental_strict_repo_env`. |
| `configure` | [bool](../core/bool); default is `False` Indicate that the repository inspects the system for configuration purpose |
| `remotable` | [bool](../core/bool); default is `False` **Experimental**. This parameter is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--experimental_repo_remote_exec` Compatible with remote execution |
| `doc` | [string](../core/string); or `None`; default is `None` |
## rule
```
callable rule(implementation, *, test=unbound, attrs={}, outputs=None, executable=unbound, output_to_genfiles=False, fragments=[], host_fragments=[], _skylark_testable=False, toolchains=[], doc=None, provides=[], dependency_resolution_rule=False, exec_compatible_with=[], analysis_test=False, build_setting=None, cfg=None, exec_groups=None, initializer=None, parent=None, extendable=None, subrules=[])
```
Creates a new rule, which can be called from a BUILD file or a macro to create targets.
Rules must be assigned to global variables in a .bzl file; the name of the global variable is the rule's name.
Test rules are required to have a name ending in `_test`, while all other rules must not have this suffix. (This restriction applies only to rules, not to their targets.)
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | [function](../core/function); required the Starlark function implementing this rule, must have exactly one parameter: [ctx](../builtins/ctx). The function is called during the analysis phase for each instance of the rule. It can access the attributes provided by the user. It must create actions to generate all the declared outputs. |
| `test` | [bool](../core/bool); default is `unbound` Whether this rule is a test rule, that is, whether it may be the subject of a `bazel test` command. All test rules are automatically considered [executable](#rule.executable); it is unnecessary (and discouraged) to explicitly set `executable = True` for a test rule. The value defaults to `False`. See the [Rules page](https://bazel.build/extending/rules#executable_rules_and_test_rules) for more information. |
| `attrs` | [dict](../core/dict); default is `{}` A dictionary to declare all the attributes of the rule. It maps from an attribute name to an attribute object (see [`attr`](../toplevel/attr) module). Attributes starting with `_` are private, and can be used to add an implicit dependency on a label. The attribute `name` is implicitly added and must not be specified. Attributes `visibility`, `deprecation`, `tags`, `testonly`, and `features` are implicitly added and cannot be overridden. Most rules need only a handful of attributes. To limit memory usage, there is a cap on the number of attributes that may be declared. Declared attributes will convert `None` to the default value. |
| `outputs` | [dict](../core/dict.html); or `None`; or [function](../core/function.html); default is `None` **Deprecated**. This parameter is deprecated and will be removed soon. Please do not depend on it. It is *disabled* with `--incompatible_no_rule_outputs_param`. Use this flag to verify your code is compatible with its imminent removal. This parameter has been deprecated. Migrate rules to use `OutputGroupInfo` or `attr.output` instead. A schema for defining predeclared outputs. Unlike [`output`](../toplevel/attr.html#output) and [`output_list`](../toplevel/attr.html#output_list) attributes, the user does not specify the labels for these files. See the [Rules page](https://bazel.build/extending/rules#files) for more on predeclared outputs.The value of this argument is either a dictionary or a callback function that produces a dictionary. The callback works similar to computed dependency attributes: The function's parameter names are matched against the rule's attributes, so for example if you pass `outputs = _my_func` with the definition `def _my_func(srcs, deps): ...`, the function has access to the attributes `srcs` and `deps`. Whether the dictionary is specified directly or via a function, it is interpreted as follows.Each entry in the dictionary creates a predeclared output where the key is an identifier and the value is a string template that determines the output's label. In the rule's implementation function, the identifier becomes the field name used to access the output's [`File`](../builtins/File.html) in [`ctx.outputs`](../builtins/ctx.html#outputs). The output's label has the same package as the rule, and the part after the package is produced by substituting each placeholder of the form `"%{ATTR}"` with a string formed from the value of the attribute `ATTR`:
String-typed attributes are substituted verbatim.
Label-typed attributes become the part of the label after the package, minus the file extension. For example, the label `"//pkg:a/b.c"` becomes `"a/b"`.
Output-typed attributes become the part of the label after the package, including the file extension (for the above example, `"a/b.c"`).
All list-typed attributes (for example, `attr.label_list`) used in placeholders are required to have *exactly one element*. Their conversion is the same as their non-list version (`attr.label`).
Other attribute types may not appear in placeholders.
The special non-attribute placeholders `%{dirname}` and `%{basename}` expand to those parts of the rule's label, excluding its package. For example, in `"//pkg:a/b.c"`, the dirname is `a` and the basename is `b.c`.
In practice, the most common substitution placeholder is `"%{name}"`. For example, for a target named "foo", the outputs dict `{"bin": "%{name}.exe"}` predeclares an output named `foo.exe` that is accessible in the implementation function as `ctx.outputs.bin`. |
| `executable` | [bool](../core/bool); default is `unbound` |
| `output_to_genfiles` | [bool](../core/bool); default is `False` If true, the files will be generated in the genfiles directory instead of the bin directory. Unless you need it for compatibility with existing rules (e.g. when generating header files for C++), do not set this flag. |
| `fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of names of configuration fragments that the rule requires in target configuration. |
| `host_fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of names of configuration fragments that the rule requires in host configuration. |
| `_skylark_testable` | [bool](../core/bool); default is `False` *(Experimental)* If true, this rule will expose its actions for inspection by rules that depend on it via an `Actions` provider. The provider is also available to the rule itself by calling [ctx.created\_actions()](../builtins/ctx#created_actions). This should only be used for testing the analysis-time behavior of Starlark rules. This flag may be removed in the future. |
| `toolchains` | [sequence](../core/list); default is `[]` If set, the set of toolchains this rule requires. The list can contain String, Label, or StarlarkToolchainTypeApi objects, in any combination. Toolchains will be found by checking the current platform, and provided to the rule implementation via `ctx.toolchain`. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the rule that can be extracted by documentation generating tools. |
| `provides` | [sequence](../core/list); default is `[]` A list of providers that the implementation function must return. It is an error if the implementation function omits any of the types of providers listed here from its return value. However, the implementation function may return additional providers not listed here. Each element of the list is an `*Info` object returned by [`provider()`](../globals/bzl#provider). When a target of the rule is used as a dependency for a target that declares a required provider, it is not necessary to specify that provider here. It is enough that the implementation function returns it. However, it is considered best practice to specify it, even though this is not required. The [`required_providers`](../globals/bzl#aspect.required_providers) field of an [aspect](../globals/bzl#aspect) does, however, require that providers are specified here. |
| `dependency_resolution_rule` | [bool](../core/bool); default is `False` If set, the rule can be a dependency through attributes also marked as available in materializers. Every attribute of rules with this flag set must be marked as available in materializers also. This is so that rules so marked cannot depend on rules that are not so marked. |
| `exec_compatible_with` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A list of constraints on the execution platform that apply to all targets of this rule type. |
| `analysis_test` | [bool](../core/bool.html); default is `False` If true, then this rule is treated as an analysis test. Note: Analysis test rules are primarily defined using infrastructure provided in core Starlark libraries. See [Testing](https://bazel.build/rules/testing#testing-rules) for guidance. If a rule is defined as an analysis test rule, it becomes allowed to use configuration transitions defined using [analysis\_test\_transition](#analysis_test_transition) on its attributes, but opts into some restrictions:
Targets of this rule are limited in the number of transitive dependencies they may have.
The rule is considered a test rule (as if `test=True` were set). This supersedes the value of `test`
The rule implementation function may not register actions. Instead, it must register a pass/fail result via providing [AnalysisTestResultInfo](../providers/AnalysisTestResultInfo.html).
|
| `build_setting` | [BuildSetting](../builtins/BuildSetting); or `None`; default is `None` If set, describes what kind of [`build setting`](/rules/config#user-defined-build-settings) this rule is. See the [`config`](../toplevel/config) module. If this is set, a mandatory attribute named "build\_setting\_default" is automatically added to this rule, with a type corresponding to the value passed in here. |
| `cfg` | default is `None` If set, points to the configuration transition the rule will apply to its own configuration before analysis. |
| `exec_groups` | [dict](../core/dict); or `None`; default is `None` Dict of execution group name (string) to [`exec_group`s](../globals/bzl#exec_group). If set, allows rules to run actions on multiple execution platforms within a single target. See [execution groups documentation](/reference/exec-groups) for more info. |
| `initializer` | default is `None` Experimental: the Stalark function initializing the attributes of the rule. The function is called at load time for each instance of the rule. It's called with `name` and the values of public attributes defined by the rule (not with generic attributes, for example `tags`). It has to return a dictionary from the attribute names to the desired values. The attributes that are not returned are unaffected. Returning `None` as value results in using the default value specified in the attribute definition. Initializers are evaluated before the default values specified in an attribute definition. Consequently, if a parameter in the initializer's signature contains a default values, it overwrites the default from the attribute definition (except if returning `None`). Similarly, if a parameter in the initializer's signature doesn't have a default, the parameter will become mandatory. It's a good practice to omit default/mandatory settings on an attribute definition in such cases. It's a good practice to use `**kwargs` for attributes that are not handled. In case of extended rules, all initializers are called proceeding from child to ancestors. Each initializer is passed only the public attributes it knows about. |
| `parent` | default is `None` Experimental: the Stalark rule that is extended. When set the public attributes are merged as well as advertised providers. The rule matches `executable` and `test` from the parent. Values of `fragments`, `toolchains`, `exec_compatible_with`, and `exec_groups` are merged. Legacy or deprecated parameters may not be set. Incoming configuration transition `cfg` of parent is applied after this rule's incoming configuration. |
| `extendable` | [bool](../core/bool); or [Label](../builtins/Label); or [string](../core/string); or `None`; default is `None` Experimental: A label of an allowlist defining which rules can extending this rule. It can be set also to True/False to always allow/disallow extending. Bazel defaults to always allowing extensions. |
| `subrules` | [sequence](../core/list) of [Subrule](../builtins/Subrule)s; default is `[]` Experimental: List of subrules used by this rule. |
## select
```
select select(x, no_match_error='')
```
`select()` is the helper function that makes a rule attribute [configurable](/reference/be/common-definitions#configurable-attributes). See [build encyclopedia](/reference/be/functions#select) for details.
### Parameters
| Parameter | Description |
| - | - |
| `x` | [dict](../core/dict); required A dict that maps configuration conditions to values. Each key is a [Label](../builtins/Label) or a label string that identifies a config\_setting or constraint\_value instance. See the [documentation on macros](https://bazel.build/extending/legacy-macros#label-resolution) for when to use a Label instead of a string. If `--incompatible_resolve_select_keys_eagerly` is enabled, the keys are resolved to `Label` objects relative to the package of the file that contains this call to `select`. |
| `no_match_error` | [string](../core/string); default is `''` Optional custom error to report if no condition matches. |
## subrule
```
Subrule subrule(*, implementation, attrs={}, toolchains=[], fragments=[], subrules=[])
```
Constructs a new instance of a subrule. The result of this function must be stored in a global variable before it can be used.
### Parameters
| Parameter | Description |
| - | - |
| `implementation` | [function](../core/function); required The Starlark function implementing this subrule |
| `attrs` | [dict](../core/dict.html); default is `{}` A dictionary to declare all the (private) attributes of the subrule. Subrules may only have private attributes that are label-typed (i.e. label or label-list). The resolved values corresponding to these labels are automatically passed by Bazel to the subrule's implementation function as named arguments (thus the implementation function is required to accept named parameters matching the attribute names). The types of these values will be:
`FilesToRunProvider` for label attributes with `executable=True`
`File` for label attributes with `allow_single_file=True`
`Target` for all other label attributes
`[Target]` for all label-list attributes
|
| `toolchains` | [sequence](../core/list); default is `[]` If set, the set of toolchains this subrule requires. The list can contain String, Label, or StarlarkToolchainTypeApi objects, in any combination. Toolchains will be found by checking the current platform, and provided to the subrule implementation via `ctx.toolchains`. Note that AEGs need to be enabled on the consuming rule(s) if this parameter is set. In case you haven't migrated to AEGs yet, see [https://bazel.build/extending/auto-exec-groups#migration-aegs](https://bazel.build/extending/auto-exec-groups#migration-aegs). |
| `fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of names of configuration fragments that the subrule requires in target configuration. |
| `subrules` | [sequence](../core/list) of [Subrule](../builtins/Subrule)s; default is `[]` List of other subrules needed by this subrule. |
## tag\_class
```
tag_class tag_class(attrs={}, *, doc=None)
```
Creates a new tag\_class object, which defines an attribute schema for a class of tags, which are data objects usable by a module extension.
### Parameters
| Parameter | Description |
| - | - |
| `attrs` | [dict](../core/dict); default is `{}` A dictionary to declare all the attributes of this tag class. It maps from an attribute name to an attribute object (see [attr](../toplevel/attr) module). Note that unlike [`rule()`](../globals/bzl#rule), [`aspect()`](../globals/bzl#aspect) and [`repository_rule()`](../globals/bzl#repository_rule), declared attributes will not convert `None` to the default value. For the default to be used, the attribute must be omitted entirely by the caller. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the tag class that can be extracted by documentation generating tools. |
## visibility
```
None visibility(value)
```
Sets the load visibility of the .bzl module currently being initialized.
The load visibility of a module governs whether or not other BUILD and .bzl files may load it. (This is distinct from the target visibility of the underlying .bzl source file, which governs whether the file may appear as a dependency of other targets.) Load visibility works at the level of packages: To load a module the file doing the loading must live in a package that has been granted visibility to the module. A module can always be loaded within its own package, regardless of its visibility.
`visibility()` may only be called once per .bzl file, and only at the top level, not inside a function. The preferred style is to put this call immediately below the `load()` statements and any brief logic needed to determine the argument.
If the flag `--check_bzl_visibility` is set to false, load visibility violations will emit warnings but not fail the build.
### Parameters
| Parameter | Description |
| - | - |
| `value` | required A list of package specification strings, or a single package specification string.Package specifications follow the same format as for `package_group`, except that negative package specifications are not permitted. That is, a specification may have the forms:
`"//foo"`: the package `//foo`
`"//foo/..."`: the package `//foo` and all of its subpackages.
`"public"` or `"private"`: all packages or no packages, respectively
The "@" syntax is not allowed; all specifications are interpreted relative to the current module's repository.If `value` is a list of strings, the set of packages granted visibility to this module is the union of the packages represented by each specification. (An empty list has the same effect as `private`.) If `value` is a single string, it is treated as if it were the singleton list `[value]`.Note that the flags `--incompatible_package_group_has_public_syntax` and `--incompatible_fix_package_group_reporoot_syntax` have no effect on this argument. The `"public"` and `"private"` values are always available, and `"//..."` is always interpreted as "all packages in the current repository". |
# MODULE.bazel files
Source: https://bazel.build/rules/lib/globals/module
Methods available in MODULE.bazel files.
## Members
* [archive\_override](#archive_override)
* [bazel\_dep](#bazel_dep)
* [flag\_alias](#flag_alias)
* [git\_override](#git_override)
* [include](#include)
* [inject\_repo](#inject_repo)
* [local\_path\_override](#local_path_override)
* [module](#module)
* [multiple\_version\_override](#multiple_version_override)
* [override\_repo](#override_repo)
* [register\_execution\_platforms](#register_execution_platforms)
* [register\_toolchains](#register_toolchains)
* [single\_version\_override](#single_version_override)
* [use\_extension](#use_extension)
* [use\_repo](#use_repo)
* [use\_repo\_rule](#use_repo_rule)
## archive\_override
```
None archive_override(*, module_name, **kwargs)
```
Specifies that this dependency should come from an archive file (zip, gzip, etc) at a
certain location, instead of from a registry. Effectively, this dependency will be
backed by an [`http_archive`](../repo/http#http_archive) rule.
This directive only takes effect in the root module; in other words, if a module is
used as a dependency by others, its own overrides are ignored.
### Parameters
| Parameter | Description |
| - | - |
| `module_name` | [string](../core/string); required The name of the Bazel module dependency to apply this override to. |
| `kwargs` | required All other arguments are forwarded to the underlying `http_archive` repo rule. Note that the `name` attribute shouldn't be specified; use `module_name` instead. |
## bazel\_dep
```
None bazel_dep(*, name, version='', max_compatibility_level=-1, repo_name='', dev_dependency=False)
```
Declares a direct dependency on another Bazel module.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required The name of the module to be added as a direct dependency. |
| `version` | [string](../core/string); default is `''` The version of the module to be added as a direct dependency. |
| `max_compatibility_level` | [int](../core/int); default is `-1` Deprecated. This is now a no-op and has no effect. |
| `repo_name` | [string](../core/string); or `None`; default is `''` The name of the external repo representing this dependency. This is by default the name of the module. Can be set to `None` to make this dependency a "*nodep*" dependency: in this case, this `bazel_dep` specification is only honored if the target module already exists in the dependency graph by some other means. |
| `dev_dependency` | [bool](../core/bool); default is `False` If true, this dependency will be ignored if the current module is not the root module or `--ignore_dev_dependency` is enabled. |
## flag\_alias
```
None flag_alias(*, name, starlark_flag)
```
Maps a command-line flag `--foo` to a Starlark flag `--@repo//defs:foo`.
Bazel translates all instances of `bazel build //target --foo`
to `bazel build //target --@repo//defs:foo`.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required The name of the flag. |
| `starlark_flag` | [string](../core/string); required The label of the Starlark flag to alias to. |
## git\_override
```
None git_override(*, module_name, **kwargs)
```
Specifies that this dependency should come from a certain commit in a Git repository,
instead of from a registry. Effectively, this dependency will be backed by a
[`git_repository`](../repo/git#git_repository) rule.
This directive only takes effect in the root module; in other words, if a module is
used as a dependency by others, its own overrides are ignored.
### Parameters
| Parameter | Description |
| - | - |
| `module_name` | [string](../core/string); required The name of the Bazel module dependency to apply this override to. |
| `kwargs` | required All other arguments are forwarded to the underlying `git_repository` repo rule. Note that the `name` attribute shouldn't be specified; use `module_name` instead. |
## include
```
None include(label, *, dev_dependency=False)
```
Includes the contents of another MODULE.bazel-like file. Effectively, `include()` behaves as if the included file is textually placed at the location of the `include()` call, except that variable bindings (such as those used for `use_extension`) are only ever visible in the file they occur in, not in any included or including files.
Only the root module and modules subject to a non-registry override may use `include()`.
Only files in the current module's repo may be included.
`include()` allows you to segment a module file into multiple parts, to avoid having an enormous MODULE.bazel file or to better manage access control for individual semantic segments.
### Parameters
| Parameter | Description |
| - | - |
| `label` | [string](../core/string); required The label pointing to the file to include. The label must point to a file in the main repo; in other words, it **must **start with double slashes (`//`). The name of the file must end with `.MODULE.bazel` and must not start with `.`.**** |
| `dev_dependency` | [bool](../core/bool); default is `False` If true, this include will be ignored if the current module is not the root module or `--ignore_dev_dependency` is enabled. The value must be a literal `True` or `False`. |
## inject\_repo
```
None inject_repo(extension_proxy, *args, **kwargs)
```
Injects one or more new repos into the given module extension.
This is ignored if the current module is not the root module or
`--ignore_dev_dependency` is enabled.
Use [`override_repo`](#override_repo) instead to override an
existing repo.
### Parameters
| Parameter | Description |
| - | - |
| `extension_proxy` | module\_extension\_proxy; required A module extension proxy object returned by a `use_extension` call. |
| `args` | required The repos visible to the current module that should be injected into the extension under the same name. |
| `kwargs` | required The new repos to inject into the extension, where the values are the names of repos in the scope of the current module and the keys are the name they will be visible under in the extension. Keys that are not valid identifiers can be specified via a literal dict passed as extra keyword arguments, e.g., `inject_repo(extension_proxy, **{"foo.2": "foo"})`. |
## local\_path\_override
```
None local_path_override(*, module_name, path)
```
Specifies that this dependency should come from a certain directory on local disk,
instead of from a registry. Effectively, this dependency will be backed by a
[`local_repository`](../repo/local#local_repository) rule.
This directive only takes effect in the root module; in other words, if a module is
used as a dependency by others, its own overrides are ignored.
### Parameters
| Parameter | Description |
| - | - |
| `module_name` | [string](../core/string); required The name of the Bazel module dependency to apply this override to. |
| `path` | [string](../core/string); required The path to the directory where this module is. |
## module
```
None module(*, name='', version='', compatibility_level=-1, repo_name='', bazel_compatibility=[])
```
Declares certain properties of the Bazel module represented by the current Bazel repo. These properties are either essential metadata of the module (such as the name and version), or affect behavior of the current module and its dependents.
It should be called at most once, and if called, it must be the very first directive in the MODULE.bazel file. It can be omitted only if this module is the root module (as in, if it's not going to be depended on by another module).
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); default is `''` The name of the module. Can be omitted only if this module is the root module (as in, if it's not going to be depended on by another module). A valid module name must: 1) only contain lowercase letters (a-z), digits (0-9), dots (.), hyphens (-), and underscores (\_); 2) begin with a lowercase letter; 3) end with a lowercase letter or digit. |
| `version` | [string](../core/string); default is `''` The version of the module. Can be omitted only if this module is the root module (as in, if it's not going to be depended on by another module). The version must be in a relaxed SemVer format; see [the documentation](/external/module#version_format) for more details. |
| `compatibility_level` | [int](../core/int); default is `-1` Deprecated. This is now a no-op and has no effect. |
| `repo_name` | [string](../core/string); default is `''` The name of the repository representing this module, as seen by the module itself. By default, the name of the repo is the name of the module. This can be specified to ease migration for projects that have been using a repo name for itself that differs from its module name. |
| `bazel_compatibility` | Iterable of [string](../core/string)s; default is `[]` A list of bazel versions that allows users to declare which Bazel versions are compatible with this module. It does NOT affect dependency resolution, but bzlmod will use this information to check if your current Bazel version is compatible. The format of this value is a string of some constraint values separated by comma. Three constraints are supported: \<=X.X.X: The Bazel version must be equal or older than X.X.X. Used when there is a known incompatible change in a newer version. >=X.X.X: The Bazel version must be equal or newer than X.X.X.Used when you depend on some features that are only available since X.X.X. -X.X.X: The Bazel version X.X.X is not compatible. Used when there is a bug in X.X.X that breaks you, but fixed in later versions. |
## multiple\_version\_override
```
None multiple_version_override(*, module_name, versions, registry='')
```
Specifies that a dependency should still come from a registry, but multiple versions of it should be allowed to coexist. See [the documentation](/external/module#multiple-version_override) for more details. This directive only takes effect in the root module; in other words, if a module is used as a dependency by others, its own overrides are ignored.
### Parameters
| Parameter | Description |
| - | - |
| `module_name` | [string](../core/string); required The name of the Bazel module dependency to apply this override to. |
| `versions` | Iterable of [string](../core/string)s; required Explicitly specifies the versions allowed to coexist. These versions must already be present in the dependency graph pre-selection. Dependencies on this module will be "upgraded" to the nearest higher allowed version at the same compatibility level, whereas dependencies that have a higher version than any allowed versions at the same compatibility level will cause an error. |
| `registry` | [string](../core/string); default is `''` Overrides the registry for this module; instead of finding this module from the default list of registries, the given registry should be used. |
## override\_repo
```
None override_repo(extension_proxy, *args, **kwargs)
```
Overrides one or more repos defined by the given module extension with the given repos
visible to the current module. This is ignored if the current module is not the root
module or `--ignore_dev_dependency` is enabled.
A repository may be overridden with the root module itself. In that case, the root
module must refer to itself by its own repository name instead of importing the
overridden repository with `use_repo`. Other modules may still import it.
Use [`inject_repo`](#inject_repo) instead to add a new repo.
### Parameters
| Parameter | Description |
| - | - |
| `extension_proxy` | module\_extension\_proxy; required A module extension proxy object returned by a `use_extension` call. |
| `args` | required The repos in the extension that should be overridden with the repos of the same name in the current module. |
| `kwargs` | required The overrides to apply to the repos generated by the extension, where the values are the names of repos in the scope of the current module and the keys are the names of the repos they will override in the extension. Keys that are not valid identifiers can be specified via a literal dict passed as extra keyword arguments, e.g., `override_repo(extension_proxy, **{"foo.2": "foo"})`. |
## register\_execution\_platforms
```
None register_execution_platforms(*platform_labels, dev_dependency=False)
```
Specifies already-defined execution platforms to be registered when this module is selected. Should be absolute [target patterns](https://bazel.build/reference/glossary#target-pattern) (ie. beginning with either `@` or `//`). See [toolchain resolution](/docs/toolchains) for more information. Patterns that expand to multiple targets, such as `:all`, will be registered in lexicographical order by name.
### Parameters
| Parameter | Description |
| - | - |
| `dev_dependency` | [bool](../core/bool); default is `False` If true, the execution platforms will not be registered if the current module is not the root module or `--ignore_dev_dependency` is enabled. |
| `platform_labels` | [sequence](../core/list) of [string](../core/string)s; required The target patterns to register. |
## register\_toolchains
```
None register_toolchains(*toolchain_labels, dev_dependency=False)
```
Specifies already-defined toolchains to be registered when this module is selected. Should be absolute [target patterns](https://bazel.build/reference/glossary#target-pattern) (ie. beginning with either `@` or `//`). See [toolchain resolution](/docs/toolchains) for more information. Patterns that expand to multiple targets, such as `:all`, will be registered in lexicographical order by target name (not the name of the toolchain implementation).
### Parameters
| Parameter | Description |
| - | - |
| `dev_dependency` | [bool](../core/bool); default is `False` If true, the toolchains will not be registered if the current module is not the root module or `--ignore_dev_dependency` is enabled. |
| `toolchain_labels` | [sequence](../core/list) of [string](../core/string)s; required The target patterns to register. |
## single\_version\_override
```
None single_version_override(*, module_name, version='', registry='', patches=[], patch_cmds=[], patch_strip=0)
```
Specifies that a dependency should still come from a registry, but its version should be pinned, or its registry overridden, or a list of patches applied. This directive only takes effect in the root module; in other words, if a module is used as a dependency by others, its own overrides are ignored.
### Parameters
| Parameter | Description |
| - | - |
| `module_name` | [string](../core/string); required The name of the Bazel module dependency to apply this override to. |
| `version` | [string](../core/string); default is `''` Overrides the declared version of this module in the dependency graph. In other words, this module will be "pinned" to this override version. This attribute can be omitted if all one wants to override is the registry or the patches. |
| `registry` | [string](../core/string); default is `''` Overrides the registry for this module; instead of finding this module from the default list of registries, the given registry should be used. |
| `patches` | Iterable of [string](../core/string)s; default is `[]` A list of labels pointing to patch files to apply for this module. The patch files must exist in the source tree of the top level project. They are applied in the list order. If a patch makes changes to the MODULE.bazel file, these changes will only be effective if the patch file is provided by the root module. |
| `patch_cmds` | Iterable of [string](../core/string)s; default is `[]` Sequence of Bash commands to be applied on Linux/Macos after patches are applied. Changes to the MODULE.bazel file will not be effective. |
| `patch_strip` | [int](../core/int); default is `0` Same as the --strip argument of Unix patch. |
## use\_extension
```
module_extension_proxy use_extension(extension_bzl_file, extension_name, *, dev_dependency=False, isolate=False)
```
Returns a proxy object representing a module extension; its methods can be invoked to create module extension tags.
### Parameters
| Parameter | Description |
| - | - |
| `extension_bzl_file` | [string](../core/string); required A label to the Starlark file defining the module extension. |
| `extension_name` | [string](../core/string); required The name of the module extension to use. A symbol with this name must be exported by the Starlark file. |
| `dev_dependency` | [bool](../core/bool); default is `False` If true, this usage of the module extension will be ignored if the current module is not the root module or `--ignore_dev_dependency` is enabled. |
| `isolate` | [bool](../core/bool); default is `False` **Experimental**. This parameter is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--experimental_isolated_extension_usages` If true, this usage of the module extension will be isolated from all other usages, both in this and other modules. Tags created for this usage do not affect other usages and the repositories generated by the extension for this usage will be distinct from all other repositories generated by the extension. This parameter is currently experimental and only available with the flag `--experimental_isolated_extension_usages`. |
## use\_repo
```
None use_repo(extension_proxy, *args, **kwargs)
```
Imports one or more repos generated by the given module extension into the scope of the current module.
### Parameters
| Parameter | Description |
| - | - |
| `extension_proxy` | module\_extension\_proxy; required |
| `args` | required The names of the repos to import. |
| `kwargs` | required Specifies certain repos to import into the scope of the current module with different names. The keys should be the name to use in the current scope, whereas the values should be the original names exported by the module extension. Keys that are not valid identifiers can be specified via a literal dict passed as extra keyword arguments, e.g., `use_repo(extension_proxy, **{"foo.2": "foo"})`. |
## use\_repo\_rule
```
repo_rule_proxy use_repo_rule(repo_rule_bzl_file, repo_rule_name)
```
Returns a proxy value that can be directly invoked in the MODULE.bazel file as a repository rule, one or more times. Repos created in such a way are only visible to the current module, under the name declared using the `name` attribute on the proxy. The implicit Boolean `dev_dependency` attribute can also be used on the proxy to denote that a certain repo is only to be created when the current module is the root module.
### Parameters
| Parameter | Description |
| - | - |
| `repo_rule_bzl_file` | [string](../core/string); required A label to the Starlark file defining the repo rule. |
| `repo_rule_name` | [string](../core/string); required The name of the repo rule to use. A symbol with this name must be exported by the Starlark file. |
# REPO.bazel files
Source: https://bazel.build/rules/lib/globals/repo
Methods available in REPO.bazel files.
## Members
* [ignore\_directories](#ignore_directories)
* [repo](#repo)
## ignore\_directories
```
None ignore_directories(dirs)
```
The list of directories to ignore in this repository.
This function takes a list of strings and a directory is ignored if any of the given strings matches its repository-relative path according to the semantics of the `glob()` function. This function can be used to ignore directories that are implementation details of source control systems, output files of other build systems, etc.
### Parameters
| Parameter | Description |
| - | - |
| `dirs` | [sequence](../core/list) of [string](../core/string)s; required |
## repo
```
None repo(**kwargs)
```
Declares metadata that applies to every rule in the repository. It must be called at most once per REPO.bazel file. If called, it must be the first call in the REPO.bazel file.
### Parameters
| Parameter | Description |
| - | - |
| `kwargs` | required The `repo()` function accepts exactly the same arguments as the [`package()`](/reference/be/functions#package) function in BUILD files. |
# VENDOR.bazel files
Source: https://bazel.build/rules/lib/globals/vendor
Methods available in VENDOR.bazel files.
## Members
* [ignore](#ignore)
* [pin](#pin)
## ignore
```
None ignore(*args)
```
Ignore this repo from vendoring. Bazel will never vendor it or use the corresponding directory (if exists) while building in vendor mode.
### Parameters
| Parameter | Description |
| - | - |
| `args` | required The canonical repo names of the repos to ignore. |
## pin
```
None pin(*args)
```
Pin the contents of this repo under the vendor directory. Bazel will not update this repo while vendoring, and will use the vendored source as if there is a --override\_repository flag when building in vendor mode
### Parameters
| Parameter | Description |
| - | - |
| `args` | required The canonical repo names of the repos to pin. |
# Providers
Source: https://bazel.build/rules/lib/providers
This section lists providers available on built-in rules. See the [Rules page](https://bazel.build/extending/rules#providers) for more on providers. These symbols are available only in .bzl files.
* [AnalysisTestResultInfo](/rules/lib/providers/AnalysisTestResultInfo)
* [CcInfo](/rules/lib/providers/CcInfo)
* [CcToolchainConfigInfo](/rules/lib/providers/CcToolchainConfigInfo)
* [CcToolchainInfo](/rules/lib/providers/CcToolchainInfo)
* [ConstraintCollection](/rules/lib/providers/ConstraintCollection)
* [ConstraintSettingInfo](/rules/lib/providers/ConstraintSettingInfo)
* [ConstraintValueInfo](/rules/lib/providers/ConstraintValueInfo)
* [DebugPackageInfo](/rules/lib/providers/DebugPackageInfo)
* [DefaultInfo](/rules/lib/providers/DefaultInfo)
* [ExecutionInfo](/rules/lib/providers/ExecutionInfo)
* [FeatureFlagInfo](/rules/lib/providers/FeatureFlagInfo)
* [file\_provider](/rules/lib/providers/file_provider)
* [FilesToRunProvider](/rules/lib/providers/FilesToRunProvider)
* [IncompatiblePlatformProvider](/rules/lib/providers/IncompatiblePlatformProvider)
* [InstrumentedFilesInfo](/rules/lib/providers/InstrumentedFilesInfo)
* [java\_compilation\_info](/rules/lib/providers/java_compilation_info)
* [java\_output\_jars](/rules/lib/providers/java_output_jars)
* [JavaInfo](/rules/lib/providers/JavaInfo)
* [JavaPluginInfo](/rules/lib/providers/JavaPluginInfo)
* [JavaRuntimeInfo](/rules/lib/providers/JavaRuntimeInfo)
* [JavaToolchainInfo](/rules/lib/providers/JavaToolchainInfo)
* [MaterializedDepsInfo](/rules/lib/providers/MaterializedDepsInfo)
* [ObjcProvider](/rules/lib/providers/ObjcProvider)
* [OutputGroupInfo](/rules/lib/providers/OutputGroupInfo)
* [PackageSpecificationInfo](/rules/lib/providers/PackageSpecificationInfo)
* [PlatformInfo](/rules/lib/providers/PlatformInfo)
* [RunEnvironmentInfo](/rules/lib/providers/RunEnvironmentInfo)
* [TemplateVariableInfo](/rules/lib/providers/TemplateVariableInfo)
* [ToolchainInfo](/rules/lib/providers/ToolchainInfo)
* [ToolchainTypeInfo](/rules/lib/providers/ToolchainTypeInfo)
# AnalysisTestResultInfo
Source: https://bazel.build/rules/lib/providers/AnalysisTestResultInfo
Encapsulates the result of analyis-phase testing. Build targets which return an instance of this provider signal to the build system that it should generate a 'stub' test executable which generates the equivalent test result. Analysis test rules (rules created with `analysis_test=True` **must** return an instance of this provider, and non-analysis-phase test rules **cannot** return this provider.
## Members
* [AnalysisTestResultInfo](#AnalysisTestResultInfo)
* [message](#message)
* [success](#success)
## AnalysisTestResultInfo
```
AnalysisTestResultInfo AnalysisTestResultInfo(success, message)
```
The `AnalysisTestResultInfo` constructor.
### Parameters
| Parameter | Description |
| - | - |
| `success` | [bool](../core/bool); required If true, then the analysis-phase test represented by this target should pass. If false, the test should fail. |
| `message` | [string](../core/string); required A descriptive message containing information about the test and its success/failure. |
## message
```
string AnalysisTestResultInfo.message
```
A descriptive message containing information about the test and its success/failure.
## success
```
bool AnalysisTestResultInfo.success
```
If true, then the analysis-phase test represented by this target passed. If false, the test failed.
# CcInfo
Source: https://bazel.build/rules/lib/providers/CcInfo
A provider for compilation and linking of C++. This is also a marking provider telling C++ rules that they can depend on the rule with this provider. If it is not intended for the rule to be depended on by C++, the rule should wrap the CcInfo in some other provider.
## Members
* [CcInfo](#CcInfo)
* [compilation\_context](#compilation_context)
* [linking\_context](#linking_context)
## CcInfo
```
CcInfo CcInfo(*, compilation_context=None, linking_context=None, debug_context=None)
```
The `CcInfo` constructor.
### Parameters
| Parameter | Description |
| - | - |
| `compilation_context` | [CompilationContext](../builtins/CompilationContext); or `None`; default is `None` The `CompilationContext`. |
| `linking_context` | [struct](../builtins/struct); or `None`; default is `None` The `LinkingContext`. |
| `debug_context` | [struct](../builtins/struct); or `None`; default is `None` The `DebugContext`. |
## compilation\_context
```
CompilationContext CcInfo.compilation_context
```
Returns the `CompilationContext`
## linking\_context
```
struct CcInfo.linking_context
```
Returns the `LinkingContext`
# CcToolchainConfigInfo
Source: https://bazel.build/rules/lib/providers/CcToolchainConfigInfo
Additional layer of configurability for C++ rules. Encapsulates platform-dependent specifics of C++ actions through features and action configs. It is used to configure the C++ toolchain, and later on for command line construction. Replaces the functionality of CROSSTOOL file.
# CcToolchainInfo
Source: https://bazel.build/rules/lib/providers/CcToolchainInfo
Information about the C++ compiler being used.
## Members
* [all\_files](#all_files)
* [ar\_executable](#ar_executable)
* [built\_in\_include\_directories](#built_in_include_directories)
* [compiler](#compiler)
* [compiler\_executable](#compiler_executable)
* [cpu](#cpu)
* [disallowed\_copts\_infos](#disallowed_copts_infos)
* [dynamic\_runtime\_lib](#dynamic_runtime_lib)
* [gcov\_executable](#gcov_executable)
* [ld\_executable](#ld_executable)
* [libc](#libc)
* [needs\_pic\_for\_dynamic\_libraries](#needs_pic_for_dynamic_libraries)
* [nm\_executable](#nm_executable)
* [objcopy\_executable](#objcopy_executable)
* [objdump\_executable](#objdump_executable)
* [preprocessor\_executable](#preprocessor_executable)
* [static\_runtime\_lib](#static_runtime_lib)
* [strip\_executable](#strip_executable)
* [sysroot](#sysroot)
* [target\_gnu\_system\_name](#target_gnu_system_name)
## all\_files
```
None CcToolchainInfo.all_files
```
Returns all toolchain files (so they can be passed to actions using this toolchain as inputs).
## ar\_executable
```
None CcToolchainInfo.ar_executable
```
The path to the ar binary.
## built\_in\_include\_directories
```
None CcToolchainInfo.built_in_include_directories
```
Returns the list of built-in directories of the compiler.
## compiler
```
None CcToolchainInfo.compiler
```
C++ compiler.
## compiler\_executable
```
None CcToolchainInfo.compiler_executable
```
The path to the compiler binary.
## cpu
```
None CcToolchainInfo.cpu
```
Target CPU of the C++ toolchain.
## disallowed\_copts\_infos
```
None CcToolchainInfo.disallowed_copts_infos
```
Returns the list of disallowed\_copts\_info structs for disallowed copts enforcement.
## dynamic\_runtime\_lib
```
None CcToolchainInfo.dynamic_runtime_lib(*, feature_configuration)
```
Returns the files from `dynamic_runtime_lib` attribute (so they can be passed to actions using this toolchain as inputs). The caller can check whether the feature\_configuration enables `static_link_cpp_runtimes` feature (if not, neither `static_runtime_lib` nor `dynamic_runtime_lib` have to be used), and use `static_runtime_lib` if static linking mode is active.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | required Feature configuration to be queried. |
## gcov\_executable
```
None CcToolchainInfo.gcov_executable
```
The path to the gcov binary.
## ld\_executable
```
None CcToolchainInfo.ld_executable
```
The path to the ld binary.
## libc
```
None CcToolchainInfo.libc
```
libc version string.
## needs\_pic\_for\_dynamic\_libraries
```
None CcToolchainInfo.needs_pic_for_dynamic_libraries(*, feature_configuration)
```
Returns true if this rule's compilations should apply -fPIC, false otherwise. Determines if we should apply -fPIC for this rule's C++ compilations depending on the C++ toolchain and presence of `--force_pic` Bazel option.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | required Feature configuration to be queried. |
## nm\_executable
```
None CcToolchainInfo.nm_executable
```
The path to the nm binary.
## objcopy\_executable
```
None CcToolchainInfo.objcopy_executable
```
The path to the objcopy binary.
## objdump\_executable
```
None CcToolchainInfo.objdump_executable
```
The path to the objdump binary.
## preprocessor\_executable
```
None CcToolchainInfo.preprocessor_executable
```
The path to the preprocessor binary.
## static\_runtime\_lib
```
None CcToolchainInfo.static_runtime_lib(*, feature_configuration)
```
Returns the files from `static_runtime_lib` attribute (so they can be passed to actions using this toolchain as inputs). The caller should check whether the feature\_configuration enables `static_link_cpp_runtimes` feature (if not, neither `static_runtime_lib` nor `dynamic_runtime_lib` should be used), and use `dynamic_runtime_lib` if dynamic linking mode is active.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | required Feature configuration to be queried. |
## strip\_executable
```
None CcToolchainInfo.strip_executable
```
The path to the strip binary.
## sysroot
```
None CcToolchainInfo.sysroot
```
Returns the sysroot to be used. If the toolchain compiler does not support different sysroots, or the sysroot is the same as the default sysroot, then this method returns `None`.
## target\_gnu\_system\_name
```
None CcToolchainInfo.target_gnu_system_name
```
The GNU System Name.
# ConstraintCollection
Source: https://bazel.build/rules/lib/providers/ConstraintCollection
Provides access to data about a collection of ConstraintValueInfo providers.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
# ConstraintSettingInfo
Source: https://bazel.build/rules/lib/providers/ConstraintSettingInfo
A specific constraint setting that may be used to define a platform. See [Defining Constraints and Platforms](/docs/platforms#constraints-platforms) for more information.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
## Members
* [has\_default\_constraint\_value](#has_default_constraint_value)
## has\_default\_constraint\_value
```
bool ConstraintSettingInfo.has_default_constraint_value
```
Whether there is a default constraint\_value for this setting.
# ConstraintValueInfo
Source: https://bazel.build/rules/lib/providers/ConstraintValueInfo
A value for a constraint setting that can be used to define a platform. See [Defining Constraints and Platforms](/docs/platforms#constraints-platforms) for more information.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
# DebugPackageInfo
Source: https://bazel.build/rules/lib/providers/DebugPackageInfo
A provider for the binary file and its associated .dwp files, if fission is enabled.If Fission (\{@url [https://gcc.gnu.org/wiki/DebugFission](https://gcc.gnu.org/wiki/DebugFission)}) is not enabled, the dwp file will be null.
## Members
* [DebugPackageInfo](#DebugPackageInfo)
* [dwp\_file](#dwp_file)
* [stripped\_file](#stripped_file)
* [target\_label](#target_label)
* [unstripped\_file](#unstripped_file)
## DebugPackageInfo
```
DebugPackageInfo DebugPackageInfo(*, target_label, stripped_file=None, unstripped_file, dwp_file=None)
```
The `DebugPackageInfo` constructor.
### Parameters
| Parameter | Description |
| - | - |
| `target_label` | [Label](../builtins/Label); required The label for the \*\_binary target |
| `stripped_file` | [File](../builtins/File); or `None`; default is `None` The stripped file (the explicit ".stripped" target) |
| `unstripped_file` | [File](../builtins/File); required The unstripped file (the default executable target). |
| `dwp_file` | [File](../builtins/File); or `None`; default is `None` The .dwp file (for fission builds) or null if --fission=no. |
## dwp\_file
```
File DebugPackageInfo.dwp_file
```
Returns the .dwp file (for fission builds) or null if --fission=no.
May return `None`.
## stripped\_file
```
File DebugPackageInfo.stripped_file
```
Returns the stripped file (the explicit ".stripped" target).
May return `None`.
## target\_label
```
Label DebugPackageInfo.target_label
```
Returns the label for the \*\_binary target
## unstripped\_file
```
File DebugPackageInfo.unstripped_file
```
Returns the unstripped file (the default executable target)
# DefaultInfo
Source: https://bazel.build/rules/lib/providers/DefaultInfo
A provider that gives general information about a target's direct and transitive files. Every rule type has this provider, even if it is not returned explicitly by the rule's implementation function.
See the [rules](https://bazel.build/extending/rules) page for extensive guides on how to use this provider.
## Members
* [DefaultInfo](#DefaultInfo)
* [data\_runfiles](#data_runfiles)
* [default\_runfiles](#default_runfiles)
* [executable](#executable)
* [files](#files)
* [files\_to\_run](#files_to_run)
## DefaultInfo
```
DefaultInfo DefaultInfo(*, files=None, runfiles=None, data_runfiles=None, default_runfiles=None, executable=None)
```
The `DefaultInfo` constructor.
### Parameters
| Parameter | Description |
| - | - |
| `files` | [depset](../builtins/depset); or `None`; default is `None` A [`depset`](../builtins/depset) of [`File`](../builtins/File) objects representing the default outputs to build when this target is specified on the bazel command line. By default it is all predeclared outputs. |
| `runfiles` | [runfiles](../builtins/runfiles); or `None`; default is `None` [`runfiles`](../builtins/runfiles) descriptor describing the files that this target needs when run (e.g. via the `run` command or as a tool dependency for an action). |
| `data_runfiles` | [runfiles](../builtins/runfiles); or `None`; default is `None` **It is recommended that you avoid using this parameter (see ["runfiles features to avoid"](https://bazel.build/extending/rules#runfiles_features_to_avoid))** runfiles descriptor describing the runfiles this target needs to run when it is a dependency via the `data` attribute. |
| `default_runfiles` | [runfiles](../builtins/runfiles); or `None`; default is `None` **It is recommended that you avoid using this parameter (see ["runfiles features to avoid"](https://bazel.build/extending/rules#runfiles_features_to_avoid))** runfiles descriptor describing the runfiles this target needs to run when it is a dependency via any attribute other than the `data` attribute. |
| `executable` | [File](../builtins/File); or `None`; default is `None` If this rule is marked [`executable`](../globals/bzl#rule.executable) or [`test`](../globals/bzl#rule.test), this is a [`File`](../builtins/File) object representing the file that should be executed to run the target. By default it is the predeclared output `ctx.outputs.executable` but it is recommended to pass another file (either predeclared or not) explicitly. |
## data\_runfiles
```
runfiles DefaultInfo.data_runfiles
```
runfiles descriptor describing the files that this target needs when run in the condition that it is a `data` dependency attribute. Under most circumstances, use the `default_runfiles` parameter instead. See ["runfiles features to avoid"](https://bazel.build/extending/rules#runfiles_features_to_avoid) for details.
May return `None`.
## default\_runfiles
```
runfiles DefaultInfo.default_runfiles
```
runfiles descriptor describing the files that this target needs when run (via the `run` command or as a tool dependency).
May return `None`.
## executable
```
File DefaultInfo.executable
```
A [`File`](../builtins/File) object representing the executable that should be executed to run the target, or `None` if unset. Should be set only for [`executable`](../globals/bzl#rule.executable) and [`test`](../globals/bzl#rule.test) targets.
May return `None`.
## files
```
depset DefaultInfo.files
```
A [`depset`](../builtins/depset) of [`File`](../builtins/File) objects representing the default outputs to build when this target is specified on the bazel command line. By default it is all predeclared outputs.
May return `None`.
## files\_to\_run
```
FilesToRunProvider DefaultInfo.files_to_run
```
A [`FilesToRunProvider`](../providers/FilesToRunProvider) object containing information about the executable and runfiles of the target.
May return `None`.
# ExecutionInfo
Source: https://bazel.build/rules/lib/providers/ExecutionInfo
Use this provider to specify special environment requirements needed to run tests.
## Members
* [ExecutionInfo](#ExecutionInfo)
* [exec\_group](#exec_group)
* [requirements](#requirements)
## ExecutionInfo
```
ExecutionInfo ExecutionInfo(requirements={}, exec_group='test')
```
Creates an instance.
### Parameters
| Parameter | Description |
| - | - |
| `requirements` | [dict](../core/dict); default is `{}` A dict indicating special execution requirements, such as hardware platforms. |
| `exec_group` | [string](../core/string); default is `'test'` The name of the exec group that is used to execute the test. |
## exec\_group
```
string ExecutionInfo.exec_group
```
The name of the exec group that is used to execute the test.
## requirements
```
dict ExecutionInfo.requirements
```
A dict indicating special execution requirements, such as hardware platforms.
# FeatureFlagInfo
Source: https://bazel.build/rules/lib/providers/FeatureFlagInfo
A provider used to access information about config\_feature\_flag rules.
## Members
* [error](#error)
* [is\_valid\_value](#is_valid_value)
* [value](#value)
## error
```
string FeatureFlagInfo.error
```
If non-None, this error was generated when trying to compute current value of flag.
May return `None`.
## is\_valid\_value
```
bool FeatureFlagInfo.is_valid_value(value)
```
The value of the flag in the configuration used by the flag rule.
### Parameters
| Parameter | Description |
| - | - |
| `value` | [string](../core/string); required String, the value to check for validity for this flag. |
## value
```
string FeatureFlagInfo.value
```
The current value of the flag in the flag's current configuration. None if there is an error.
May return `None`.
# FilesToRunProvider
Source: https://bazel.build/rules/lib/providers/FilesToRunProvider
Contains information about executables produced by a target and the files needed to run it. This provider can not be created directly, it is an implicit output of executable targets accessible via [`DefaultInfo.files_to_run`](../providers/DefaultInfo#files_to_run).
## Members
* [executable](#executable)
* [repo\_mapping\_manifest](#repo_mapping_manifest)
* [runfiles\_manifest](#runfiles_manifest)
## executable
```
File FilesToRunProvider.executable
```
The main executable or None if it does not exist.
May return `None`.
## repo\_mapping\_manifest
```
File FilesToRunProvider.repo_mapping_manifest
```
The repo mapping manifest or None if it does not exist.
May return `None`.
## runfiles\_manifest
```
File FilesToRunProvider.runfiles_manifest
```
The runfiles manifest or None if it does not exist.
May return `None`.
# IncompatiblePlatformProvider
Source: https://bazel.build/rules/lib/providers/IncompatiblePlatformProvider
A provider for targets that are incompatible with the target platform. See [Detecting incompatible targets using `bazel cquery`](/docs/platforms#detecting-incompatible-targets-using-bazel-cquery) for more information.
# InstrumentedFilesInfo
Source: https://bazel.build/rules/lib/providers/InstrumentedFilesInfo
Contains information about source files and instrumentation metadata files for rule targets matched by [`--instrumentation_filter`](https://bazel.build/reference/command-line-reference#flag--instrumentation_filter) for purposes of [code coverage data collection](https://bazel.build/extending/rules#code_coverage). When coverage data collection is enabled, a manifest containing the combined paths in [`instrumented_files`](#instrumented_files) and [`metadata_files`](#metadata_files) are passed to the test action as inputs, with the manifest's path noted in the environment variable `COVERAGE_MANIFEST`. The metadata files, but not the source files, are also passed to the test action as inputs. When `InstrumentedFilesInfo` is returned by an [aspect](https://bazel.build/extending/aspects)'s implementation function, any `InstrumentedFilesInfo` from the base rule target is ignored.
## Members
* [instrumented\_files](#instrumented_files)
* [metadata\_files](#metadata_files)
## instrumented\_files
```
depset InstrumentedFilesInfo.instrumented_files
```
[`depset`](../builtins/depset) of [`File`](../builtins/File) objects representing instrumented source files for this target and its dependencies.
## metadata\_files
```
depset InstrumentedFilesInfo.metadata_files
```
[`depset`](../builtins/depset) of [`File`](../builtins/File) objects representing coverage metadata files for this target and its dependencies. These files contain additional information required to generate LCOV-format coverage output after the code is executed, e.g. the `.gcno` files generated when `gcc` is run with `-ftest-coverage`.
# JavaInfo
Source: https://bazel.build/rules/lib/providers/JavaInfo
A provider encapsulating information about Java and Java-like targets.
## Members
* [\_neverlink](#_neverlink)
* [annotation\_processing](#annotation_processing)
* [api\_generating\_plugins](#api_generating_plugins)
* [compilation\_info](#compilation_info)
* [compile\_jars](#compile_jars)
* [full\_compile\_jars](#full_compile_jars)
* [header\_compilation\_direct\_deps](#header_compilation_direct_deps)
* [java\_outputs](#java_outputs)
* [module\_flags\_info](#module_flags_info)
* [outputs](#outputs)
* [plugins](#plugins)
* [runtime\_output\_jars](#runtime_output_jars)
* [source\_jars](#source_jars)
* [transitive\_compile\_time\_jars](#transitive_compile_time_jars)
* [transitive\_native\_libraries](#transitive_native_libraries)
* [transitive\_runtime\_jars](#transitive_runtime_jars)
* [transitive\_source\_jars](#transitive_source_jars)
## \_neverlink
```
bool JavaInfo._neverlink
```
Whether this library should be used only for compilation and not at runtime.
## annotation\_processing
```
java_annotation_processing JavaInfo.annotation_processing
```
Returns information about annotation processors applied on this Java/Java-like target.
Deprecated: Please use `plugins` instead (which returns information about annotation processors to be applied by consuming targets).
May return `None`.
## api\_generating\_plugins
```
JavaPluginData JavaInfo.api_generating_plugins
```
Returns data about API generating plugins defined or exported by this target.
Those annotation processors are applied to a Java target before producing its header jars (which contain method signatures). When no API plugins are present, header jars are generated from the sources, reducing critical path.
The `api_generating_plugins` is a subset of `plugins`.
## compilation\_info
```
java_compilation_info JavaInfo.compilation_info
```
Returns compilation information for this Java/Java-like target.
May return `None`.
## compile\_jars
```
depset JavaInfo.compile_jars
```
Returns the Jars required by this target directly at compile time. They can be interface jars (ijar or hjar), regular jars or both, depending on whether rule implementations chose to create interface jars or not.
## full\_compile\_jars
```
depset JavaInfo.full_compile_jars
```
Returns the regular, full compile time Jars required by this target directly. They can be
* the corresponding regular Jars of the interface Jars returned by `JavaInfo.compile_jars`
* the regular (full) Jars returned by `JavaInfo.compile_jars`
Note: `JavaInfo.compile_jars` can return a mix of interface Jars and regular Jars.
Only use this method if interface Jars don't work with your rule set(s) (e.g. some Scala targets) If you're working with Java-only targets it's preferable to use interface Jars via `JavaInfo.compile_jars`
## header\_compilation\_direct\_deps
```
depset JavaInfo.header_compilation_direct_deps
```
Returns the direct dependencies of the header compilation action.
## java\_outputs
```
list JavaInfo.java_outputs
```
Returns information about outputs of this Java/Java-like target.
## module\_flags\_info
```
JavaModuleFlagsProvider JavaInfo.module_flags_info
```
Returns the Java module flag configuration.
## outputs
```
java_output_jars JavaInfo.outputs
```
Returns information about outputs of this Java/Java-like target. Deprecated: use java\_outputs.
May return `None`.
## plugins
```
JavaPluginData JavaInfo.plugins
```
Returns data about all plugins that a consuming target should apply.
This is typically either a `java_plugin` itself or a `java_library` exporting one or more plugins.
A `java_library` runs annotation processing with all plugins from this field appearing in `deps` and `plugins` attributes.
## runtime\_output\_jars
```
sequence JavaInfo.runtime_output_jars
```
Returns a list of runtime Jars created by this Java/Java-like target.
## source\_jars
```
sequence JavaInfo.source_jars
```
Returns a list of Jars with all the source files (including those generated by annotations) of the target itself, i.e. NOT including the sources of the transitive dependencies.
## transitive\_compile\_time\_jars
```
depset JavaInfo.transitive_compile_time_jars
```
Returns the transitive set of Jars required to build the target.Note: for binary targets (such as java\_binary and java\_test), this is empty, since such targets
are not intended to be dependencies of other Java targets.
## transitive\_native\_libraries
```
depset JavaInfo.transitive_native_libraries
```
Returns the transitive set of CC native libraries required by the target.
## transitive\_runtime\_jars
```
depset JavaInfo.transitive_runtime_jars
```
Returns a transitive set of Jars required on the target's runtime classpath.Note: for binary targets (such as java\_binary and java\_test), this is empty, since such targets
are not intended to be dependencies of other Java targets.
## transitive\_source\_jars
```
depset JavaInfo.transitive_source_jars
```
Returns the Jars containing source files of the current target and all of its transitive dependencies.
# JavaPluginInfo
Source: https://bazel.build/rules/lib/providers/JavaPluginInfo
A provider encapsulating information about Java plugins.
At the moment, the only supported kind of plugins are annotation processors.
## Members
* [api\_generating\_plugins](#api_generating_plugins)
* [java\_outputs](#java_outputs)
* [plugins](#plugins)
## api\_generating\_plugins
```
JavaPluginData JavaPluginInfo.api_generating_plugins
```
Returns data about API generating plugins defined or exported by this target.
Those annotation processors are applied to a Java target before producing its header jars (which contain method signatures). When no API plugins are present, header jars are generated from the sources, reducing critical path.
The `api_generating_plugins` is a subset of `plugins`.
## java\_outputs
```
list JavaPluginInfo.java_outputs
```
Returns information about outputs of this Java/Java-like target.
## plugins
```
JavaPluginData JavaPluginInfo.plugins
```
Returns data about all plugins that a consuming target should apply.
This is typically either a `java_plugin` itself or a `java_library` exporting one or more plugins.
A `java_library` runs annotation processing with all plugins from this field appearing in `deps` and `plugins` attributes.
# JavaRuntimeInfo
Source: https://bazel.build/rules/lib/providers/JavaRuntimeInfo
Information about the Java runtime being used.
## Members
* [default\_cds](#default_cds)
* [files](#files)
* [hermetic\_files](#hermetic_files)
* [hermetic\_static\_libs](#hermetic_static_libs)
* [java\_executable\_exec\_path](#java_executable_exec_path)
* [java\_executable\_runfiles\_path](#java_executable_runfiles_path)
* [java\_home](#java_home)
* [java\_home\_runfiles\_path](#java_home_runfiles_path)
* [lib\_ct\_sym](#lib_ct_sym)
* [lib\_modules](#lib_modules)
* [version](#version)
## default\_cds
```
File JavaRuntimeInfo.default_cds
```
Returns the JDK default CDS archive.
May return `None`.
## files
```
depset JavaRuntimeInfo.files
```
Returns the files in the Java runtime.
## hermetic\_files
```
depset JavaRuntimeInfo.hermetic_files
```
Returns the files in the Java runtime needed for hermetic deployments.
## hermetic\_static\_libs
```
sequence JavaRuntimeInfo.hermetic_static_libs
```
Returns the JDK static libraries.
## java\_executable\_exec\_path
```
string JavaRuntimeInfo.java_executable_exec_path
```
Returns the execpath of the Java executable.
## java\_executable\_runfiles\_path
```
string JavaRuntimeInfo.java_executable_runfiles_path
```
Returns the path of the Java executable in runfiles trees. This should only be used when one needs to access the JVM during the execution of a binary or a test built by Bazel. In particular, when one needs to invoke the JVM during an action, java\_executable\_exec\_path should be used instead.
## java\_home
```
string JavaRuntimeInfo.java_home
```
Returns the execpath of the root of the Java installation.
## java\_home\_runfiles\_path
```
string JavaRuntimeInfo.java_home_runfiles_path
```
Returns the path of the Java installation in runfiles trees. This should only be used when one needs to access the JDK during the execution of a binary or a test built by Bazel. In particular, when one needs the JDK during an action, java\_home should be used instead.
## lib\_ct\_sym
```
File JavaRuntimeInfo.lib_ct_sym
```
Returns the lib/ct.sym file.
May return `None`.
## lib\_modules
```
File JavaRuntimeInfo.lib_modules
```
Returns the lib/modules file.
May return `None`.
## version
```
int JavaRuntimeInfo.version
```
The Java feature version of the runtime. This is 0 if the version is unknown.
# JavaToolchainInfo
Source: https://bazel.build/rules/lib/providers/JavaToolchainInfo
Provides access to information about the Java toolchain rule. Accessible as a 'java\_toolchain' field on a Target struct.
## Members
* [bootclasspath](#bootclasspath)
* [ijar](#ijar)
* [jacocorunner](#jacocorunner)
* [java\_runtime](#java_runtime)
* [jvm\_opt](#jvm_opt)
* [label](#label)
* [proguard\_allowlister](#proguard_allowlister)
* [single\_jar](#single_jar)
* [source\_version](#source_version)
* [target\_version](#target_version)
* [tools](#tools)
## bootclasspath
```
depset JavaToolchainInfo.bootclasspath
```
The Java target bootclasspath entries. Corresponds to javac's -bootclasspath flag.
## ijar
```
FilesToRunProvider JavaToolchainInfo.ijar
```
A FilesToRunProvider representing the ijar executable.
## jacocorunner
```
FilesToRunProvider JavaToolchainInfo.jacocorunner
```
The jacocorunner used by the toolchain.
May return `None`.
## java\_runtime
```
JavaRuntimeInfo JavaToolchainInfo.java_runtime
```
The java runtime information.
## jvm\_opt
```
depset JavaToolchainInfo.jvm_opt
```
The default options for the JVM running the java compiler and associated tools.
## label
```
Label JavaToolchainInfo.label
```
The toolchain label.
## proguard\_allowlister
```
FilesToRunProvider JavaToolchainInfo.proguard_allowlister
```
Return the binary to validate proguard configuration
May return `None`.
## single\_jar
```
FilesToRunProvider JavaToolchainInfo.single_jar
```
The SingleJar executable.
## source\_version
```
string JavaToolchainInfo.source_version
```
The java source version.
## target\_version
```
string JavaToolchainInfo.target_version
```
The java target version.
## tools
```
depset JavaToolchainInfo.tools
```
The compilation tools.
# MaterializedDepsInfo
Source: https://bazel.build/rules/lib/providers/MaterializedDepsInfo
The provider returned from materializer rules to materialize dependencies.
## Members
* [deps](#deps)
## deps
```
sequence MaterializedDepsInfo.deps
```
A newly allocated immutable copy of the list of dependencies. These may be ConfiguredTarget or DormantDependency objects.
# ObjcProvider
Source: https://bazel.build/rules/lib/providers/ObjcProvider
A provider for compilation and linking of objc.
## Members
* [direct\_module\_maps](#direct_module_maps)
* [direct\_sources](#direct_sources)
* [j2objc\_library](#j2objc_library)
* [module\_map](#module_map)
* [source](#source)
* [strict\_include](#strict_include)
* [umbrella\_header](#umbrella_header)
## direct\_module\_maps
```
sequence ObjcProvider.direct_module_maps
```
Module map files from this target directly (no transitive module maps). Used to enforce proper use of private header files and for Swift compilation.
## direct\_sources
```
sequence ObjcProvider.direct_sources
```
All direct source files from this target (no transitive files), including any headers in the 'srcs' attribute.
## j2objc\_library
```
depset ObjcProvider.j2objc_library
```
Static libraries that are built from J2ObjC-translated Java code.
## module\_map
```
depset ObjcProvider.module_map
```
Clang module maps, used to enforce proper use of private header files.
## source
```
depset ObjcProvider.source
```
All transitive source files.
## strict\_include
```
depset ObjcProvider.strict_include
```
Non-propagated include search paths specified with '-I' on the command line. Also known as header search paths (and distinct from *user* header search paths).
## umbrella\_header
```
depset ObjcProvider.umbrella_header
```
Clang umbrella header. Public headers are #included in umbrella headers to be compatible with J2ObjC segmented headers.
# OutputGroupInfo
Source: https://bazel.build/rules/lib/providers/OutputGroupInfo
A provider that indicates what output groups a rule has.
See [Requesting output files](https://bazel.build/extending/rules#requesting_output_files) for more information.
## Members
* [OutputGroupInfo](#OutputGroupInfo)
## OutputGroupInfo
```
OutputGroupInfo OutputGroupInfo(**kwargs)
```
Instantiate this provider with
```
OutputGroupInfo(group1 = , group2 = ...)
```
See [Requesting output files](https://bazel.build/extending/rules#requesting_output_files) for more information.
### Parameters
| Parameter | Description |
| - | - |
| `kwargs` | default is `{}` |
# PackageSpecificationInfo
Source: https://bazel.build/rules/lib/providers/PackageSpecificationInfo
Information about transitive package specifications used in package groups.
## Members
* [contains](#contains)
## contains
```
bool PackageSpecificationInfo.contains(target)
```
Checks if a target exists in a package group.
### Parameters
| Parameter | Description |
| - | - |
| `target` | [Label](../builtins/Label); or [string](../core/string); required A target which is checked if it exists inside the package group. |
# PlatformInfo
Source: https://bazel.build/rules/lib/providers/PlatformInfo
Provides access to data about a specific platform. See [Defining Constraints and Platforms](/docs/platforms#constraints-platforms) for more information.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
# RunEnvironmentInfo
Source: https://bazel.build/rules/lib/providers/RunEnvironmentInfo
A provider that can be returned from executable rules to control the environment in which their executable is executed.
## Members
* [environment](#environment)
* [inherited\_environment](#inherited_environment)
## environment
```
dict RunEnvironmentInfo.environment
```
A map of string keys and values that represent environment variables and their values. These will be made available when the target that returns this provider is executed, either as a test or via the run command.
## inherited\_environment
```
List RunEnvironmentInfo.inherited_environment
```
A sequence of names of environment variables. These variables are made available with their current value taken from the shell environment when the target that returns this provider is executed, either as a test or via the run command. If a variable is contained in both `environment` and `inherited_environment`, the value inherited from the shell environment will take precedence if set. This is most useful for test rules, which run with a hermetic environment under `bazel test` and can use this mechanism to non-hermetically include a variable from the outer environment. By contrast, `bazel run` already forwards the outer environment. Note, though, that it may be surprising for an otherwise hermetic test to hardcode a non-hermetic dependency on the environment, and that this may even accidentally expose sensitive information. Prefer setting the test environment explicitly with the `--test_env` flag, and even then prefer to avoid using this flag and instead populate the environment explicitly.
# TemplateVariableInfo
Source: https://bazel.build/rules/lib/providers/TemplateVariableInfo
Encapsulates template variables, that is, variables that can be referenced by strings like `$(VARIABLE)` in BUILD files and expanded by `ctx.expand_make_variables` and implicitly in certain attributes of built-in rules.
`TemplateVariableInfo` can be created by calling its eponymous constructor with a string-to-string dict as an argument that specifies the variables provided.
Example: `platform_common.TemplateVariableInfo({'FOO': 'bar'})`
## Members
* [variables](#variables)
## variables
```
dict TemplateVariableInfo.variables
```
Returns the make variables defined by this target as a dictionary with string keys and string values
# ToolchainInfo
Source: https://bazel.build/rules/lib/providers/ToolchainInfo
Provider returned by [toolchain rules](/docs/toolchains#defining-toolchains) to share data with [rules which depend on toolchains](/docs/toolchains#writing-rules-that-use-toolchains). Read about [toolchains](/docs/toolchains) for more information.
# ToolchainTypeInfo
Source: https://bazel.build/rules/lib/providers/ToolchainTypeInfo
Provides access to data about a specific toolchain type.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
## Members
* [type\_label](#type_label)
## type\_label
```
Label ToolchainTypeInfo.type_label
```
The label uniquely identifying this toolchain type.
# file_provider
Source: https://bazel.build/rules/lib/providers/file_provider
An interface for rules that provide files.
# java_compilation_info
Source: https://bazel.build/rules/lib/providers/java_compilation_info
Provides access to compilation information for Java rules.
## Members
* [boot\_classpath](#boot_classpath)
* [compilation\_classpath](#compilation_classpath)
* [javac\_options](#javac_options)
* [runtime\_classpath](#runtime_classpath)
## boot\_classpath
```
list java_compilation_info.boot_classpath
```
Boot classpath for this Java target.
## compilation\_classpath
```
depset java_compilation_info.compilation_classpath
```
Compilation classpath for this Java target.
## javac\_options
```
depset java_compilation_info.javac_options
```
A depset of options to java compiler. To get the exact list of options passed to javac in the correct order, use the tokenize\_javacopts utility in rules\_java
## runtime\_classpath
```
depset java_compilation_info.runtime_classpath
```
Run-time classpath for this Java target.
# java_output_jars
Source: https://bazel.build/rules/lib/providers/java_output_jars
Information about outputs of a Java rule. Deprecated: use java\_info.java\_outputs.
## Members
* [jars](#jars)
* [jdeps](#jdeps)
* [native\_headers](#native_headers)
## jars
```
list java_output_jars.jars
```
Returns information about outputs of this Java/Java-like target. Deprecated: Use java\_info.java\_outputs.
## jdeps
```
File java_output_jars.jdeps
```
A manifest proto file. The protobuf file containing the manifest generated from JavaBuilder. This function returns a value when exactly one manifest proto file is present in the outputs. Deprecated: Use java\_info.java\_outputs\[i].jdeps.
May return `None`.
## native\_headers
```
File java_output_jars.native_headers
```
A jar containing CC header files supporting native method implementation. This function returns a value when exactly one native headers jar file is present in the outputs. Deprecated: Use java\_info.java\_outputs\[i].native\_headers\_jar.
May return `None`.
# cache repository rules
Source: https://bazel.build/rules/lib/repo/cache
The following functions can be loaded from
`@bazel_tools//tools/build_defs/repo:cache.bzl`.
Returns the default canonical id to use for downloads.
## get\_default\_canonical\_id
```
load("@bazel//tools/build_defs/repo:cache.bzl", "get_default_canonical_id")
get_default_canonical_id(repository_ctx, urls)
```
Returns the default canonical id to use for downloads.
Returns `""` (empty string) when Bazel is run with
`--repo_env=BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID=0`.
e.g.
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:cache.bzl", "get_default_canonical_id")
# ...
repository_ctx.download_and_extract(
url = urls,
integrity = integrity
canonical_id = get_default_canonical_id(repository_ctx, urls),
),
```
### Parameters
`repository_ctx`
required.
The repository context of the repository rule calling this utility
function.
`urls`
required.
A list of URLs matching what is passed to `repository_ctx.download` and
`repository_ctx.download_and_extract`.
# git repository rules
Source: https://bazel.build/rules/lib/repo/git
The following functions can be loaded from
`@bazel_tools//tools/build_defs/repo:git.bzl`.
Rules for cloning external git repositories.
## git\_repository
```
load("@bazel//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(name, add_prefix, branch, build_file, build_file_content, canonical_id, commit,
init_submodules, patch_args, patch_cmds, patch_cmds_win, patch_strip, patch_tool,
patches, recursive_init_submodules, remote, remote_module_file_integrity,
remote_module_file_urls, remote_patch_strip, remote_patches, shallow_since,
sparse_checkout_file, sparse_checkout_patterns, strip_prefix, tag, verbose,
workspace_file, workspace_file_content)
```
Clone an external git repository.
Clones a Git repository, checks out the specified branch, tag, or commit, and
makes its targets available for binding. If no branch, tag or commit is
specified, check out the repository's default branch. Also determine the id
and date of the commit that was checked out, and return a dict with
parameters that provide a reproducible version of this rule (which a tag or
branch not necessarily is).
Bazel will first try to perform a shallow fetch of only the specified commit.
If that fails (usually due to missing server support), it will fall back to a
full fetch of the repository.
Prefer [`http_archive`](/rules/lib/repo/http#http_archive) to `git_repository`.
The reasons are:
* Git repository rules depend on system `git(1)` whereas the HTTP downloader is built
into Bazel and has no system dependencies.
* `http_archive` supports a list of `urls` as mirrors, and `git_repository` supports only
a single `remote`.
* `http_archive` works with the [repository cache](/run/build#repository-cache), but not
`git_repository`. See
[#5116](https://github.com/bazelbuild/bazel/issues/5116) for more information.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`add_prefix`
String; optional
Destination directory relative to the repository directory.
The git repo will be cloned into this directory, after applying `strip_prefix`
(if any) to the file paths within the repo. For example, file
`foo-1.2.3/src/foo.h` will be cloned to `bar/src/foo.h` if `add_prefix = "bar"`
and `strip_prefix = "foo-1.2.3"`.
`branch`
String; optional
branch in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified.
`build_file`
[Label](https://bazel.build/concepts/labels); optional
The file to use as the BUILD file for this repository. This attribute is an absolute label (use '@//' for the main repo). The file does not need to be named BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it from the repository's actual BUILD files).
`build_file_content`
String; optional
The content for the BUILD file for this repository.
`canonical_id`
String; optional
A canonical ID of the file downloaded.
If specified and non-empty, Bazel will not take the file from cache, unless it
was added to the cache by a request with the same canonical ID.
If unspecified or empty, Bazel by default uses the URLs of the file as the
canonical ID. This helps catch the common mistake of updating the URLs without
also updating the hash, resulting in builds that succeed locally but fail on
machines without the file in the cache. This behavior can be disabled with
\--repo\_env=BAZEL\_HTTP\_RULES\_URLS\_AS\_DEFAULT\_CANONICAL\_ID=0.
`commit`
String; optional
specific commit to be checked out. Precisely one of branch, tag, or commit must be specified.
`init_submodules`
Boolean; optional
Whether to clone submodules in the repository.
`patch_args`
List of strings; optional
The arguments given to the patch tool. Defaults to -p0 (see the `patch_strip` attribute), however -p1 will usually be needed for patches generated by git. If multiple -p arguments are specified, the last one will take effect.If arguments other than -p are specified, Bazel will fall back to use patch command line tool instead of the Bazel-native patch implementation. When falling back to patch command line tool and patch\_tool attribute is not specified, `patch` will be used.
`patch_cmds`
List of strings; optional
Sequence of Bash commands to be applied on Linux/Macos after patches are applied.
`patch_cmds_win`
List of strings; optional
Sequence of Powershell commands to be applied on Windows after patches are applied. If this attribute is not set, patch\_cmds will be executed on Windows, which requires Bash binary to exist.
`patch_strip`
Integer; optional
When set to `N`, this is equivalent to inserting `-pN` to the beginning of `patch_args`.
`patch_tool`
String; optional
The patch(1) utility to use. If this is specified, Bazel will use the specified patch tool instead of the Bazel-native patch implementation.
`patches`
[List of labels](https://bazel.build/concepts/labels); optional
A list of files that are to be applied as patches after extracting the archive. By default, it uses the Bazel-native patch implementation which doesn't support binary patch, but Bazel will fall back to use patch command line tool if `patch_tool` attribute is specified or there are arguments other than `-p` in `patch_args` attribute.
`recursive_init_submodules`
Boolean; optional
Whether to clone submodules recursively in the repository.
`remote`
String; required
The URI of the remote Git repository
`remote_module_file_integrity`
String; optional
For internal use only.
`remote_module_file_urls`
List of strings; optional
For internal use only.
`remote_patch_strip`
Integer; optional
The number of leading slashes to be stripped from the file name in the remote patches.
`remote_patches`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
A map of patch file URL to its integrity value, they are applied after cloning the repository and before applying patch files from the `patches` attribute. It uses the Bazel-native patch implementation, you can specify the patch strip number with `remote_patch_strip`
`shallow_since`
String; optional
an optional date, not after the specified commit; the argument is not allowed if a tag or branch is specified (which can always be cloned with --depth=1). Setting such a date close to the specified commit may allow for a shallow clone of the repository even if the server does not support shallow fetches of arbitrary commits. Due to bugs in git's --shallow-since implementation, using this attribute is not recommended as it may result in fetch failures.
`sparse_checkout_file`
[Label](https://bazel.build/concepts/labels); optional
File containing .gitignore-style patterns for a sparse checkout of files in this repository. Either `sparse_checkout_patterns` or `sparse_checkout_file` may be specified, or neither, but not both.
`sparse_checkout_patterns`
List of strings; optional
Sequence of patterns for a sparse checkout of files in this repository.
`strip_prefix`
String; optional
A directory prefix to strip from the extracted files.
For large repositories, consider combining this with `sparse_checkout_patterns`
to limit the files checked out before this prefix is stripped. Patterns match
paths in the original Git repository.
`tag`
String; optional
tag in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified.
`verbose`
Boolean; optional
`workspace_file`
[Label](https://bazel.build/concepts/labels); optional
No-op attribute; do not use.
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`add_prefix`
String; optional
Destination directory relative to the repository directory.
The git repo will be cloned into this directory, after applying `strip_prefix`
(if any) to the file paths within the repo. For example, file
`foo-1.2.3/src/foo.h` will be cloned to `bar/src/foo.h` if `add_prefix = "bar"`
and `strip_prefix = "foo-1.2.3"`.
`branch`
String; optional
branch in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified.
`build_file`
[Label](https://bazel.build/concepts/labels); optional
The file to use as the BUILD file for this repository. This attribute is an absolute label (use '@//' for the main repo). The file does not need to be named BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it from the repository's actual BUILD files).
`build_file_content`
String; optional
The content for the BUILD file for this repository.
`canonical_id`
String; optional
A canonical ID of the file downloaded.
If specified and non-empty, Bazel will not take the file from cache, unless it
was added to the cache by a request with the same canonical ID.
If unspecified or empty, Bazel by default uses the URLs of the file as the
canonical ID. This helps catch the common mistake of updating the URLs without
also updating the hash, resulting in builds that succeed locally but fail on
machines without the file in the cache. This behavior can be disabled with
\--repo\_env=BAZEL\_HTTP\_RULES\_URLS\_AS\_DEFAULT\_CANONICAL\_ID=0.
`commit`
String; optional
specific commit to be checked out. Precisely one of branch, tag, or commit must be specified.
`init_submodules`
Boolean; optional
Whether to clone submodules in the repository.
`patch_args`
List of strings; optional
The arguments given to the patch tool. Defaults to -p0 (see the `patch_strip` attribute), however -p1 will usually be needed for patches generated by git. If multiple -p arguments are specified, the last one will take effect.If arguments other than -p are specified, Bazel will fall back to use patch command line tool instead of the Bazel-native patch implementation. When falling back to patch command line tool and patch\_tool attribute is not specified, `patch` will be used.
`patch_cmds`
List of strings; optional
Sequence of Bash commands to be applied on Linux/Macos after patches are applied.
`patch_cmds_win`
List of strings; optional
Sequence of Powershell commands to be applied on Windows after patches are applied. If this attribute is not set, patch\_cmds will be executed on Windows, which requires Bash binary to exist.
`patch_strip`
Integer; optional
When set to `N`, this is equivalent to inserting `-pN` to the beginning of `patch_args`.
`patch_tool`
String; optional
The patch(1) utility to use. If this is specified, Bazel will use the specified patch tool instead of the Bazel-native patch implementation.
`patches`
[List of labels](https://bazel.build/concepts/labels); optional
A list of files that are to be applied as patches after extracting the archive. By default, it uses the Bazel-native patch implementation which doesn't support binary patch, but Bazel will fall back to use patch command line tool if `patch_tool` attribute is specified or there are arguments other than `-p` in `patch_args` attribute.
`recursive_init_submodules`
Boolean; optional
Whether to clone submodules recursively in the repository.
`remote`
String; required
The URI of the remote Git repository
`remote_module_file_integrity`
String; optional
For internal use only.
`remote_module_file_urls`
List of strings; optional
For internal use only.
`remote_patch_strip`
Integer; optional
The number of leading slashes to be stripped from the file name in the remote patches.
`remote_patches`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
A map of patch file URL to its integrity value, they are applied after cloning the repository and before applying patch files from the `patches` attribute. It uses the Bazel-native patch implementation, you can specify the patch strip number with `remote_patch_strip`
`shallow_since`
String; optional
an optional date, not after the specified commit; the argument is not allowed if a tag or branch is specified (which can always be cloned with --depth=1). Setting such a date close to the specified commit may allow for a shallow clone of the repository even if the server does not support shallow fetches of arbitrary commits. Due to bugs in git's --shallow-since implementation, using this attribute is not recommended as it may result in fetch failures.
`sparse_checkout_file`
[Label](https://bazel.build/concepts/labels); optional
File containing .gitignore-style patterns for a sparse checkout of files in this repository. Either `sparse_checkout_patterns` or `sparse_checkout_file` may be specified, or neither, but not both.
`sparse_checkout_patterns`
List of strings; optional
Sequence of patterns for a sparse checkout of files in this repository.
`strip_prefix`
String; optional
A directory prefix to strip from the extracted files.
For large repositories, consider combining this with `sparse_checkout_patterns`
to limit the files checked out before this prefix is stripped. Patterns match
paths in the original Git repository.
`tag`
String; optional
tag in the remote repository to checked out. Precisely one of branch, tag, or commit must be specified.
`verbose`
Boolean; optional
`workspace_file`
[Label](https://bazel.build/concepts/labels); optional
No-op attribute; do not use.
`workspace_file_content`
String; optional
No-op attribute; do not use.
# http repository rules
Source: https://bazel.build/rules/lib/repo/http
The following functions can be loaded from
`@bazel_tools//tools/build_defs/repo:http.bzl`.
Rules for downloading files and archives over HTTP.
### Setup
To use these rules in a module extension, load them in your .bzl file and then call them from your
extension's implementation function. For example, to use `http_archive`:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
def _my_extension_impl(mctx):
http_archive(name = "foo", urls = [...])
my_extension = module_extension(implementation = _my_extension_impl)
```
Alternatively, you can directly call these repo rules in your MODULE.bazel file with
`use_repo_rule`:
```python theme={null}
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(name = "foo", urls = [...])
```
## http\_archive
```
load("@bazel//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(name, add_prefix, auth_patterns, build_file, build_file_content, canonical_id, files,
integrity, netrc, patch_args, patch_cmds, patch_cmds_win, patch_strip, patch_tool,
patches, remote_file_integrity, remote_file_urls, remote_module_file_integrity,
remote_module_file_urls, remote_patch_strip, remote_patches, sha256, strip_components,
strip_prefix, type, url, urls, workspace_file, workspace_file_content)
```
Downloads a Bazel repository as a compressed archive file, decompresses it,
and makes its targets available for binding.
It supports the following file extensions: `"zip"`, `"jar"`, `"war"`, `"aar"`, `"nupkg"`, `"whl"`, `"tar"`, `"tar.gz"`, `"tgz"`, `"gz"`, `"tar.xz"`, `"txz"`, `"xz"`, `"tar.zst"`, `"tzst"`, `"zst"`, `"tar.bz2"`, `"tbz"`, `"bz2"`, `"ar"`, `"deb"`, `"7z"`, `"tar.br"` or `"br"`.
Examples:
Suppose the current repository contains the source code for a chat program,
rooted at the directory `~/chat-app`. It needs to depend on an SSL library
which is available from [http://example.com/openssl.zip](http://example.com/openssl.zip). This `.zip` file
contains the following directory structure:
```
WORKSPACE
src/
openssl.cc
openssl.h
```
In the local repository, the user creates a `openssl.BUILD` file which
contains the following target definition:
```python theme={null}
cc_library(
name = "openssl-lib",
srcs = ["src/openssl.cc"],
hdrs = ["src/openssl.h"],
)
```
Targets in the `~/chat-app` repository can depend on this target if the
following lines are added to `~/chat-app/WORKSPACE`:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "my_ssl",
url = "http://example.com/openssl.zip",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
build_file = "@//:openssl.BUILD",
)
```
Then targets would specify `@my_ssl//:openssl-lib` as a dependency.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`add_prefix`
String; optional
Destination directory relative to the repository directory.
The archive will be unpacked into this directory, after applying `strip_prefix`
(if any) to the file paths within the archive. For example, file
`foo-1.2.3/src/foo.h` will be unpacked to `bar/src/foo.h` if `add_prefix = "bar"`
and `strip_prefix = "foo-1.2.3"`.
`auth_patterns`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
An optional dict mapping host names to custom authorization patterns.
If a URL's host name is present in this dict the value will be used as a pattern when
generating the authorization header for the http request. This enables the use of custom
authorization schemes used in a lot of common cloud storage providers.
The pattern currently supports 2 tokens: `` and
``, which are replaced with their equivalent value
in the netrc file for the same host name. After formatting, the result is set
as the value for the `Authorization` field of the HTTP request.
Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token:
```
auth_patterns = {
"storage.cloudprovider.com": "Bearer "
}
```
netrc:
```
machine storage.cloudprovider.com
password RANDOM-TOKEN
```
The final HTTP request would have the following header:
```
Authorization: Bearer RANDOM-TOKEN
```
`build_file`
[Label](https://bazel.build/concepts/labels); optional
The file to use as the BUILD file for this repository.This attribute is an absolute label (use '@//' for the main repo). The file does not need to be named BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it from the repository's actual BUILD files. Either build\_file or build\_file\_content can be specified, but not both.
`build_file_content`
String; optional
The content for the BUILD file for this repository. Either build\_file or build\_file\_content can be specified, but not both.
`canonical_id`
String; optional
A canonical ID of the file downloaded.
If specified and non-empty, Bazel will not take the file from cache, unless it
was added to the cache by a request with the same canonical ID.
If unspecified or empty, Bazel by default uses the URLs of the file as the
canonical ID. This helps catch the common mistake of updating the URLs without
also updating the hash, resulting in builds that succeed locally but fail on
machines without the file in the cache. This behavior can be disabled with
\--repo\_env=BAZEL\_HTTP\_RULES\_URLS\_AS\_DEFAULT\_CANONICAL\_ID=0.
`files`
Dictionary: String -> Label; optional
A map of relative paths (key) to a file label (value) that overlaid on the repo as
a symlink. This is useful when you want to add REPO.bazel or BUILD.bazel files atop an existing
repository. Files are symlinked after remote files are downloaded and patches (`remote_patches`,
`patches`) are applied. Existing files will be overwritten.
`integrity`
String; optional
Expected checksum in Subresource Integrity format of the file downloaded.
This must match the checksum of the file downloaded. *It is a security risk
to omit the checksum as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but either this attribute or `sha256` should be set before shipping.
`netrc`
String; optional
Location of the .netrc file to use for authentication
`patch_args`
List of strings; optional
The arguments given to the patch tool. Defaults to -p0 (see the `patch_strip` attribute), however -p1 will usually be needed for patches generated by git. If multiple -p arguments are specified, the last one will take effect.If arguments other than -p are specified, Bazel will fall back to use patch command line tool instead of the Bazel-native patch implementation. When falling back to patch command line tool and patch\_tool attribute is not specified, `patch` will be used. This only affects patch files in the `patches` attribute.
`patch_cmds`
List of strings; optional
Sequence of Bash commands to be applied on Linux/Macos after patches are applied.
`patch_cmds_win`
List of strings; optional
Sequence of Powershell commands to be applied on Windows after patches are applied. If this attribute is not set, patch\_cmds will be executed on Windows, which requires Bash binary to exist.
`patch_strip`
Integer; optional
When set to `N`, this is equivalent to inserting `-pN` to the beginning of `patch_args`.
`patch_tool`
String; optional
The patch(1) utility to use. If this is specified, Bazel will use the specified patch tool instead of the Bazel-native patch implementation.
`patches`
[List of labels](https://bazel.build/concepts/labels); optional
A list of files that are to be applied as patches after extracting the archive. By default, it uses the Bazel-native patch implementation which doesn't support binary patch, but Bazel will fall back to use patch command line tool if `patch_tool` attribute is specified or there are arguments other than `-p` in `patch_args` attribute.
`remote_file_integrity`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
A map of file relative paths (key) to its integrity value (value). These relative paths should map to the files (key) in the `remote_file_urls` attribute.
`remote_file_urls`
[Dictionary: String -> List of strings](https://bazel.build/rules/lib/dict); optional
A map of relative paths (key) to a list of URLs (value) that are to be downloaded
and made available as overlaid files on the repo. This is useful when you want to add REPO.bazel or
BUILD.bazel files atop an existing repository. The files are downloaded before `files` are
symlinked and patches (`remote_patches`, `patches`) are applied. The list of URLs should all be
possible mirrors of the same file. The URLs are tried in order until one succeeds. Existing files
will be overwritten.
`remote_module_file_integrity`
String; optional
For internal use only.
`remote_module_file_urls`
List of strings; optional
For internal use only.
`remote_patch_strip`
Integer; optional
The number of leading slashes to be stripped from the file name in the remote patches.
`remote_patches`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
A map of patch file URL to its integrity value, they are applied after extracting the archive and before applying patch files from the `patches` attribute. It uses the Bazel-native patch implementation, you can specify the patch strip number with `remote_patch_strip`
`sha256`
String; optional
The expected SHA-256 of the file downloaded.
This must match the SHA-256 of the file downloaded. *It is a security risk
to omit the SHA-256 as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but either this attribute or `integrity` should be set before shipping.
`strip_components`
Integer; optional
Strip the given number of leading components from file paths
on extraction.
Only one of `strip_components` and `strip_prefix` can be set.
`strip_prefix`
String; optional
A directory prefix to strip from the extracted files.
Many archives contain a top-level directory that contains all of the useful
files in archive. Instead of needing to specify this prefix over and over
in the `build_file`, this field can be used to strip it from all of the
extracted files.
For example, suppose you are using `foo-lib-latest.zip`, which contains the
directory `foo-lib-1.2.3/` under which there is a `WORKSPACE` file and are
`src/`, `lib/`, and `test/` directories that contain the actual code you
wish to build. Specify `strip_prefix = "foo-lib-1.2.3"` to use the
`foo-lib-1.2.3` directory as your top-level directory.
Note that if there are files outside of this directory, they will be
discarded and inaccessible (e.g., a top-level license file). This includes
files/directories that start with the prefix but are not in the directory
(e.g., `foo-lib-1.2.3.release-notes`). If the specified prefix does not
match a directory in the archive, Bazel will return an error.
Only one of `strip_prefix` and `strip_components` can be set.
`type`
String; optional
The archive type of the downloaded file.
By default, the archive type is determined from the file extension of the
URL. If the file has no extension, you can explicitly specify one of the
following: `"zip"`, `"jar"`, `"war"`, `"aar"`, `"nupkg"`, `"whl"`, `"tar"`, `"tar.gz"`, `"tgz"`, `"gz"`, `"tar.xz"`, `"txz"`, `"xz"`, `"tar.zst"`, `"tzst"`, `"zst"`, `"tar.bz2"`, `"tbz"`, `"bz2"`, `"ar"`, `"deb"`, `"7z"`, `"tar.br"` or `"br"`.
`url`
String; optional
A URL to a file that will be made available to Bazel.
This must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
More flexibility can be achieved by the urls parameter that allows
to specify alternative URLs to fetch from.
`urls`
List of strings; optional
A list of URLs to a file that will be made available to Bazel.
Each entry must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
URLs are tried in order until one succeeds, so you should list local mirrors first.
If all downloads fail, the rule will fail.
`workspace_file`
[Label](https://bazel.build/concepts/labels); optional
No-op attribute; do not use.
`workspace_file_content`
String; optional
No-op attribute; do not use.
**ENVIRONMENT VARIABLES**
This repository rule depends on the following environment variables:
* `BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID`
## http\_file
```
load("@bazel//tools/build_defs/repo:http.bzl", "http_file")
http_file(name, auth_patterns, canonical_id, downloaded_file_path, executable, integrity, netrc,
sha256, url, urls)
```
Downloads a file from a URL and makes it available to be used as a file
group.
Examples:
Suppose you need to have a debian package for your custom rules. This package
is available from [http://example.com/package.deb](http://example.com/package.deb). Then you can add to your
WORKSPACE file:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "my_deb",
url = "http://example.com/package.deb",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```
Targets would specify `@my_deb//file` as a dependency to depend on this file.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`auth_patterns`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
An optional dict mapping host names to custom authorization patterns.
If a URL's host name is present in this dict the value will be used as a pattern when
generating the authorization header for the http request. This enables the use of custom
authorization schemes used in a lot of common cloud storage providers.
The pattern currently supports 2 tokens: `` and
``, which are replaced with their equivalent value
in the netrc file for the same host name. After formatting, the result is set
as the value for the `Authorization` field of the HTTP request.
Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token:
```
auth_patterns = {
"storage.cloudprovider.com": "Bearer "
}
```
netrc:
```
machine storage.cloudprovider.com
password RANDOM-TOKEN
```
The final HTTP request would have the following header:
```
Authorization: Bearer RANDOM-TOKEN
```
`canonical_id`
String; optional
A canonical ID of the file downloaded.
If specified and non-empty, Bazel will not take the file from cache, unless it
was added to the cache by a request with the same canonical ID.
If unspecified or empty, Bazel by default uses the URLs of the file as the
canonical ID. This helps catch the common mistake of updating the URLs without
also updating the hash, resulting in builds that succeed locally but fail on
machines without the file in the cache. This behavior can be disabled with
\--repo\_env=BAZEL\_HTTP\_RULES\_URLS\_AS\_DEFAULT\_CANONICAL\_ID=0.
`downloaded_file_path`
String; optional
Path assigned to the file downloaded
`executable`
Boolean; optional
If the downloaded file should be made executable.
`integrity`
String; optional
Expected checksum in Subresource Integrity format of the file downloaded.
This must match the checksum of the file downloaded. *It is a security risk
to omit the checksum as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but either this attribute or `sha256` should be set before shipping.
`netrc`
String; optional
Location of the .netrc file to use for authentication
`sha256`
String; optional
The expected SHA-256 of the file downloaded.
This must match the SHA-256 of the file downloaded. *It is a security risk
to omit the SHA-256 as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but should be set before shipping.
`url`
String; optional
A URL to a file that will be made available to Bazel.
This must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
More flexibility can be achieved by the urls parameter that allows
to specify alternative URLs to fetch from.
`urls`
List of strings; optional
A list of URLs to a file that will be made available to Bazel.
Each entry must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
URLs are tried in order until one succeeds, so you should list local mirrors first.
If all downloads fail, the rule will fail.
**ENVIRONMENT VARIABLES**
This repository rule depends on the following environment variables:
* `BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID`
## http\_jar
```
load("@bazel//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(name, auth_patterns, canonical_id, downloaded_file_name, integrity, netrc, sha256, url,
urls)
```
Downloads a jar from a URL and makes it available as java\_import
Downloaded files must have a .jar extension.
Examples:
Suppose the current repository contains the source code for a chat program, rooted at the
directory `~/chat-app`. It needs to depend on an SSL library which is available from
`http://example.com/openssl-0.2.jar`.
Targets in the `~/chat-app` repository can depend on this target if the following lines are
added to `~/chat-app/WORKSPACE`:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
name = "my_ssl",
url = "http://example.com/openssl-0.2.jar",
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```
Targets would specify `@my_ssl//jar` as a dependency to depend on this jar.
You may also reference files on the current system (localhost) by using "file:///path/to/file"
if you are on Unix-based systems. If you're on Windows, use "file:///c:/path/to/file". In both
examples, note the three slashes (`/`) -- the first two slashes belong to `file://` and the third
one belongs to the absolute path to the file.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`auth_patterns`
[Dictionary: String -> String](https://bazel.build/rules/lib/dict); optional
An optional dict mapping host names to custom authorization patterns.
If a URL's host name is present in this dict the value will be used as a pattern when
generating the authorization header for the http request. This enables the use of custom
authorization schemes used in a lot of common cloud storage providers.
The pattern currently supports 2 tokens: `` and
``, which are replaced with their equivalent value
in the netrc file for the same host name. After formatting, the result is set
as the value for the `Authorization` field of the HTTP request.
Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token:
```
auth_patterns = {
"storage.cloudprovider.com": "Bearer "
}
```
netrc:
```
machine storage.cloudprovider.com
password RANDOM-TOKEN
```
The final HTTP request would have the following header:
```
Authorization: Bearer RANDOM-TOKEN
```
`canonical_id`
String; optional
A canonical ID of the file downloaded.
If specified and non-empty, Bazel will not take the file from cache, unless it
was added to the cache by a request with the same canonical ID.
If unspecified or empty, Bazel by default uses the URLs of the file as the
canonical ID. This helps catch the common mistake of updating the URLs without
also updating the hash, resulting in builds that succeed locally but fail on
machines without the file in the cache. This behavior can be disabled with
\--repo\_env=BAZEL\_HTTP\_RULES\_URLS\_AS\_DEFAULT\_CANONICAL\_ID=0.
`downloaded_file_name`
String; optional
Filename assigned to the jar downloaded
`integrity`
String; optional
Expected checksum in Subresource Integrity format of the file downloaded.
This must match the checksum of the file downloaded. *It is a security risk
to omit the checksum as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but either this attribute or `sha256` should be set before shipping.
`netrc`
String; optional
Location of the .netrc file to use for authentication
`sha256`
String; optional
The expected SHA-256 of the file downloaded.
This must match the SHA-256 of the file downloaded. *It is a security risk
to omit the SHA-256 as remote files can change.* At best omitting this
field will make your build non-hermetic. It is optional to make development
easier but either this attribute or `integrity` should be set before shipping.
`url`
String; optional
A URL to a file that will be made available to Bazel.
This must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
More flexibility can be achieved by the urls parameter that allows
to specify alternative URLs to fetch from.
The URL must end in `.jar`.
`urls`
List of strings; optional
A list of URLs to a file that will be made available to Bazel.
Each entry must be a file, http or https URL. Redirections are followed.
Authentication is not supported.
URLs are tried in order until one succeeds, so you should list local mirrors first.
If all downloads fail, the rule will fail.
All URLs must end in `.jar`.
**ENVIRONMENT VARIABLES**
This repository rule depends on the following environment variables:
* `BAZEL_HTTP_RULES_URLS_AS_DEFAULT_CANONICAL_ID`
# Repository Rules
Source: https://bazel.build/rules/lib/repo/index
* [Rules related to git](git)
* [Rules related to http](http)
* [Rules related to local directories](local)
# Generic functions for repository rule authors
* [Utility functions on patching](utils)
# local repository rules
Source: https://bazel.build/rules/lib/repo/local
The following functions can be loaded from
`@bazel_tools//tools/build_defs/repo:local.bzl`.
Rules for making directories in the local filesystem available as repos.
### Setup
To use these rules in a module extension, load them in your .bzl file and then call them from your
extension's implementation function. For example, to use `local_repository`:
```python theme={null}
load("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
def _my_extension_impl(mctx):
local_repository(name = "foo", path = "foo")
my_extension = module_extension(implementation = _my_extension_impl)
```
Alternatively, you can directly call these repo rules in your MODULE.bazel file with
`use_repo_rule`:
```python theme={null}
local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(name = "foo", path = "foo")
```
## local\_repository
```
load("@bazel//tools/build_defs/repo:local.bzl", "local_repository")
local_repository(name, path)
```
Makes a local directory that already contains Bazel files available as a repo. This directory should contain Bazel BUILD files and a repo boundary file already. If it doesn't contain these files, consider using [`new_local_repository`](#new_local_repository) instead.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`path`
String; required
The path to the directory to make available as a repo.
The path can be either absolute, or relative to the workspace root.
## new\_local\_repository
```
load("@bazel//tools/build_defs/repo:local.bzl", "new_local_repository")
new_local_repository(name, build_file, build_file_content, path)
```
Makes a local directory that doesn't contain Bazel files available as a repo. This directory need not contain Bazel BUILD files or a repo boundary file; they will be created by this repo rule. If the directory already contains Bazel files, consider using [`local_repository`](#local_repository) instead.
**ATTRIBUTES**
`name`
[Name](https://bazel.build/concepts/labels#target-names); required
A unique name for this repository.
`build_file`
[Label](https://bazel.build/concepts/labels); optional
A file to use as a BUILD file for this repo.
Exactly one of `build_file` and `build_file_content` must be specified.
The file addressed by this label does not need to be named BUILD, but can be. Something like `BUILD.new-repo-name` may work well to distinguish it from actual BUILD files.
`build_file_content`
String; optional
The content of the BUILD file to be created for this repo.
Exactly one of `build_file` and `build_file_content` must be specified.
`path`
String; required
The path to the directory to make available as a repo.
The path can be either absolute, or relative to the workspace root.
# utils repository rules
Source: https://bazel.build/rules/lib/repo/utils
The following functions can be loaded from
`@bazel_tools//tools/build_defs/repo:utils.bzl`.
Utils for manipulating external repositories, once fetched.
### Setup
These utilities are intended to be used by other repository rules. They
can be loaded as follows.
```python theme={null}
load(
"@bazel_tools//tools/build_defs/repo:utils.bzl",
"workspace_and_buildfile",
"patch",
"update_attrs",
)
```
## download\_remote\_files
```
load("@bazel//tools/build_defs/repo:utils.bzl", "download_remote_files")
download_remote_files(ctx, auth)
```
Utility function for downloading remote files.
This rule is intended to be used in the implementation function of
a repository rule. It assumes the parameters `remote_file_urls` and
`remote_file_integrity` to be present in `ctx.attr`.
Existing files will be overwritten.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
`auth`
optional.
default is `None`
An optional dict specifying authentication information for some of the URLs.
### Returns
dict mapping file paths to a download info.
## get\_auth
```
load("@bazel//tools/build_defs/repo:utils.bzl", "get_auth")
get_auth(ctx, urls)
```
Utility function to obtain the correct auth dict for a list of urls from .netrc file.
Support optional netrc and auth\_patterns attributes if available.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
`urls`
required.
the list of urls to read
### Returns
the auth dict which can be passed to repository\_ctx.download
## maybe
```
load("@bazel//tools/build_defs/repo:utils.bzl", "maybe")
maybe(repo_rule, name, **kwargs)
```
Utility function for only adding a repository if it's not already present.
This is to implement safe repositories.bzl macro documented in
[https://bazel.build/rules/deploying#dependencies](https://bazel.build/rules/deploying#dependencies).
### Parameters
`repo_rule`
required.
repository rule function.
`name`
required.
name of the repository to create.
`kwargs`
optional.
remaining arguments that are passed to the repo\_rule function.
### Returns
Nothing, defines the repository when needed as a side-effect.
## parse\_netrc
```
load("@bazel//tools/build_defs/repo:utils.bzl", "parse_netrc")
parse_netrc(contents, filename)
```
Utility function to parse at least a basic .netrc file.
### Parameters
`contents`
required.
input for the parser.
`filename`
optional.
default is `"a .netrc file"`
filename to use in error messages, if any.
### Returns
dict mapping a machine names to a dict with the information provided
about them
## patch
```
load("@bazel//tools/build_defs/repo:utils.bzl", "patch")
patch(ctx, patches, patch_cmds, patch_cmds_win, patch_tool, patch_args, auth, patch_directory)
```
Implementation of patching an already extracted repository.
This rule is intended to be used in the implementation function of
a repository rule. If the parameters `patches`, `patch_tool`,
`patch_args`, `patch_cmds`, `patch_cmds_win` and `patch_directory`
are not specified then they are taken from `ctx.attr`.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
`patches`
optional.
default is `None`
The patch files to apply. List of strings, Labels, or paths.
`patch_cmds`
optional.
default is `None`
Bash commands to run for patching, passed one at a
time to bash -c. List of strings
`patch_cmds_win`
optional.
default is `None`
Powershell commands to run for patching, passed
one at a time to powershell /c. List of strings. If the
boolean value of this parameter is false, patch\_cmds will be
used and this parameter will be ignored.
`patch_tool`
optional.
default is `None`
Path of the patch tool to execute for applying
patches. String.
`patch_args`
optional.
default is `None`
Arguments to pass to the patch tool. List of strings.
`auth`
optional.
default is `None`
An optional dict specifying authentication information for some of the URLs.
`patch_directory`
optional.
default is `None`
Directory relative to the repository root in which to
apply `patches` and run `patch_cmds`. Remote patches are always applied
at the repository root. Defaults to the repository root.
### Returns
dict mapping remote patch URLs to a download info.
## read\_netrc
```
load("@bazel//tools/build_defs/repo:utils.bzl", "read_netrc")
read_netrc(ctx, filename)
```
Utility function to parse at least a basic .netrc file.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
`filename`
required.
the name of the .netrc file to read
### Returns
dict mapping a machine names to a dict with the information provided
about them
## read\_user\_netrc
```
load("@bazel//tools/build_defs/repo:utils.bzl", "read_user_netrc")
read_user_netrc(ctx)
```
Read user's default netrc file.
If the `NETRC` environment variable is set to a non-empty value, the file it
names is read; as with `read_netrc`, it is an error if that file does not
exist. Otherwise, `.netrc` in the user's home directory (`$HOME`, or
`%USERPROFILE%` on Windows) is read if it exists.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility function.
### Returns
dict mapping a machine names to a dict with the information provided about them.
## symlink\_files
```
load("@bazel//tools/build_defs/repo:utils.bzl", "symlink_files")
symlink_files(ctx)
```
Utility function for symlinking local files.
This is intended to be used in the implementation function of a repository rule. It assumes the
parameter `files` is present in `ctx.attr`.
Existing files will be overwritten.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
## update\_attrs
```
load("@bazel//tools/build_defs/repo:utils.bzl", "update_attrs")
update_attrs(orig, keys, override)
```
Utility function for altering and adding the specified attributes to a particular repository rule invocation.
This is used to make a rule reproducible.
### Parameters
`orig`
required.
dict of actually set attributes (either explicitly or implicitly)
by a particular rule invocation
`keys`
required.
complete set of attributes defined on this rule
`override`
required.
dict of attributes to override or add to orig
### Returns
dict of attributes with the keys from override inserted/updated
## use\_netrc
```
load("@bazel//tools/build_defs/repo:utils.bzl", "use_netrc")
use_netrc(netrc, urls, patterns)
```
Compute an auth dict from a parsed netrc file and a list of URLs.
### Parameters
`netrc`
required.
a netrc file already parsed to a dict, e.g., as obtained from
read\_netrc
`urls`
required.
a list of URLs.
`patterns`
required.
optional dict of url to authorization patterns
### Returns
dict suitable as auth argument for ctx.download; more precisely, the dict
will map all URLs where the netrc file provides login and password to a
dict containing the corresponding login, password and optional authorization pattern,
as well as the mapping of "type" to "basic" or "pattern".
## workspace\_and\_buildfile
```
load("@bazel//tools/build_defs/repo:utils.bzl", "workspace_and_buildfile")
workspace_and_buildfile(ctx)
```
Utility function for writing a BUILD file.
This rule is intended to be used in the implementation function of a
repository rule.
It assumes the parameters `name`, `build_file`, and `build_file_content` to
be present in `ctx.attr`; the latter two possibly with value None.
### Parameters
`ctx`
required.
The repository context of the repository rule calling this utility
function.
# Top-level Modules
Source: https://bazel.build/rules/lib/toplevel
This section lists top-level modules. These symbols are available only in .bzl files.
* [apple\_common](/rules/lib/toplevel/apple_common)
* [attr](/rules/lib/toplevel/attr)
* [cc\_common](/rules/lib/toplevel/cc_common)
* [config](/rules/lib/toplevel/config)
* [config\_common](/rules/lib/toplevel/config_common)
* [coverage\_common](/rules/lib/toplevel/coverage_common)
* [java\_common](/rules/lib/toplevel/java_common)
* [native](/rules/lib/toplevel/native)
* [platform\_common](/rules/lib/toplevel/platform_common)
* [proto](/rules/lib/toplevel/proto)
* [testing](/rules/lib/toplevel/testing)
# apple_common
Source: https://bazel.build/rules/lib/toplevel/apple_common
Functions for Starlark to access internals of the apple rule implementations.
## Members
* [apple\_host\_system\_env](#apple_host_system_env)
* [apple\_toolchain](#apple_toolchain)
* [dotted\_version](#dotted_version)
* [platform](#platform)
* [platform\_type](#platform_type)
* [target\_apple\_env](#target_apple_env)
* [XcodeProperties](#XcodeProperties)
* [XcodeVersionConfig](#XcodeVersionConfig)
## apple\_host\_system\_env
```
dict apple_common.apple_host_system_env(xcode_config)
```
Returns a [dict](../core/dict) of environment variables that should be set for actions that need to run build tools on an Apple host system, such as the version of Xcode that should be used. The keys are variable names and the values are their corresponding values.
### Parameters
| Parameter | Description |
| - | - |
| `xcode_config` | required A provider containing information about the Xcode configuration. |
## apple\_toolchain
```
unknown apple_common.apple_toolchain()
```
Utilities for resolving items from the apple toolchain.
## dotted\_version
```
DottedVersion apple_common.dotted_version(version)
```
Creates a new [DottedVersion](../builtins/DottedVersion) instance.
### Parameters
| Parameter | Description |
| - | - |
| `version` | [string](../core/string); required The string representation of the DottedVersion. |
## platform
```
struct apple_common.platform
```
An enum-like struct that contains the following fields corresponding to Apple platforms:
* `ios_device`
* `ios_simulator`
* `macos`
* `tvos_device`
* `tvos_simulator`
* `visionos_device`
* `visionos_simulator`
* `watchos_device`
* `watchos_simulator`
These values can be passed to methods that expect a platform, like [XcodeVersionConfig.sdk\_version\_for\_platform](../providers/XcodeVersionConfig#sdk_version_for_platform).
## platform\_type
```
struct apple_common.platform_type
```
An enum-like struct that contains the following fields corresponding to Apple platform types:
* `ios`
* `macos`
* `tvos`
* `visionos`
* `watchos`
These values can be passed to methods that expect a platform type.
## target\_apple\_env
```
dict apple_common.target_apple_env(xcode_config, platform)
```
Returns a `dict` of environment variables that should be set for actions that build targets of the given Apple platform type. For example, this dictionary contains variables that denote the platform name and SDK version with which to build. The keys are variable names and the values are their corresponding values.
### Parameters
| Parameter | Description |
| - | - |
| `xcode_config` | required |
| `platform` | required |
## XcodeProperties
```
Provider apple_common.XcodeProperties
```
The constructor/key for the `XcodeVersionProperties` provider.
If a target propagates the `XcodeVersionProperties` provider, use this as the key with which to retrieve it. Example:
```
dep = ctx.attr.deps[0]
p = dep[apple_common.XcodeVersionProperties]
```
## XcodeVersionConfig
```
Provider apple_common.XcodeVersionConfig
```
The constructor/key for the `XcodeVersionConfig` provider.
# attr
Source: https://bazel.build/rules/lib/toplevel/attr
This is a top-level module for defining the attribute schemas of a rule or aspect. Each function returns an object representing the schema of a single attribute. These objects are used as the values of the `attrs` dictionary argument of [`rule()`](../globals/bzl#rule), [`aspect()`](../globals/bzl#aspect), [`repository_rule()`](../globals/bzl#repository_rule) and [`tag_class()`](../globals/bzl#tag_class).
See the Rules page for more on [defining](https://bazel.build/extending/rules#attributes)
and [using](https://bazel.build/extending/rules#implementation_function) attributes.
## Members
* [bool](#bool)
* [int](#int)
* [int\_list](#int_list)
* [label](#label)
* [label\_keyed\_string\_dict](#label_keyed_string_dict)
* [label\_list](#label_list)
* [label\_list\_dict](#label_list_dict)
* [output](#output)
* [output\_list](#output_list)
* [string](#string)
* [string\_dict](#string_dict)
* [string\_keyed\_label\_dict](#string_keyed_label_dict)
* [string\_list](#string_list)
* [string\_list\_dict](#string_list_dict)
## bool
```
Attribute attr.bool(*, configurable=unbound, default=False, doc=None, mandatory=False)
```
Creates a schema for a boolean attribute. The corresponding [`ctx.attr`](../builtins/ctx#attr) attribute will be of type [`bool`](../core/bool).
### Parameters
| Parameter | Description |
| - | - |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [bool](../core/bool); default is `False` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
## int
```
Attribute attr.int(*, configurable=unbound, default=0, doc=None, mandatory=False, values=[])
```
Creates a schema for an integer attribute. The value must be in the signed 32-bit range. The corresponding [`ctx.attr`](../builtins/ctx#attr) attribute will be of type [`int`](../core/int).
### Parameters
| Parameter | Description |
| - | - |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [int](../core/int); default is `0` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `values` | [sequence](../core/list) of [int](../core/int)s; default is `[]` The list of allowed values for the attribute. An error is raised if any other value is given. |
## int\_list
```
Attribute attr.int_list(mandatory=False, allow_empty=True, *, configurable=unbound, default=[], doc=None)
```
Creates a schema for a list-of-integers attribute. Each element must be in the signed 32-bit range.
### Parameters
| Parameter | Description |
| - | - |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [sequence](../core/list) of [int](../core/int)s; default is `[]` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
## label
```
Attribute attr.label(*, configurable=unbound, default=None, materializer=None, doc=None, executable=False, allow_files=None, allow_single_file=None, mandatory=False, skip_validations=False, providers=[], for_dependency_resolution=unbound, allow_rules=None, cfg=None, aspects=[], flags=[])
```
Creates a schema for a label attribute. This is a dependency attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time (within the rule's implementation function), when retrieving the attribute value from `ctx.attr`, labels are replaced by the corresponding [`Target`](../builtins/Target)s. This allows you to access the providers of the current target's dependencies.
In addition to ordinary source files, this kind of attribute is often used to refer to a tool -- for example, a compiler. Such tools are considered to be dependencies, just like source files. To avoid requiring users to specify the tool's label every time they use the rule in their BUILD files, you can hard-code the label of a canonical tool as the `default` value of this attribute. If you also want to prevent users from overriding this default, you can make the attribute private by giving it a name that starts with an underscore. See the [Rules](https://bazel.build/extending/rules#private-attributes) page for more information.
### Parameters
| Parameter | Description |
| - | - |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [Label](../builtins/Label); or [string](../core/string); or [LateBoundDefault](../builtins/LateBoundDefault); or NativeComputedDefault; or [function](../core/function); or `None`; default is `None` A default value to use if no value for this attribute is given when instantiating the rule.Use a string or the [`Label`](../builtins/Label#Label) function to specify a default value, for example, `attr.label(default = "//a:b")`. |
| `materializer` | [function](../core/function); default is `None` **Experimental**. This parameter is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--experimental_dormant_deps` If set, the attribute materializes dormant dependencies from the transitive closure. The value of this parameter must be a functon that gets access to the values of the attributes of the rule that either are not dependencies or are marked as available for dependency resolution. It must return either a dormant dependency or a list of them depending on the type of the attribute |
| `doc` | [string](../core/string); or `None`; default is `None` |
| `executable` | [bool](../core/bool); default is `False` True if the dependency has to be executable. This means the label must refer to an executable file, or to a rule that outputs an executable file. Access the label with `ctx.executable.`. |
| `allow_files` | [bool](../core/bool); or [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Whether `File` targets are allowed. Can be `True`, `False` (default), or a list of file extensions that are allowed (for example, `[".cc", ".cpp"]`). |
| `allow_single_file` | default is `None` This is similar to `allow_files`, with the restriction that the label must correspond to a single [File](../builtins/File). Access it through `ctx.file.`. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `skip_validations` | [bool](../core/bool); default is `False` If true, validation actions of transitive dependencies from this attribute will not run. This is a temporary mitigation and WILL be removed in the future. |
| `providers` | [sequence](../core/list); default is `[]` The providers that must be given by any dependency appearing in this attribute. The format of this argument is a list of lists of providers -- `*Info` objects returned by [`provider()`](../globals/bzl#provider) (or in the case of a legacy provider, its string name). The dependency must return ALL providers mentioned in at least ONE of the inner lists. As a convenience, this argument may also be a single-level list of providers, in which case it is wrapped in an outer list with one element (i.e. `[A, B]` means `[[A, B]]`). It is NOT required that the rule of the dependency advertises those providers in its `provides` parameter, however, it is considered best practice. |
| `for_dependency_resolution` | default is `unbound` If this is set, the attribute is available for materializers. Only rules marked with the flag of the same name are allowed to be referenced through such attributes. |
| `allow_rules` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Which rule targets (name of the classes) are allowed. This is deprecated (kept only for compatibility), use providers instead. |
| `cfg` | default is `None` [Configuration](https://bazel.build/extending/rules#configurations) of the attribute. It can be either `"exec"`, which indicates that the dependency is built for the `execution platform`, or `"target"`, which indicates that the dependency is build for the `target platform`. A typical example of the difference is when building mobile apps, where the `target platform` is `Android` or `iOS` while the `execution platform` is `Linux`, `macOS`, or `Windows`. This parameter is required if `executable` is True to guard against accidentally building host tools in the target configuration. `"target"` has no semantic effect, so don't set it when `executable` is False unless it really helps clarify your intentions. |
| `aspects` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` Aspects that should be applied to the dependency or dependencies specified by this attribute. |
| `flags` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Deprecated, will be removed. |
## label\_keyed\_string\_dict
```
Attribute attr.label_keyed_string_dict(allow_empty=True, *, configurable=unbound, default={}, doc=None, allow_files=None, allow_rules=None, providers=[], for_dependency_resolution=unbound, flags=[], mandatory=False, skip_validations=False, cfg=None, aspects=[])
```
Creates a schema for an attribute holding a dictionary, where the keys are labels and the values are strings. This is a dependency attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time (within the rule's implementation function), when retrieving the attribute value from `ctx.attr`, labels are replaced by the corresponding [`Target`](../builtins/Target)s. This allows you to access the providers of the current target's dependencies.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [dict](../core/dict); or [function](../core/function); default is `{}` A default value to use if no value for this attribute is given when instantiating the rule.Use strings or the [`Label`](../builtins/Label#Label) function to specify default values, for example, `attr.label_keyed_string_dict(default = {"//a:b": "value", "//a:c": "string"})`. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `allow_files` | [bool](../core/bool); or [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Whether `File` targets are allowed. Can be `True`, `False` (default), or a list of file extensions that are allowed (for example, `[".cc", ".cpp"]`). |
| `allow_rules` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Which rule targets (name of the classes) are allowed. This is deprecated (kept only for compatibility), use providers instead. |
| `providers` | [sequence](../core/list); default is `[]` The providers that must be given by any dependency appearing in this attribute. The format of this argument is a list of lists of providers -- `*Info` objects returned by [`provider()`](../globals/bzl#provider) (or in the case of a legacy provider, its string name). The dependency must return ALL providers mentioned in at least ONE of the inner lists. As a convenience, this argument may also be a single-level list of providers, in which case it is wrapped in an outer list with one element (i.e. `[A, B]` means `[[A, B]]`). It is NOT required that the rule of the dependency advertises those providers in its `provides` parameter, however, it is considered best practice. |
| `for_dependency_resolution` | default is `unbound` If this is set, the attribute is available for materializers. Only rules marked with the flag of the same name are allowed to be referenced through such attributes. |
| `flags` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Deprecated, will be removed. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `skip_validations` | [bool](../core/bool); default is `False` If true, validation actions of transitive dependencies from this attribute will not run. This is a temporary mitigation and WILL be removed in the future. |
| `cfg` | default is `None` [Configuration](https://bazel.build/extending/rules#configurations) of the attribute. It can be either `"exec"`, which indicates that the dependency is built for the `execution platform`, or `"target"`, which indicates that the dependency is build for the `target platform`. A typical example of the difference is when building mobile apps, where the `target platform` is `Android` or `iOS` while the `execution platform` is `Linux`, `macOS`, or `Windows`. |
| `aspects` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` Aspects that should be applied to the dependency or dependencies specified by this attribute. |
## label\_list
```
Attribute attr.label_list(allow_empty=True, *, configurable=unbound, default=[], materializer=None, doc=None, allow_files=None, allow_rules=None, providers=[], for_dependency_resolution=unbound, flags=[], mandatory=False, skip_validations=False, cfg=None, aspects=[])
```
Creates a schema for a list-of-labels attribute. This is a dependency attribute. The corresponding [`ctx.attr`](../builtins/ctx#attr) attribute will be of type [list](../core/list) of [`Target`s](../builtins/Target).
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time (within the rule's implementation function), when retrieving the attribute value from `ctx.attr`, labels are replaced by the corresponding [`Target`](../builtins/Target)s. This allows you to access the providers of the current target's dependencies.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [sequence](../core/list) of [Label](../builtins/Label)s; or [function](../core/function); default is `[]` A default value to use if no value for this attribute is given when instantiating the rule.Use strings or the [`Label`](../builtins/Label#Label) function to specify default values, for example, `attr.label_list(default = ["//a:b", "//a:c"])`. |
| `materializer` | [function](../core/function); default is `None` **Experimental**. This parameter is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--experimental_dormant_deps` If set, the attribute materializes dormant dependencies from the transitive closure. The value of this parameter must be a functon that gets access to the values of the attributes of the rule that either are not dependencies or are marked as available for dependency resolution. It must return either a dormant dependency or a list of them depending on the type of the attribute |
| `doc` | [string](../core/string); or `None`; default is `None` |
| `allow_files` | [bool](../core/bool); or [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Whether `File` targets are allowed. Can be `True`, `False` (default), or a list of file extensions that are allowed (for example, `[".cc", ".cpp"]`). |
| `allow_rules` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Which rule targets (name of the classes) are allowed. This is deprecated (kept only for compatibility), use providers instead. |
| `providers` | [sequence](../core/list); default is `[]` The providers that must be given by any dependency appearing in this attribute. The format of this argument is a list of lists of providers -- `*Info` objects returned by [`provider()`](../globals/bzl#provider) (or in the case of a legacy provider, its string name). The dependency must return ALL providers mentioned in at least ONE of the inner lists. As a convenience, this argument may also be a single-level list of providers, in which case it is wrapped in an outer list with one element (i.e. `[A, B]` means `[[A, B]]`). It is NOT required that the rule of the dependency advertises those providers in its `provides` parameter, however, it is considered best practice. |
| `for_dependency_resolution` | default is `unbound` If this is set, the attribute is available for materializers. Only rules marked with the flag of the same name are allowed to be referenced through such attributes. |
| `flags` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Deprecated, will be removed. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `skip_validations` | [bool](../core/bool); default is `False` If true, validation actions of transitive dependencies from this attribute will not run. This is a temporary mitigation and WILL be removed in the future. |
| `cfg` | default is `None` [Configuration](https://bazel.build/extending/rules#configurations) of the attribute. It can be either `"exec"`, which indicates that the dependency is built for the `execution platform`, or `"target"`, which indicates that the dependency is build for the `target platform`. A typical example of the difference is when building mobile apps, where the `target platform` is `Android` or `iOS` while the `execution platform` is `Linux`, `macOS`, or `Windows`. |
| `aspects` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` Aspects that should be applied to the dependency or dependencies specified by this attribute. |
## label\_list\_dict
```
Attribute attr.label_list_dict(allow_empty=True, *, configurable=unbound, default={}, doc=None, allow_files=None, allow_rules=None, providers=[], for_dependency_resolution=unbound, flags=[], mandatory=False, skip_validations=False, cfg=None, aspects=[])
```
Creates a schema for an attribute holding a dictionary, where the keys are strings and the values are list of labels. This is a dependency attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time (within the rule's implementation function), when retrieving the attribute value from `ctx.attr`, labels are replaced by the corresponding [`Target`](../builtins/Target)s. This allows you to access the providers of the current target's dependencies.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [dict](../core/dict); default is `{}` A default value to use if no value for this attribute is given when instantiating the rule.Use strings or the [`Label`](../builtins/Label#Label) function to specify default values, for example, `attr.label_list_dict(default = {"key1": ["//a:b", "//a:c"], "key2": [Label("@my_repo//d:e")]})`. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `allow_files` | [bool](../core/bool); or [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Whether `File` targets are allowed. Can be `True`, `False` (default), or a list of file extensions that are allowed (for example, `[".cc", ".cpp"]`). |
| `allow_rules` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Which rule targets (name of the classes) are allowed. This is deprecated (kept only for compatibility), use providers instead. |
| `providers` | [sequence](../core/list); default is `[]` The providers that must be given by any dependency appearing in this attribute. The format of this argument is a list of lists of providers -- `*Info` objects returned by [`provider()`](../globals/bzl#provider) (or in the case of a legacy provider, its string name). The dependency must return ALL providers mentioned in at least ONE of the inner lists. As a convenience, this argument may also be a single-level list of providers, in which case it is wrapped in an outer list with one element (i.e. `[A, B]` means `[[A, B]]`). It is NOT required that the rule of the dependency advertises those providers in its `provides` parameter, however, it is considered best practice. |
| `for_dependency_resolution` | default is `unbound` If this is set, the attribute is available for materializers. Only rules marked with the flag of the same name are allowed to be referenced through such attributes. |
| `flags` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Deprecated, will be removed. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `skip_validations` | [bool](../core/bool); default is `False` If true, validation actions of transitive dependencies from this attribute will not run. This is a temporary mitigation and WILL be removed in the future. |
| `cfg` | default is `None` [Configuration](https://bazel.build/extending/rules#configurations) of the attribute. It can be either `"exec"`, which indicates that the dependency is built for the `execution platform`, or `"target"`, which indicates that the dependency is build for the `target platform`. A typical example of the difference is when building mobile apps, where the `target platform` is `Android` or `iOS` while the `execution platform` is `Linux`, `macOS`, or `Windows`. |
| `aspects` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` Aspects that should be applied to the dependency or dependencies specified by this attribute. |
## output
```
Attribute attr.output(*, doc=None, mandatory=False)
```
Creates a schema for an output (label) attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time, the corresponding [`File`](../builtins/File) can be retrieved using [`ctx.outputs`](../builtins/ctx#outputs).
### Parameters
| Parameter | Description |
| - | - |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
## output\_list
```
Attribute attr.output_list(allow_empty=True, *, doc=None, mandatory=False)
```
Creates a schema for a list-of-outputs attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time, the corresponding [`File`](../builtins/File) can be retrieved using [`ctx.outputs`](../builtins/ctx#outputs).
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
## string
```
Attribute attr.string(*, configurable=unbound, default='', doc=None, mandatory=False, values=[])
```
Creates a schema for a [string](../core/string#attr) attribute.
### Parameters
| Parameter | Description |
| - | - |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [string](../core/string); or NativeComputedDefault; default is `''` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `values` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of allowed values for the attribute. An error is raised if any other value is given. |
## string\_dict
```
Attribute attr.string_dict(allow_empty=True, *, configurable=unbound, default={}, doc=None, mandatory=False)
```
Creates a schema for an attribute holding a dictionary, where the keys and values are strings.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [dict](../core/dict); default is `{}` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
## string\_keyed\_label\_dict
```
Attribute attr.string_keyed_label_dict(allow_empty=True, *, configurable=unbound, default={}, doc=None, allow_files=None, allow_rules=None, providers=[], for_dependency_resolution=unbound, flags=[], mandatory=False, cfg=None, aspects=[])
```
Creates a schema for an attribute whose value is a dictionary where the keys are strings and the values are labels. This is a dependency attribute.
This attribute contains unique [`Label`](../builtins/Label) values. If a string is supplied in place of a `Label`, it will be converted using the [label constructor](../builtins/Label#Label). The relative parts of the label path, including the (possibly renamed) repository, are resolved with respect to the instantiated target's package.
At analysis time (within the rule's implementation function), when retrieving the attribute value from `ctx.attr`, labels are replaced by the corresponding [`Target`](../builtins/Target)s. This allows you to access the providers of the current target's dependencies.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [dict](../core/dict); or [function](../core/function); default is `{}` A default value to use if no value for this attribute is given when instantiating the rule.Use strings or the [`Label`](../builtins/Label#Label) function to specify default values, for example, `attr.string_keyed_label_dict(default = {"foo": "//a:b", "bar": "//a:c"})`. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `allow_files` | [bool](../core/bool); or [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Whether `File` targets are allowed. Can be `True`, `False` (default), or a list of file extensions that are allowed (for example, `[".cc", ".cpp"]`). |
| `allow_rules` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Which rule targets (name of the classes) are allowed. This is deprecated (kept only for compatibility), use providers instead. |
| `providers` | [sequence](../core/list); default is `[]` The providers that must be given by any dependency appearing in this attribute. The format of this argument is a list of lists of providers -- `*Info` objects returned by [`provider()`](../globals/bzl#provider) (or in the case of a legacy provider, its string name). The dependency must return ALL providers mentioned in at least ONE of the inner lists. As a convenience, this argument may also be a single-level list of providers, in which case it is wrapped in an outer list with one element (i.e. `[A, B]` means `[[A, B]]`). It is NOT required that the rule of the dependency advertises those providers in its `provides` parameter, however, it is considered best practice. |
| `for_dependency_resolution` | default is `unbound` If this is set, the attribute is available for materializers. Only rules marked with the flag of the same name are allowed to be referenced through such attributes. |
| `flags` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Deprecated, will be removed. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `cfg` | default is `None` [Configuration](https://bazel.build/extending/rules#configurations) of the attribute. It can be either `"exec"`, which indicates that the dependency is built for the `execution platform`, or `"target"`, which indicates that the dependency is build for the `target platform`. A typical example of the difference is when building mobile apps, where the `target platform` is `Android` or `iOS` while the `execution platform` is `Linux`, `macOS`, or `Windows`. |
| `aspects` | [sequence](../core/list) of [Aspect](../builtins/Aspect)s; default is `[]` Aspects that should be applied to the dependency or dependencies specified by this attribute. |
## string\_list
```
Attribute attr.string_list(mandatory=False, allow_empty=True, *, configurable=unbound, default=[], doc=None)
```
Creates a schema for a list-of-strings attribute.
### Parameters
| Parameter | Description |
| - | - |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [sequence](../core/list) of [string](../core/string)s; or NativeComputedDefault; default is `[]` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
## string\_list\_dict
```
Attribute attr.string_list_dict(allow_empty=True, *, configurable=unbound, default={}, doc=None, mandatory=False)
```
Creates a schema for an attribute holding a dictionary, where the keys are strings and the values are lists of strings.
### Parameters
| Parameter | Description |
| - | - |
| `allow_empty` | [bool](../core/bool); default is `True` True if the attribute can be empty. |
| `configurable` | [bool](../core/bool); or unbound; default is `unbound` This argument can only be specified for an attribute of a symbolic macro. If `configurable` is explicitly set to `False`, the symbolic macro attribute is non-configurable - in other words, it cannot take a `select()` value. If the `configurable` is either unbound or explicitly set to `True`, the attribute is configurable and can take a `select()` value. For an attribute of a rule or aspect, `configurable` must be left unbound. Most Starlark rule attributes are always configurable, with the exception of `attr.output()`, `attr.output_list()`, and `attr.license()` rule attributes, which are always non-configurable. |
| `default` | [dict](../core/dict); default is `{}` A default value to use if no value for this attribute is given when instantiating the rule. |
| `doc` | [string](../core/string); or `None`; default is `None` A description of the attribute that can be extracted by documentation generating tools. |
| `mandatory` | [bool](../core/bool); default is `False` If true, the value must be specified explicitly (even if it has a `default`). |
# cc_common
Source: https://bazel.build/rules/lib/toplevel/cc_common
Utilities for C++ compilation, linking, and command line generation.
## Members
* [action\_is\_enabled](#action_is_enabled)
* [CcToolchainInfo](#CcToolchainInfo)
* [compile](#compile)
* [configure\_features](#configure_features)
* [create\_cc\_toolchain\_config\_info](#create_cc_toolchain_config_info)
* [create\_compilation\_context](#create_compilation_context)
* [create\_compilation\_outputs](#create_compilation_outputs)
* [create\_compile\_variables](#create_compile_variables)
* [create\_library\_to\_link](#create_library_to_link)
* [create\_link\_variables](#create_link_variables)
* [create\_linker\_input](#create_linker_input)
* [create\_linking\_context](#create_linking_context)
* [create\_linking\_context\_from\_compilation\_outputs](#create_linking_context_from_compilation_outputs)
* [create\_lto\_compilation\_context](#create_lto_compilation_context)
* [do\_not\_use\_tools\_cpp\_compiler\_present](#do_not_use_tools_cpp_compiler_present)
* [get\_environment\_variables](#get_environment_variables)
* [get\_execution\_requirements](#get_execution_requirements)
* [get\_memory\_inefficient\_command\_line](#get_memory_inefficient_command_line)
* [get\_tool\_for\_action](#get_tool_for_action)
* [is\_enabled](#is_enabled)
* [link](#link)
* [merge\_cc\_infos](#merge_cc_infos)
* [merge\_compilation\_contexts](#merge_compilation_contexts)
* [merge\_compilation\_outputs](#merge_compilation_outputs)
## action\_is\_enabled
```
bool cc_common.action_is_enabled(*, feature_configuration, action_name)
```
Returns True if given action\_config is enabled in the feature configuration.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `action_name` | [string](../core/string); required Name of the action\_config. |
## CcToolchainInfo
```
Provider cc_common.CcToolchainInfo
```
The key used to retrieve the provider that contains information about the C++ toolchain being used
## compile
```
tuple cc_common.compile(*, actions, feature_configuration, cc_toolchain, srcs=[], public_hdrs=[], private_hdrs=[], includes=[], local_includes=[], quote_includes=[], system_includes=[], framework_includes=[], defines=[], local_defines=[], include_prefix='', strip_include_prefix='', user_compile_flags=[], conly_flags=[], cxx_flags=[], compilation_contexts=[], progress_message_prefix, name, disallow_pic_outputs=False, disallow_nopic_outputs=False, additional_inputs=[], module_interfaces=unbound)
```
Should be used for C++ compilation. Returns tuple of (`CompilationContext`, `CcCompilationOutputs`).
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required `actions` object. |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required `feature_configuration` to be queried. |
| `cc_toolchain` | Info; required `CcToolchainInfo` provider to be used. |
| `srcs` | [sequence](../core/list); default is `[]` The list of source files to be compiled. |
| `public_hdrs` | [sequence](../core/list); default is `[]` List of headers needed for compilation of srcs and may be included by dependent rules transitively. |
| `private_hdrs` | [sequence](../core/list); default is `[]` List of headers needed for compilation of srcs and NOT to be included by dependent rules. |
| `includes` | [sequence](../core/list); or [depset](../builtins/depset); default is `[]` Search paths for header files referenced both by angle bracket and quotes. Usually passed with -I. Propagated to dependents transitively. |
| `local_includes` | [sequence](../core/list); or [depset](../builtins/depset); default is `[]` Search paths for header files referenced by angle brackets and quotes. Usually passed with -I. Not propagated to dependents transitively. |
| `quote_includes` | [sequence](../core/list); default is `[]` Search paths for header files referenced by quotes, e.g. #include "foo/bar/header.h". They can be either relative to the exec root or absolute. Usually passed with -iquote. Propagated to dependents transitively. |
| `system_includes` | [sequence](../core/list); default is `[]` Search paths for header files referenced by angle brackets, e.g. #include \. They can be either relative to the exec root or absolute. Usually passed with -isystem. Propagated to dependents transitively. |
| `framework_includes` | [sequence](../core/list); default is `[]` Search paths for header files from Apple frameworks. They can be either relative to the exec root or absolute. Usually passed with -F. Propagated to dependents transitively. |
| `defines` | [sequence](../core/list); default is `[]` Set of defines needed to compile this target. Each define is a string. Propagated to dependents transitively. |
| `local_defines` | [sequence](../core/list); default is `[]` Set of defines needed to compile this target. Each define is a string. Not propagated to dependents transitively. |
| `include_prefix` | [string](../core/string); default is `''` The prefix to add to the paths of the headers of this rule. When set, the headers in the hdrs attribute of this rule are accessible at is the value of this attribute prepended to their repository-relative path. The prefix in the strip\_include\_prefix attribute is removed before this prefix is added. |
| `strip_include_prefix` | [string](../core/string); default is `''` The prefix to strip from the paths of the headers of this rule. When set, the headers in the hdrs attribute of this rule are accessible at their path with this prefix cut off. If it's a relative path, it's taken as a package-relative one. If it's an absolute one, it's understood as a repository-relative path. The prefix in the include\_prefix attribute is added after this prefix is stripped. |
| `user_compile_flags` | [sequence](../core/list); default is `[]` Additional list of compilation options. |
| `conly_flags` | [sequence](../core/list); default is `[]` Additional list of compilation options for C compiles. |
| `cxx_flags` | [sequence](../core/list); default is `[]` Additional list of compilation options for C++ compiles. |
| `compilation_contexts` | [sequence](../core/list); default is `[]` Headers from dependencies used for compilation. |
| `progress_message_prefix` | [string](../core/string); or `None`; required An additional string to identify actions for logging. |
| `name` | [string](../core/string); required This is used for naming the output artifacts of actions created by this method. See also the `main_output` arg. |
| `disallow_pic_outputs` | [bool](../core/bool); default is `False` Whether PIC outputs should be created. |
| `disallow_nopic_outputs` | [bool](../core/bool); default is `False` Whether NOPIC outputs should be created. |
| `additional_inputs` | [sequence](../core/list); default is `[]` List of additional files needed for compilation of srcs |
| `module_interfaces` | [sequence](../core/list); default is `unbound` The list of module interfaces source files to be compiled. Note: this is an experimental feature, only enabled with --experimental\_cpp\_modules |
## configure\_features
```
FeatureConfiguration cc_common.configure_features(*, ctx, cc_toolchain, language=None, requested_features=[], unsupported_features=[])
```
Creates a feature\_configuration instance. Requires the cpp configuration fragment.
### Parameters
| Parameter | Description |
| - | - |
| `ctx` | [ctx](../builtins/ctx); required The rule context. |
| `cc_toolchain` | Info; required cc\_toolchain for which we configure features. |
| `language` | [string](../core/string); or `None`; default is `None` The language to configure for: either c++ or objc (default c++) |
| `requested_features` | [sequence](../core/list); default is `[]` List of features to be enabled. |
| `unsupported_features` | [sequence](../core/list); default is `[]` List of features that are unsupported by the current rule. |
## create\_cc\_toolchain\_config\_info
```
None cc_common.create_cc_toolchain_config_info(*, ctx, features=[], action_configs=[], artifact_name_patterns=[], cxx_builtin_include_directories=[], toolchain_identifier, host_system_name=None, target_system_name=None, target_cpu=None, target_libc=None, compiler, abi_version=None, abi_libc_version=None, tool_paths=[], make_variables=[], builtin_sysroot=None, disallowed_copts_infos=[])
```
Creates a `CcToolchainConfigInfo` provider
### Parameters
| Parameter | Description |
| - | - |
| `ctx` | [ctx](../builtins/ctx); required The rule context. |
| `features` | [sequence](../core/list); default is `[]` Contains all flag specifications for one feature. Arguments: `name`: The feature's name. It is possible to introduce a feature without a change to Bazel by adding a 'feature' section to the toolchain and adding the corresponding string as feature in the `BUILD` file. `enabled`: If 'True', this feature is enabled unless a rule type explicitly marks it as unsupported. `flag_sets`: A FlagSet list. If the given feature is enabled, the flag sets will be applied for the actions are specified for. `env_sets`: an EnvSet list. If the given feature is enabled, the env sets will be applied for the actions they are specified for. `requires`: A list of feature sets defining when this feature is supported by the toolchain. The feature is supported if any of the feature sets fully apply, that is, when all features of a feature set are enabled. If `requires` is omitted, the feature is supported independently of which other features are enabled. Use this for example to filter flags depending on the build mode enabled (opt / fastbuild / dbg). `implies`: A string list of features or action configs that are automatically enabled when this feature is enabled. If any of the implied features or action configs cannot be enabled, this feature will (silently) not be enabled either. `provides`: A list of names this feature conflicts with. A feature cannot be enabled if:- `provides` contains the name of a different feature or action config that we want to enable.- `provides` contains the same value as a 'provides' in a different feature or action config that we want to enable. Use this in order to ensure that incompatible features cannot be accidentally activated at the same time, leading to hard to diagnose compiler errors. |
| `action_configs` | [sequence](../core/list); default is `[]` An action config corresponds to a Bazel action, and allows selection of a tool based on activated features. Action config activation occurs by the same semantics as features: a feature can 'require' or 'imply' an action config in the same way that it would another feature. Arguments: `action_name`: The name of the Bazel action that this config applies to, e.g. 'c-compile' or 'c-module-compile'. `enabled`: If 'True', this action is enabled unless a rule type explicitly marks it as unsupported. `tools`: The tool applied to the action will be the first tool with a feature set that matches the feature configuration. An error will be thrown if no tool matches a provided feature configuration - for that reason, it's a good idea to provide a default tool with an empty feature set. `flag_sets`: If the given action config is enabled, the flag sets will be applied to the corresponding action. `implies`: A list of features or action configs that are automatically enabled when this action config is enabled. If any of the implied features or action configs cannot be enabled, this action config will (silently) not be enabled either. |
| `artifact_name_patterns` | [sequence](../core/list); default is `[]` The name for an artifact of a given category of input or output artifacts to an action. Arguments: `category_name`: The category of artifacts that this selection applies to. This field is compared against a list of categories defined in Bazel. Example categories include "linked\_output" or the artifact for this selection. Together with the extension it is used to create an artifact name based on the target name. `extension`: The extension for creating the artifact for this selection. Together with the prefix it is used to create an artifact name based on the target name. |
| `cxx_builtin_include_directories` | [sequence](../core/list); default is `[]` Built-in include directories for C++ compilation. These should be the exact paths used by the compiler, and are generally relative to the exec root. The paths used by the compiler can be determined by 'gcc -E -xc++ - -v'. We currently use the C++ paths also for C compilation, which is safe as long as there are no name clashes between C++ and C header files. Relative paths are resolved relative to the configuration file directory. If the compiler has --sysroot support, then these paths should use %sysroot% rather than the include path, and specify the sysroot attribute in order to give blaze the information necessary to make the correct replacements. |
| `toolchain_identifier` | [string](../core/string); required The unique identifier of the toolchain within the crosstool release. It must be possible to use this as a directory name in a path. It has to match the following regex: \[a-zA-Z\_]\[.- \w]\* |
| `host_system_name` | [string](../core/string); or `None`; default is `None` Ignored. |
| `target_system_name` | [string](../core/string); or `None`; default is `None` Deprecated. The GNU System Name. The string is exposed to CcToolchainInfo.target\_gnu\_system\_name. |
| `target_cpu` | [string](../core/string); or `None`; default is `None` Deprecated: Use cpu based constraints instead. If the string is "k8", `target_cpu` will be omitted from the filename of raw FDO profile data. |
| `target_libc` | [string](../core/string); or `None`; default is `None` Deprecated: Use OS based constraints instead. The libc version string (e.g. "glibc-2.2.2"). If the string is "macosx", platform is assumed to be MacOS. Otherwise, Linux. The string is exposed to CcToolchainInfo.libc. |
| `compiler` | [string](../core/string); required The compiler string (e.g. "gcc"). The current toolchain's compiler is exposed to `@bazel_tools//tools/cpp:compiler (compiler_flag)` as a flag value. Targets that require compiler-specific flags can use the config\_settings in [https://github.com/bazelbuild/rules\_cc/blob/main/cc/compiler/BUILD](https://github.com/bazelbuild/rules_cc/blob/main/cc/compiler/BUILD) in select() statements or create custom config\_setting if the existing settings don't suffice. |
| `abi_version` | [string](../core/string); or `None`; default is `None` The abi in use, which is a gcc version. E.g.: "gcc-3.4". The string is set to C++ toolchain variable ABI. |
| `abi_libc_version` | [string](../core/string); or `None`; default is `None` The glibc version used by the abi we're using. The string is set to C++ toolchain variable ABI\_LIBC\_VERSION. |
| `tool_paths` | [sequence](../core/list); default is `[]` Tool locations. Arguments: `name`: Name of the tool. `path`: Location of the tool; Can be absolute path (in case of non hermetic toolchain), or path relative to the cc\_toolchain's package. |
| `make_variables` | [sequence](../core/list); default is `[]` A make variable that is made accessible to rules. |
| `builtin_sysroot` | [string](../core/string); or `None`; default is `None` The built-in sysroot. If this attribute is not present, Bazel does not allow using a different sysroot, i.e. through the --grte\_top option. |
| `disallowed_copts_infos` | [sequence](../core/list); default is `[]` A list of disallowed\_copts\_info structs used for disallowed copts enforcement. |
## create\_compilation\_context
```
CompilationContext cc_common.create_compilation_context(*, headers=unbound, system_includes=unbound, includes=unbound, quote_includes=unbound, framework_includes=unbound, defines=unbound, local_defines=unbound)
```
Creates a `CompilationContext`.
### Parameters
| Parameter | Description |
| - | - |
| `headers` | default is `unbound` Set of headers needed to compile this target |
| `system_includes` | default is `unbound` Set of search paths for header files referenced by angle brackets, i.e. #include \. They can be either relative to the exec root or absolute. Usually passed with -isystem |
| `includes` | default is `unbound` Set of search paths for header files referenced both by angle bracket and quotes.Usually passed with -I |
| `quote_includes` | default is `unbound` Set of search paths for header files referenced by quotes, i.e. #include "foo/bar/header.h". They can be either relative to the exec root or absolute. Usually passed with -iquote |
| `framework_includes` | default is `unbound` Set of framework search paths for header files (Apple platform only) |
| `defines` | default is `unbound` Set of defines needed to compile this target. Each define is a string. Propagated transitively to dependents. |
| `local_defines` | default is `unbound` Set of defines needed to compile this target. Each define is a string. Not propagated transitively to dependents. |
## create\_compilation\_outputs
```
CcCompilationOutputs cc_common.create_compilation_outputs(*, objects=None, pic_objects=None)
```
Create compilation outputs object.
### Parameters
| Parameter | Description |
| - | - |
| `objects` | [depset](../builtins/depset); or `None`; default is `None` List of object files. |
| `pic_objects` | [depset](../builtins/depset); or `None`; default is `None` List of pic object files. |
## create\_compile\_variables
```
Variables cc_common.create_compile_variables(*, cc_toolchain, feature_configuration, source_file=None, output_file=None, user_compile_flags=None, include_directories=None, quote_include_directories=None, system_include_directories=None, framework_include_directories=None, preprocessor_defines=None, thinlto_index=None, thinlto_input_bitcode_file=None, thinlto_output_object_file=None, use_pic=False, add_legacy_cxx_options=False, variables_extension=unbound)
```
Returns variables used for compilation actions.
### Parameters
| Parameter | Description |
| - | - |
| `cc_toolchain` | Info; required cc\_toolchain for which we are creating build variables. |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `source_file` | [File](../builtins/File); or [string](../core/string); or `None`; default is `None` Optional source file path for the compilation. Please prefer passing source\_file here over appending it to the end of the command line generated from cc\_common.get\_memory\_inefficient\_command\_line, as then it's in the power of the toolchain author to properly specify and position compiler flags. |
| `output_file` | [File](../builtins/File); or [string](../core/string); or `None`; default is `None` Optional output file path of the compilation. Please prefer passing output\_file here over appending it to the end of the command line generated from cc\_common.get\_memory\_inefficient\_command\_line, as then it's in the power of the toolchain author to properly specify and position compiler flags. |
| `user_compile_flags` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` List of additional compilation flags (copts). |
| `include_directories` | [depset](../builtins/depset); or `None`; default is `None` Depset of include directories. |
| `quote_include_directories` | [depset](../builtins/depset); or `None`; default is `None` Depset of quote include directories. |
| `system_include_directories` | [depset](../builtins/depset); or `None`; default is `None` Depset of system include directories. |
| `framework_include_directories` | [depset](../builtins/depset); or `None`; default is `None` Depset of framework include directories. |
| `preprocessor_defines` | [depset](../builtins/depset); or `None`; default is `None` Depset of preprocessor defines. |
| `thinlto_index` | [string](../core/string); or `None`; default is `None` LTO index file path. |
| `thinlto_input_bitcode_file` | [string](../core/string); or `None`; default is `None` Bitcode file that is input to LTO backend. |
| `thinlto_output_object_file` | [string](../core/string); or `None`; default is `None` Object file that is output by LTO backend. |
| `use_pic` | [bool](../core/bool); default is `False` When true the compilation will generate position independent code. |
| `add_legacy_cxx_options` | [bool](../core/bool); default is `False` Unused. |
| `variables_extension` | [dict](../core/dict); default is `unbound` A dictionary of additional variables used by compile actions. |
## create\_library\_to\_link
```
LibraryToLink cc_common.create_library_to_link(*, actions, feature_configuration=None, cc_toolchain=None, static_library=None, pic_static_library=None, dynamic_library=None, interface_library=None, pic_objects=unbound, objects=unbound, alwayslink=False, dynamic_library_symlink_path='', interface_library_symlink_path='')
```
Creates `LibraryToLink`
### Parameters
| Parameter | Description |
| - | - |
| `actions` | required `actions` object. |
| `feature_configuration` | default is `None` `feature_configuration` to be queried. |
| `cc_toolchain` | default is `None` `CcToolchainInfo` provider to be used. |
| `static_library` | [File](../builtins/File); or `None`; default is `None` `File` of static library to be linked. |
| `pic_static_library` | [File](../builtins/File); or `None`; default is `None` `File` of pic static library to be linked. |
| `dynamic_library` | [File](../builtins/File); or `None`; default is `None` `File` of dynamic library to be linked. Always used for runtime and used for linking if `interface_library` is not passed. |
| `interface_library` | [File](../builtins/File); or `None`; default is `None` `File` of interface library to be linked. |
| `pic_objects` | [sequence](../core/list) of [File](../builtins/File)s; default is `unbound` Experimental, do not use |
| `objects` | [sequence](../core/list) of [File](../builtins/File)s; default is `unbound` Experimental, do not use |
| `alwayslink` | [bool](../core/bool); default is `False` Whether to link the static library/objects in the --whole\_archive block. |
| `dynamic_library_symlink_path` | [string](../core/string); default is `''` Override the default path of the dynamic library link in the solib directory. Empty string to use the default. |
| `interface_library_symlink_path` | [string](../core/string); default is `''` Override the default path of the interface library link in the solib directory. Empty string to use the default. |
## create\_link\_variables
```
Variables cc_common.create_link_variables(*, cc_toolchain, feature_configuration, library_search_directories=[], runtime_library_search_directories=[], user_link_flags=[], output_file=None, param_file=None, is_using_linker=True, is_linking_dynamic_library=False, must_keep_debug=True, use_test_only_flags=False, is_static_linking_mode=True)
```
Returns link variables used for linking actions.
### Parameters
| Parameter | Description |
| - | - |
| `cc_toolchain` | Info; required cc\_toolchain for which we are creating build variables. |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `library_search_directories` | [depset](../builtins/depset); default is `[]` Depset of directories where linker will look for libraries at link time. |
| `runtime_library_search_directories` | [depset](../builtins/depset); default is `[]` Depset of directories where loader will look for libraries at runtime. |
| `user_link_flags` | [sequence](../core/list); default is `[]` List of additional link flags (linkopts). |
| `output_file` | default is `None` Optional output file path. |
| `param_file` | default is `None` Optional param file path. |
| `is_using_linker` | [bool](../core/bool); default is `True` True when using linker, False when archiver. Caller is responsible for keeping this in sync with action name used (is\_using\_linker = True for linking executable or dynamic library, is\_using\_linker = False for archiving static library). |
| `is_linking_dynamic_library` | [bool](../core/bool); default is `False` True when creating dynamic library, False when executable or static library. Caller is responsible for keeping this in sync with action name used. This field will be removed once b/65151735 is fixed. |
| `must_keep_debug` | [bool](../core/bool); default is `True` When set to False, bazel will expose 'strip\_debug\_symbols' variable, which is usually used to use the linker to strip debug symbols from the output file. |
| `use_test_only_flags` | [bool](../core/bool); default is `False` When set to true, 'is\_cc\_test' variable will be set. |
| `is_static_linking_mode` | [bool](../core/bool); default is `True` Unused. |
## create\_linker\_input
```
LinkerInput cc_common.create_linker_input(*, owner, libraries=None, user_link_flags=None, additional_inputs=None)
```
Creates a `LinkerInput`.
### Parameters
| Parameter | Description |
| - | - |
| `owner` | [Label](../builtins/Label); required The label of the target that produced all files used in this input. |
| `libraries` | `None`; or [depset](../builtins/depset); default is `None` List of `LibraryToLink`. |
| `user_link_flags` | `None`; or [depset](../builtins/depset) of [string](../core/string)s; or [sequence](../core/list) of [string](../core/string)s; default is `None` User link flags passed as strings. Accepts either \[String], \[\[String]] or depset(String). The latter is discouraged as it's only kept for compatibility purposes, the depset is flattened. If you want to propagate user\_link\_flags via unflattened depsets() wrap them in a LinkerInput so that they are not flattened till the end. |
| `additional_inputs` | `None`; or [depset](../builtins/depset); default is `None` For additional inputs to the linking action, e.g.: linking scripts. |
## create\_linking\_context
```
LinkingContext cc_common.create_linking_context(*, linker_inputs)
```
Creates a `LinkingContext`.
### Parameters
| Parameter | Description |
| - | - |
| `linker_inputs` | [depset](../builtins/depset); required Depset of `LinkerInput`. |
## create\_linking\_context\_from\_compilation\_outputs
```
tuple cc_common.create_linking_context_from_compilation_outputs(*, actions, name, feature_configuration, cc_toolchain, language='c++', disallow_static_libraries=False, disallow_dynamic_library=False, compilation_outputs, linking_contexts=[], user_link_flags=[], alwayslink=False, additional_inputs=[], variables_extension=unbound)
```
Should be used for creating library rules that can propagate information downstream in order to be linked later by a top level rule that does transitive linking to create an executable or a dynamic library. Returns tuple of (`CcLinkingContext`, `CcLinkingOutputs`).
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required `actions` object. |
| `name` | [string](../core/string); required This is used for naming the output artifacts of actions created by this method. |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required `feature_configuration` to be queried. |
| `cc_toolchain` | Info; required `CcToolchainInfo` provider to be used. |
| `language` | [string](../core/string); default is `'c++'` Only C++ supported for now. Do not use this parameter. |
| `disallow_static_libraries` | [bool](../core/bool); default is `False` Whether static libraries should be created. |
| `disallow_dynamic_library` | [bool](../core/bool); default is `False` Whether a dynamic library should be created. |
| `compilation_outputs` | [CcCompilationOutputs](../builtins/CcCompilationOutputs); required Compilation outputs containing object files to link. |
| `linking_contexts` | [sequence](../core/list); default is `[]` Libraries from dependencies. These libraries will be linked into the output artifact of the link() call, be it a binary or a library. |
| `user_link_flags` | [sequence](../core/list); default is `[]` Additional list of linking options. |
| `alwayslink` | [bool](../core/bool); default is `False` Whether this library should always be linked. |
| `additional_inputs` | [sequence](../core/list); default is `[]` For additional inputs to the linking action, e.g.: linking scripts. |
| `variables_extension` | [dict](../core/dict); default is `unbound` Additional variables to pass to the toolchain configuration when creating link command line. |
## create\_lto\_compilation\_context
```
LtoCompilationContext cc_common.create_lto_compilation_context(*, objects={})
```
Create LTO compilation context
### Parameters
| Parameter | Description |
| - | - |
| `objects` | [dict](../core/dict); default is `{}` map of full object to index object |
## do\_not\_use\_tools\_cpp\_compiler\_present
```
None cc_common.do_not_use_tools_cpp_compiler_present
```
Do not use this field, its only purpose is to help with migration from config\_setting.values\{'compiler') to config\_settings.flag\_values\{'@bazel\_tools//tools/cpp:compiler'}
## get\_environment\_variables
```
dict cc_common.get_environment_variables(*, feature_configuration, action_name, variables)
```
Returns environment variables to be set for given action.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `action_name` | [string](../core/string); required Name of the action. Has to be one of the names in @bazel\_tools//tools/build\_defs/cc:action\_names.bzl ([https://github.com/bazelbuild/bazel/blob/master/tools/build\_defs/cc/action\_names.bzl](https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl)) |
| `variables` | Variables; required Build variables to be used for template expansion. |
## get\_execution\_requirements
```
sequence cc_common.get_execution_requirements(*, feature_configuration, action_name)
```
Returns execution requirements for given action.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `action_name` | [string](../core/string); required Name of the action. Has to be one of the names in @bazel\_tools//tools/build\_defs/cc:action\_names.bzl ([https://github.com/bazelbuild/bazel/blob/master/tools/build\_defs/cc/action\_names.bzl](https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl)) |
## get\_memory\_inefficient\_command\_line
```
sequence cc_common.get_memory_inefficient_command_line(*, feature_configuration, action_name, variables)
```
Returns flattened command line flags for given action, using given variables for expansion. Flattens nested sets and ideally should not be used, or at least should not outlive analysis. Work on memory efficient function returning Args is ongoing.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `action_name` | [string](../core/string); required Name of the action. Has to be one of the names in @bazel\_tools//tools/build\_defs/cc:action\_names.bzl ([https://github.com/bazelbuild/bazel/blob/master/tools/build\_defs/cc/action\_names.bzl](https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl)) |
| `variables` | Variables; required Build variables to be used for template expansions. |
## get\_tool\_for\_action
```
string cc_common.get_tool_for_action(*, feature_configuration, action_name)
```
Returns tool path for given action.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `action_name` | [string](../core/string); required Name of the action. Has to be one of the names in @bazel\_tools//tools/build\_defs/cc:action\_names.bzl ([https://github.com/bazelbuild/bazel/blob/master/tools/build\_defs/cc/action\_names.bzl](https://github.com/bazelbuild/bazel/blob/master/tools/build_defs/cc/action_names.bzl)) |
## is\_enabled
```
bool cc_common.is_enabled(*, feature_configuration, feature_name)
```
Returns True if given feature is enabled in the feature configuration.
### Parameters
| Parameter | Description |
| - | - |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required Feature configuration to be queried. |
| `feature_name` | [string](../core/string); required Name of the feature. |
## link
```
CcLinkingOutputs cc_common.link(*, actions, name, feature_configuration, cc_toolchain, language='c++', output_type='executable', link_deps_statically=True, compilation_outputs=None, linking_contexts=[], user_link_flags=[], stamp=0, additional_inputs=[], additional_outputs=[], variables_extension={})
```
Should be used for C++ transitive linking.
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required `actions` object. |
| `name` | [string](../core/string); required This is used for naming the output artifacts of actions created by this method. |
| `feature_configuration` | [FeatureConfiguration](../builtins/FeatureConfiguration); required `feature_configuration` to be queried. |
| `cc_toolchain` | Info; required `CcToolchainInfo` provider to be used. |
| `language` | [string](../core/string); default is `'c++'` Only C++ supported for now. Do not use this parameter. |
| `output_type` | [string](../core/string); default is `'executable'` Can be either 'executable' or 'dynamic\_library'. |
| `link_deps_statically` | [bool](../core/bool); default is `True` True to link dependencies statically, False dynamically. |
| `compilation_outputs` | [CcCompilationOutputs](../builtins/CcCompilationOutputs); or `None`; default is `None` Compilation outputs containing object files to link. |
| `linking_contexts` | [sequence](../core/list); default is `[]` Linking contexts from dependencies to be linked into the linking context generated by this rule. |
| `user_link_flags` | [sequence](../core/list); default is `[]` Additional list of linker options. |
| `stamp` | [int](../core/int); default is `0` Whether to include build information in the linked executable, if output\_type is 'executable'. If 1, build information is always included. If 0 (the default build information is always excluded. If -1, uses the default behavior, which may be overridden by the --\[no]stamp flag. This should be unset (or set to 0) when generating the executable output for test rules. |
| `additional_inputs` | [sequence](../core/list); or [depset](../builtins/depset); default is `[]` For additional inputs to the linking action, e.g.: linking scripts. |
| `additional_outputs` | [sequence](../core/list); default is `[]` For additional outputs to the linking action, e.g.: map files. |
| `variables_extension` | [dict](../core/dict); default is `{}` Additional variables to pass to the toolchain configuration when create link command line. |
## merge\_cc\_infos
```
unknown cc_common.merge_cc_infos(*, direct_cc_infos=[], cc_infos=[])
```
Merges multiple `CcInfo`s into one.
### Parameters
| Parameter | Description |
| - | - |
| `direct_cc_infos` | [sequence](../core/list); default is `[]` List of `CcInfo`s to be merged, whose headers will be exported by the direct fields in the returned provider. |
| `cc_infos` | [sequence](../core/list); default is `[]` List of `CcInfo`s to be merged, whose headers will not be exported by the direct fields in the returned provider. |
## merge\_compilation\_contexts
```
CompilationContext cc_common.merge_compilation_contexts(*, compilation_contexts=[])
```
Merges multiple `CompilationContexts`s into one.
### Parameters
| Parameter | Description |
| - | - |
| `compilation_contexts` | [sequence](../core/list); default is `[]` List of `CompilationContexts`s to be merged. The headers of each context will be exported by the direct fields in the returned provider. |
## merge\_compilation\_outputs
```
CcCompilationOutputs cc_common.merge_compilation_outputs(*, compilation_outputs=[])
```
Merge compilation outputs.
### Parameters
| Parameter | Description |
| - | - |
| `compilation_outputs` | [sequence](../core/list); default is `[]` |
# config
Source: https://bazel.build/rules/lib/toplevel/config
This is a top-level module for creating configuration transitions and build setting descriptors which describe what kind of build setting (if any) a rule is.
ex: the following rule is marked as a build setting by setting the `build_setting` parameter of the `rule()` function. Specifically it is a build setting of type `int` and is a `flag` which means this build setting is callable on the command line.
```
my_rule = rule(
implementation = _impl,
build_setting = config.int(flag = True),
...
)
```
## Members
* [bool](#bool)
* [exec](#exec)
* [int](#int)
* [none](#none)
* [string](#string)
* [string\_list](#string_list)
* [string\_set](#string_set)
* [target](#target)
## bool
```
BuildSetting config.bool(*, flag=False)
```
A bool-typed build setting
### Parameters
| Parameter | Description |
| - | - |
| `flag` | [bool](../core/bool); default is `False` |
## exec
```
ExecTransitionFactory config.exec(exec_group=None)
```
Creates an execution transition.
### Parameters
| Parameter | Description |
| - | - |
| `exec_group` | [string](../core/string); or `None`; default is `None` The name of the exec group whose execution platform this transition will use. If not provided, this exec transition will use the target's default execution platform. |
## int
```
BuildSetting config.int(*, flag=False)
```
An integer-typed build setting
### Parameters
| Parameter | Description |
| - | - |
| `flag` | [bool](../core/bool); default is `False` Whether or not this build setting is callable on the command line. |
## none
```
transition config.none()
```
Creates a transition which removes all configuration, unsetting all flags. Intended for the case where a dependency is data-only and contains no code that needs to be built, but should only be analyzed once.
## string
```
BuildSetting config.string(*, flag=False, allow_multiple=False)
```
A string-typed build setting
### Parameters
| Parameter | Description |
| - | - |
| `flag` | [bool](../core/bool); default is `False` Whether or not this build setting is callable on the command line. |
| `allow_multiple` | [bool](../core/bool); default is `False` Deprecated, use a `string_list` setting with `repeatable = True` instead. If set, this flag is allowed to be set multiple times on the command line. The Value of the flag as accessed in transitions and build setting implementation function will be a list of strings. Insertion order and repeated values are both maintained. This list can be post-processed in the build setting implementation function if different behavior is desired. |
## string\_list
```
BuildSetting config.string_list(*, flag=False, repeatable=False)
```
A string list-typed build setting. On the command line pass a list using comma-separated value like `--//my/setting=foo,bar`.
### Parameters
| Parameter | Description |
| - | - |
| `flag` | [bool](../core/bool); default is `False` Whether or not this build setting is callable on the command line. |
| `repeatable` | [bool](../core/bool); default is `False` If set, instead of expecting a comma-separated value, this flag is allowed to be set multiple times on the command line with each individual value treated as a single string to add to the list value. Insertion order and repeated values are both maintained. This list can be post-processed in the build setting implementation function if different behavior is desired. |
## string\_set
```
BuildSetting config.string_set(*, flag=False, repeatable=False)
```
A string set-typed build setting. The value of this setting will be a [set](https://bazel.build/rules/lib/core/set) of strings in Starlark. On the command line, pass a set using a comma-separated value like `--//my/setting=foo,bar`.
Unlike with a `string_list`, the order of the elements doesn't matter and only a single instance of each element is maintained. This is recommended over `string_list` for flags where these properties are not needed as it can improve build performance by avoiding unnecessary configurations forking.
### Parameters
| Parameter | Description |
| - | - |
| `flag` | [bool](../core/bool); default is `False` Whether or not this build setting is callable on the command line. |
| `repeatable` | [bool](../core/bool); default is `False` If set, instead of expecting a comma-separated value, this flag is allowed to be set multiple times on the command line with each individual value treated as a single string to add to the set value. Only a single instance of repeated values is maintained and the insertion order does not matter. |
## target
```
transition config.target()
```
Creates a target transition. This is a no-op transition intended for the case where a transition object is needed, but doesn't want to actually change anything. Equivalent to `cfg = "target"` in `attr.label()`.
# config_common
Source: https://bazel.build/rules/lib/toplevel/config_common
Functions for Starlark to interact with Blaze's configurability APIs.
## Members
* [FeatureFlagInfo](#FeatureFlagInfo)
* [toolchain\_type](#toolchain_type)
## FeatureFlagInfo
```
Provider config_common.FeatureFlagInfo
```
The key used to retrieve the provider containing config\_feature\_flag's value.
## toolchain\_type
```
toolchain_type config_common.toolchain_type(name, *, mandatory=True)
```
Declare a rule's dependency on a toolchain type.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); or [Label](../builtins/Label); required The toolchain type that is required. |
| `mandatory` | [bool](../core/bool); default is `True` Whether the toolchain type is mandatory or optional. |
# coverage_common
Source: https://bazel.build/rules/lib/toplevel/coverage_common
Helper functions to access coverage-related infrastructure.
## Members
* [instrumented\_files\_info](#instrumented_files_info)
## instrumented\_files\_info
```
InstrumentedFilesInfo coverage_common.instrumented_files_info(ctx, *, source_attributes=[], dependency_attributes=[], extensions=None, metadata_files=[], baseline_coverage_files=None)
```
Creates a new [InstrumentedFilesInfo](../providers/InstrumentedFilesInfo) instance. Use this provider to communicate coverage-related attributes of the current build rule.
### Parameters
| Parameter | Description |
| - | - |
| `ctx` | [ctx](../builtins/ctx); required The rule context. |
| `source_attributes` | [sequence](../core/list); default is `[]` A list of attribute names which contain source files processed by this rule. |
| `dependency_attributes` | [sequence](../core/list); default is `[]` A list of attribute names which might provide runtime dependencies (either code dependencies or runfiles). |
| `extensions` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` File extensions used to filter files from source\_attributes. For example, 'js'. If not provided (or None), then all files from source\_attributes will be added to instrumented files, if an empty list is provided, then no files from source attributes will be added. |
| `metadata_files` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` Additional files required to generate coverage LCOV files after code execution. e.g. .gcno files for C++. |
| `baseline_coverage_files` | [sequence](../core/list) of [File](../builtins/File)s; or `None`; default is `None` |
# java_common
Source: https://bazel.build/rules/lib/toplevel/java_common
Utilities for Java compilation support in Starlark.
## Members
* [BootClassPathInfo](#BootClassPathInfo)
* [compile](#compile)
* [JavaRuntimeInfo](#JavaRuntimeInfo)
* [JavaToolchainInfo](#JavaToolchainInfo)
* [merge](#merge)
* [pack\_sources](#pack_sources)
* [run\_ijar](#run_ijar)
* [stamp\_jar](#stamp_jar)
## BootClassPathInfo
```
Provider java_common.BootClassPathInfo
```
The provider used to supply bootclasspath information
## compile
```
JavaInfo java_common.compile(ctx, *, source_jars=[], source_files=[], output, output_source_jar=None, javac_opts=[], deps=[], runtime_deps=[], exports=[], plugins=[], exported_plugins=[], native_libraries=[], annotation_processor_additional_inputs=[], annotation_processor_additional_outputs=[], strict_deps='ERROR', java_toolchain, bootclasspath=None, sourcepath=[], resources=[], resource_jars=[], classpath_resources=[], neverlink=False, enable_annotation_processing=True, enable_compile_jar_action=True, add_exports=[], add_opens=[])
```
Compiles Java source files/jars from the implementation of a Starlark rule and returns a provider that represents the results of the compilation and can be added to the set of providers emitted by this rule.
### Parameters
| Parameter | Description |
| - | - |
| `ctx` | [ctx](../builtins/ctx); required The rule context. |
| `source_jars` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of the jars to be compiled. At least one of source\_jars or source\_files should be specified. |
| `source_files` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of the Java source files to be compiled. At least one of source\_jars or source\_files should be specified. |
| `output` | [File](../builtins/File); required |
| `output_source_jar` | [File](../builtins/File); or `None`; default is `None` The output source jar. Defaults to `{output_jar}-src.jar` if unset. |
| `javac_opts` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A list of the desired javac options. |
| `deps` | [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; default is `[]` A list of dependencies. |
| `runtime_deps` | [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; default is `[]` A list of runtime dependencies. |
| `exports` | [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; default is `[]` A list of exports. |
| `plugins` | [sequence](../core/list) of [JavaPluginInfo](../providers/JavaPluginInfo)s; or [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; default is `[]` A list of plugins. |
| `exported_plugins` | [sequence](../core/list) of [JavaPluginInfo](../providers/JavaPluginInfo)s; or [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; default is `[]` A list of exported plugins. |
| `native_libraries` | [sequence](../core/list) of [CcInfo](../providers/CcInfo)s; default is `[]` CC native library dependencies that are needed for this library. |
| `annotation_processor_additional_inputs` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of inputs that the Java compilation action will take in addition to the Java sources for annotation processing. |
| `annotation_processor_additional_outputs` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of outputs that the Java compilation action will output in addition to the class jar from annotation processing. |
| `strict_deps` | [string](../core/string); default is `'ERROR'` A string that specifies how to handle strict deps. Possible values: 'OFF', 'ERROR', 'WARN' and 'DEFAULT'. For more details see [`--strict_java_depsflag`](/docs/user-manual#flag--strict_java_deps). By default 'ERROR'. |
| `java_toolchain` | Info; required A JavaToolchainInfo to be used for this compilation. Mandatory. |
| `bootclasspath` | default is `None` A BootClassPathInfo to be used for this compilation. If present, overrides the bootclasspath associated with the provided java\_toolchain. |
| `sourcepath` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` |
| `resources` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` |
| `resource_jars` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` |
| `classpath_resources` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` |
| `neverlink` | [bool](../core/bool); default is `False` |
| `enable_annotation_processing` | [bool](../core/bool); default is `True` Disables annotation processing in this compilation, causing any annotation processors provided in plugins or in exported\_plugins of deps to be ignored. |
| `enable_compile_jar_action` | [bool](../core/bool); default is `True` Enables header compilation or ijar creation. If set to False, it forces use of the full class jar in the compilation classpaths of any dependants. Doing so is intended for use by non-library targets such as binaries that do not have dependants. |
| `add_exports` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Allow this library to access the given /. |
| `add_opens` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Allow this library to reflectively access the given /. |
## JavaRuntimeInfo
```
Provider java_common.JavaRuntimeInfo
```
The key used to retrieve the provider that contains information about the Java runtime being used.
## JavaToolchainInfo
```
Provider java_common.JavaToolchainInfo
```
The key used to retrieve the provider that contains information about the Java toolchain being used.
## merge
```
JavaInfo java_common.merge(providers)
```
Merges the given providers into a single JavaInfo.
### Parameters
| Parameter | Description |
| - | - |
| `providers` | [sequence](../core/list) of [JavaInfo](../providers/JavaInfo)s; required The list of providers to merge. |
## pack\_sources
```
File java_common.pack_sources(actions, *, output_source_jar=None, sources=[], source_jars=[], java_toolchain)
```
Packs sources and source jars into a single source jar file. The return value is typically passed to
`JavaInfo#source_jar`
.At least one of parameters output\_jar or output\_source\_jar is required.
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required ctx.actions |
| `output_source_jar` | [File](../builtins/File); or `None`; default is `None` The output source jar. |
| `sources` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of Java source files to be packed into the source jar. |
| `source_jars` | [sequence](../core/list) of [File](../builtins/File)s; default is `[]` A list of source jars to be packed into the source jar. |
| `java_toolchain` | Info; required A JavaToolchainInfo to used to find the ijar tool. |
## run\_ijar
```
File java_common.run_ijar(actions, *, jar, target_label=None, java_toolchain)
```
Runs ijar on a jar, stripping it of its method bodies. This helps reduce rebuilding of dependent jars during any recompiles consisting only of simple changes to method implementations. The return value is typically passed to `JavaInfo#compile_jar`.
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required ctx.actions |
| `jar` | [File](../builtins/File); required The jar to run ijar on. |
| `target_label` | [Label](../builtins/Label); or `None`; default is `None` A target label to stamp the jar with. Used for `add_dep` support. Typically, you would pass `ctx.label` to stamp the jar with the current rule's label. |
| `java_toolchain` | Info; required A JavaToolchainInfo to used to find the ijar tool. |
## stamp\_jar
```
File java_common.stamp_jar(actions, *, jar, target_label, java_toolchain)
```
Stamps a jar with a target label for `add_dep` support. The return value is typically passed to `JavaInfo#compile_jar`. Prefer to use `run_ijar` when possible.
### Parameters
| Parameter | Description |
| - | - |
| `actions` | [actions](../builtins/actions); required ctx.actions |
| `jar` | [File](../builtins/File); required The jar to run stamp\_jar on. |
| `target_label` | [Label](../builtins/Label); required A target label to stamp the jar with. Used for `add_dep` support. Typically, you would pass `ctx.label` to stamp the jar with the current rule's label. |
| `java_toolchain` | Info; required A JavaToolchainInfo to used to find the stamp\_jar tool. |
# native
Source: https://bazel.build/rules/lib/toplevel/native
A built-in module to support native rules and other package helper functions. All native rules appear as functions in this module, e.g. `native.cc_library`. Note that the native module is only available in the loading phase (i.e. for macros, not for rule implementations). Attributes will ignore `None` values, and treat them as if the attribute was unset.
The following functions are also available:
## Members
* [existing\_rule](#existing_rule)
* [existing\_rules](#existing_rules)
* [exports\_files](#exports_files)
* [glob](#glob)
* [module\_name](#module_name)
* [module\_version](#module_version)
* [package\_default\_visibility](#package_default_visibility)
* [package\_group](#package_group)
* [package\_name](#package_name)
* [package\_relative\_label](#package_relative_label)
* [repo\_name](#repo_name)
* [repository\_name](#repository_name)
* [subpackages](#subpackages)
## existing\_rule
```
unknown native.existing_rule(name)
```
Returns an immutable dict-like object that describes the attributes of a rule instantiated in this thread's package, or `None` if no rule instance of that name exists.
Here, an *immutable dict-like object* means a deeply immutable object `x` supporting dict-like iteration, `len(x)`, `name in x`, `x[name]`, `x.get(name)`, `x.items()`, `x.keys()`, and `x.values()`.
The result contains an entry for each attribute, with the exception of private ones (whose names do not start with a letter) and a few unrepresentable legacy attribute types. In addition, the dict contains entries for the rule instance's `name` and `kind` (for example, `'cc_binary'`).
The values of the result represent attribute values as follows:
* Attributes of type str, int, and bool are represented as is.
* Labels are converted to strings of the form `':foo'` for targets in the same package or `'//pkg:name'` for targets in a different package.
* Lists are represented as tuples, and dicts are converted to new, mutable dicts. Their elements are recursively converted in the same fashion.
* `select` values are returned with their contents transformed as described above.
* Attributes for which no value was specified during rule instantiation and whose default value is computed are excluded from the result. (Computed defaults cannot be computed until the analysis phase.).
If possible, use this function only in [implementation functions of rule finalizer symbolic macros](https://bazel.build/extending/macros#finalizers). Use of this function in other contexts is not recommened, and will be disabled in a future Bazel release; it makes `BUILD` files brittle and order-dependent. Also, beware that it differs subtly from the two other conversions of rule attribute values from internal form to Starlark: one used by computed defaults, the other used by `ctx.attr.foo`.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required |
## existing\_rules
```
unknown native.existing_rules()
```
Returns an immutable dict-like object describing the rules so far instantiated in this thread's package. Each entry of the dict-like object maps the name of the rule instance to the result that would be returned by `existing_rule(name)`.
Here, an *immutable dict-like object* means a deeply immutable object `x` supporting dict-like iteration, `len(x)`, `name in x`, `x[name]`, `x.get(name)`, `x.items()`, `x.keys()`, and `x.values()`.
If possible, use this function only in [implementation functions of rule finalizer symbolic macros](https://bazel.build/extending/macros#finalizers). Use of this function in other contexts is not recommened, and will be disabled in a future Bazel release; it makes `BUILD` files brittle and order-dependent.
## exports\_files
```
None native.exports_files(srcs, visibility=None, licenses=None)
```
Specifies a list of files belonging to this package that are exported to other packages.
### Parameters
| Parameter | Description |
| - | - |
| `srcs` | [sequence](../core/list) of [string](../core/string)s; required The list of files to export. |
| `visibility` | [sequence](../core/list); or `None`; default is `None` A visibility declaration can to be specified. The files will be visible to the targets specified. If no visibility is specified, the files will be visible to every package. |
| `licenses` | [sequence](../core/list) of [string](../core/string)s; or `None`; default is `None` Licenses to be specified. |
## glob
```
sequence native.glob(include=[], exclude=[], exclude_directories=1, allow_empty=unbound)
```
Glob returns a new, mutable, sorted list of every file in the current package that:
* Matches at least one pattern in `include`.
* Does not match any of the patterns in `exclude` (default `[]`).
If the `exclude_directories` argument is enabled (set to `1`), files of type directory will be omitted from the results (default `1`).
### Parameters
| Parameter | Description |
| - | - |
| `include` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to include. |
| `exclude` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to exclude. |
| `exclude_directories` | [int](../core/int); default is `1` A flag whether to exclude directories or not. |
| `allow_empty` | default is `unbound` Whether we allow glob patterns to match nothing. If `allow_empty` is False, each individual include pattern must match something and also the final result must be non-empty (after the matches of the `exclude` patterns are excluded). |
## module\_name
```
string native.module_name()
```
The name of the Bazel module associated with the repo this package is in. If this package is from a repo defined in WORKSPACE instead of MODULE.bazel, this is empty. For repos generated by module extensions, this is the name of the module hosting the extension. It's the same as the `module.name` field seen in `module_ctx.modules`.
May return `None`.
## module\_version
```
string native.module_version()
```
The version of the Bazel module associated with the repo this package is in. If this package is from a repo defined in WORKSPACE instead of MODULE.bazel, this is empty. For repos generated by module extensions, this is the version of the module hosting the extension. It's the same as the `module.version` field seen in `module_ctx.modules`.
May return `None`.
## package\_default\_visibility
```
List native.package_default_visibility()
```
Returns the default visibility of the package being evaluated. This is the value of the `default_visibility` parameter of `package()`, extended to include the package itself.
## package\_group
```
None native.package_group(*, name, packages=[], includes=[])
```
This function defines a set of packages and assigns a label to the group. The label can be referenced in `visibility` attributes.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required The unique name for this rule. |
| `packages` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A complete enumeration of packages in this group. |
| `includes` | [sequence](../core/list) of [string](../core/string)s; default is `[]` Other package groups that are included in this one. |
## package\_name
```
string native.package_name()
```
The name of the package being evaluated, without the repository name. For example, in the BUILD file `some/package/BUILD`, its value will be `some/package`. If the BUILD file calls a function defined in a .bzl file, `package_name()` will match the caller BUILD file package. The value will always be an empty string for the root package.
## package\_relative\_label
```
Label native.package_relative_label(input)
```
Converts the input string into a [Label](../builtins/Label) object, in the context of the package currently being initialized (that is, the `BUILD` file for which the current macro is executing). If the input is already a `Label`, it is returned unchanged.
This function may only be called while evaluating a BUILD file and the macros it directly or indirectly calls; it may not be called in (for instance) a rule implementation function.
The result of this function is the same `Label` value as would be produced by passing the given string to a label-valued attribute of a target declared in the BUILD file.
*Usage note:* The difference between this function and [`Label()`](../builtins/Label#Label) is that `Label()` uses the context of the package of the `.bzl` file that called it, not the package of the `BUILD` file. Use `Label()` when you need to refer to a fixed target that is hardcoded into the macro, such as a compiler. Use `package_relative_label()` when you need to normalize a label string supplied by the BUILD file to a `Label` object. (There is no way to convert a string to a `Label` in the context of a package other than the BUILD file or the calling .bzl file. For that reason, outer macros should always prefer to pass Label objects to inner macros rather than label strings.)[`ctx.package_relative_label()`](ctx#package_relative_label) provides the same functionality within a rule or aspect implementation function.
### Parameters
| Parameter | Description |
| - | - |
| `input` | [string](../core/string); or [Label](../builtins/Label); required The input label string or Label object. If a Label object is passed, it's returned as is. |
## repo\_name
```
string native.repo_name()
```
The canonical name of the repository containing the package currently being evaluated, with no leading at-signs.
## repository\_name
```
string native.repository_name()
```
**Experimental**. This API is experimental and may change at any time. Please do not depend on it. It may be enabled on an experimental basis by setting `--+incompatible_enable_deprecated_label_apis`
**Deprecated.** Prefer to use [`repo_name`](#repo_name) instead, which doesn't contain the spurious leading at-sign, but behaves identically otherwise.
The canonical name of the repository containing the package currently being evaluated, with a single at-sign (`@`) prefixed. For example, in packages that are called into existence by the WORKSPACE stanza `local_repository(name='local', path=...)` it will be set to `@local`. In packages in the main repository, it will be set to `@`.
## subpackages
```
sequence native.subpackages(*, include, exclude=[], allow_empty=False)
```
Returns a new mutable list of every direct subpackage of the current package, regardless of file-system directory depth. List returned is sorted and contains the names of subpackages relative to the current package. It is advised to prefer using the methods in bazel\_skylib.subpackages module rather than calling this function directly.
### Parameters
| Parameter | Description |
| - | - |
| `include` | [sequence](../core/list) of [string](../core/string)s; required |
| `exclude` | [sequence](../core/list) of [string](../core/string)s; default is `[]` The list of glob patterns to exclude from subpackages scan. |
| `allow_empty` | [bool](../core/bool); default is `False` Whether we fail if the call returns an empty list. By default empty list indicates potential error in BUILD file where the call to subpackages() is superflous. Setting to true allows this function to succeed in that case. |
# platform_common
Source: https://bazel.build/rules/lib/toplevel/platform_common
Functions for Starlark to interact with the platform APIs.
## Members
* [ConstraintSettingInfo](#ConstraintSettingInfo)
* [ConstraintValueInfo](#ConstraintValueInfo)
* [PlatformInfo](#PlatformInfo)
* [TemplateVariableInfo](#TemplateVariableInfo)
* [ToolchainInfo](#ToolchainInfo)
## ConstraintSettingInfo
```
Provider platform_common.ConstraintSettingInfo
```
The constructor/key for the [ConstraintSettingInfo](../providers/ConstraintSettingInfo) provider.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
## ConstraintValueInfo
```
Provider platform_common.ConstraintValueInfo
```
The constructor/key for the [ConstraintValueInfo](../providers/ConstraintValueInfo) provider.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
## PlatformInfo
```
Provider platform_common.PlatformInfo
```
The constructor/key for the [PlatformInfo](../providers/PlatformInfo) provider.
*Note: This API is experimental and may change at any time. It is disabled by default, but may be enabled with `--experimental_platforms_api`*
## TemplateVariableInfo
```
Provider platform_common.TemplateVariableInfo
```
The constructor/key for the [TemplateVariableInfo](../providers/TemplateVariableInfo) provider.
## ToolchainInfo
```
Provider platform_common.ToolchainInfo
```
The constructor/key for the [ToolchainInfo](../providers/ToolchainInfo) provider.
# proto
Source: https://bazel.build/rules/lib/toplevel/proto
A module for protocol message processing.
## Members
* [encode\_text](#encode_text)
## encode\_text
```
string proto.encode_text(x)
```
Returns the struct argument's encoding as a text-format protocol message.
The data structure must be recursively composed of strings, ints, floats, or bools, or structs, sequences, and dicts of these types.
A struct is converted to a message. Fields are emitted in name order.
Each struct field whose value is None is ignored.
A sequence (such as a list or tuple) is converted to a repeated field.
Its elements must not be sequences or dicts.
A dict is converted to a repeated field of messages with fields named 'key' and 'value'.
Entries are emitted in iteration (insertion) order.
The dict's keys must be strings or ints, and its values must not be sequences or dicts.
Examples:
```
proto.encode_text(struct(field=123))
# field: 123
proto.encode_text(struct(field=True))
# field: true
proto.encode_text(struct(field=[1, 2, 3]))
# field: 1
# field: 2
# field: 3
proto.encode_text(struct(field='text', ignored_field=None))
# field: "text"
proto.encode_text(struct(field=struct(inner_field='text', ignored_field=None)))
# field {
# inner_field: "text"
# }
proto.encode_text(struct(field=[struct(inner_field=1), struct(inner_field=2)]))
# field {
# inner_field: 1
# }
# field {
# inner_field: 2
# }
proto.encode_text(struct(field=struct(inner_field=struct(inner_inner_field='text'))))
# field {
# inner_field {
# inner_inner_field: "text"
# }
# }
proto.encode_text(struct(foo={4: 3, 2: 1}))
# foo: {
# key: 4
# value: 3
# }
# foo: {
# key: 2
# value: 1
# }
```
### Parameters
| Parameter | Description |
| - | - |
| `x` | structure; or StarlarkEncodable; required |
# testing
Source: https://bazel.build/rules/lib/toplevel/testing
Helper methods for Starlark to access testing infrastructure.
## Members
* [analysis\_test](#analysis_test)
* [ExecutionInfo](#ExecutionInfo)
* [TestEnvironment](#TestEnvironment)
## analysis\_test
```
None testing.analysis_test(name, implementation, attrs={}, fragments=[], toolchains=[], attr_values={})
```
Creates a new analysis test target.
The number of transitive dependencies of the test are limited. The limit is controlled by `--analysis_testing_deps_limit` flag.
### Parameters
| Parameter | Description |
| - | - |
| `name` | [string](../core/string); required Name of the target. It should be a Starlark identifier, matching pattern '\[A-Za-z\_]\[A-Za-z0-9\_]\*'. |
| `implementation` | [function](../core/function); required The Starlark function implementing this analysis test. It must have exactly one parameter: [ctx](../builtins/ctx). The function is called during the analysis phase. It can access the attributes declared by `attrs` and populated via `attr_values`. The implementation function may not register actions. Instead, it must register a pass/fail result via providing [AnalysisTestResultInfo](../providers/AnalysisTestResultInfo). |
| `attrs` | [dict](../core/dict); default is `{}` Dictionary declaring the attributes. See the [rule](../globals/bzl#rule) call. Attributes are allowed to use configuration transitions defined using [analysis\_test\_transition](../globals/bzl#analysis_test_transition). |
| `fragments` | [sequence](../core/list) of [string](../core/string)s; default is `[]` List of configuration fragments that are available to the implementation of the analysis test. |
| `toolchains` | [sequence](../core/list); default is `[]` The set of toolchains the test requires. See the [rule](../globals/bzl#rule) call. |
| `attr_values` | [dict](../core/dict) of [string](../core/string)s; default is `{}` Dictionary of attribute values to pass to the implementation. |
## ExecutionInfo
```
ExecutionInfo testing.ExecutionInfo
```
[testing.ExecutionInfo](../providers/ExecutionInfo) provider key/constructor
## TestEnvironment
```
RunEnvironmentInfo testing.TestEnvironment(environment, inherited_environment=[])
```
**Deprecated: Use RunEnvironmentInfo instead.** Creates a new test environment provider. Use this provider to specify extra environment variables to be made available during test execution.
### Parameters
| Parameter | Description |
| - | - |
| `environment` | [dict](../core/dict); required A map of string keys and values that represent environment variables and their values. These will be made available during the test execution. |
| `inherited_environment` | [sequence](../core/list) of [string](../core/string)s; default is `[]` A sequence of names of environment variables. These variables are made available during the test execution with their current value taken from the shell environment. If a variable is contained in both `environment` and `inherited_environment`, the value inherited from the shell environment will take precedence if set. |
# Bazel Brand Guidelines
Source: https://bazel.build/brand/index
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
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
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
* 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
[product@bazel.build](mailto:product@bazel.build).
## Usage for Events and Community Groups
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 [product@bazel.build](mailto:product@bazel.build).
Examples of naming conventions that require prior written permission:
* BazelCon
* Bazel Conference
## Contact Us
Please do not hesitate to contact us at
[product@bazel.build](mailto:product@bazel.build) 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.
# Bazel Community Experts
Source: https://bazel.build/community/experts
Companies who have contributed significantly to the Bazel community and can help with your project
***
> **[Aspect Build](https://www.aspect.build/services)**
>
> Leveraging the insights we gathered from helping over 50 companies to navigate Bazel, we developed Aspect Workflows, our Developer Platform for Bazel Monorepos. Our platform is designed to enhance the developer experience with Bazel, notably accelerating build times on CI while reducing compute costs. Aspect Workflows seamlessly integrates with your existing CI and cloud infrastructure, while aligning with your current configuration. This approach empowers users to concentrate on innovating and delivering exceptional products, while we manage the underlying infrastructure and ensure CI stays fast. Aspect offers consulting, support, and training to help your team succeed with Bazel and we are the authors and maintainers of the canonical open-source rulesets for JavaScript and OCI images.
> **[Bitrise](https://bitrise.io/why/features/mobile-build-caching-for-better-build-test-performance)**
>
> Bitrise is the world’s leading mobile-first CI/CD Platform. Our Bitrise Build Cache & CDN product enables enterprises and high-growth organizations to optimize and elevate their Bazel projects. Bitrise brings to market an uncontested build and test caching solution available nowhere else. The first of its kind, fully managed by Bitrise requiring no setup or maintenance, you can use our out-of-the-box cache Steps to enjoy a deeply integrated CI/CD & Bazel experience or integrate our cache directly into your builds on any other platform.
> **[BuildBuddy](https://www.buildbuddy.io/)**
>
> BuildBuddy provides an open-core suite of enterprise features for Bazel. Included are a Remote Build Execution service, a shared build artifact cache, and a build result UI. It's available as a fully-managed cloud service or as an easy to deploy on-prem solution. The service is free to use for individuals and open-source projects. BuildBuddy is based in San Francisco, backed by Y Combinator, and founded by two ex-Googlers deeply passionate about making developers more productive.
> **[Codethink](https://www.codethink.co.uk/)**
>
> Codethink is an Open Source software consultancy providing development, integration, test automation and whole-of-life maintenance services for advanced software on production embedded devices and cloud infrastructure. Codethink works with international-scale organisations exploiting Bazel and remote execution solutions to increase continuous delivery productivity and throughput.
> **[EngFlow](https://www.engflow.com/)**
>
> EngFlow helps companies accelerate builds for Bazel, Goma, and Android Platform. Builds, tests and CI are typically 5 to 10x faster when using EngFlow’s remote build execution, caching, and build results UI. Customers also benefit from the company’s unparalleled Bazel expertise. Created by the engineer who led the development of Bazel, EngFlow upstreams Bazel changes in the interest of customers, and has partnerships with other Bazel experts.
> **[EPAM](https://www.epam.com/)**
>
> Since 1993 EPAM has leveraged its ‘Engineering DNA’ to become a leading global product development, digital platform engineering, and top digital and product design agency. Due to its tight partnership with Google, EPAM has extensive Bazel expertise and is ready to assess readiness and perform complex migration to Bazel in order to streamline development and CI/CD processes for any technology and complexity including custom rules and tools development, remote cache and execution setup.
> **[SUM Global](http://sumglobal.com/bazel-build)**
>
> SUM Global Technology is an IT consulting firm. We help create high performance CI/CD build infrastructures. Combining decades of build domain knowledge with a deep technical expertise using Bazel, SUM Global works with your organization to create and enhance the software delivery process. We specialize in Java, Android and Angular builds as well as conversions from other tools. We can help with Google Remote Build Execution.
> **[Tweag](https://www.tweag.io/)**
>
> Tweag I/O is one of Bazel's earliest adopters, an active contributor of new features and new open source extensions since early 2018. Our specialty: partner with you to help you achieve near byte-for-byte reproducibility, fully traceable all the way to production and conveniently auditable builds that can be cached correctly and run fast. Tweag engineers combine extensive knowledge of Bazel with a capacity for deep technical understanding of your architecture, because no two builds are the same. We get you ready for Bazel with our Bazel Readiness Assessment, perform migrations, and improve existing setups.
# Bazel Product Partners
Source: https://bazel.build/community/partners
We categorize Bazel product partners as organizations that build open source or paid tooling that interfaces with Bazel. These tools aim to improve Bazel end user experience and accelerate developer productivity.
Interested organizations can write to [product@bazel.build](mailto:product@bazel.build) to get added to the product partnership program.
***
> **[Aspect Build](https://www.aspect.build/)**
>
> Leveraging the insights we gathered from helping over 50 companies to navigate Bazel, we developed Aspect Workflows, our Developer Platform for Bazel Monorepos. Our platform is designed to enhance the developer experience with Bazel, notably accelerating build times on CI while reducing compute costs. Aspect Workflows seamlessly integrates with your existing CI and cloud infrastructure, while aligning with your current configuration. This approach empowers users to concentrate on innovating and delivering exceptional products, while we manage the underlying infrastructure and ensure CI stays fast. Aspect offers consulting, support, and training to help your team succeed with Bazel and we are the authors and maintainers of the canonical open-source rulesets for JavaScript and OCI images.
> **[Bitrise](https://bitrise.io/why/features/mobile-build-caching-for-better-build-test-performance)**
>
> Bitrise Inc. is the world’s leading mobile-first CI/CD Platform. Our Bitrise Build Cache & CDN product enables enterprises and high-growth organizations to optimize and elevate their Bazel projects. Bitrise brings to market an uncontested build and test caching solution available nowhere else. The first of its kind, fully managed by Bitrise requiring no setup or maintenance, you can use our out-of-the-box cache Steps to enjoy a deeply integrated CI/CD & Bazel experience or integrate our cache directly into your builds on any other platform..
> **[BuildBuddy](https://www.buildbuddy.io/)**
>
> BuildBuddy provides an open-core suite of enterprise features for Bazel. Included are a Remote Build Execution service, a shared build cache, Bazel-optimized CI workflows, and a build & test result UI for debugging and analytics.It's available as a fully-managed cloud service or as an easy to deploy on-prem solution. The service is free to use for small teams and open-source projects. BuildBuddy is based in San Francisco, backed by Y Combinator, and founded by two ex-Googlers deeply passionate about making developers more productive.
> **[EngFlow](https://www.engflow.com/product/demo)**
>
> EngFlow is the build and test acceleration company created by core Bazel engineers and funded by Andreessen Horowitz. EngFlow’s secure (audited: SOC 2 type 2) remote execution, caching, and observability platform scales from 1 to 100,000+ cores, reduces time by 5-10x and cloud costs by 20-50%. Whether deployed on your cloud or on EngFlow’s: our global Bazel experts provide 24x7 coverage, support small and large teams, no hidden costs, and SSO included.
> **[Gradle Inc.](https://gradle.com/gradle-enterprise-solutions/bazel-build-system/)**
>
> Develocity is a multi-build-system platform for improving developer productivity and happiness. It does this by providing a comprehensive and end-to-end solution for build & test observability, acceleration, and failure analytics, and currently supports the Bazel, Apache Maven, Gradle, and SBT build systems. Specifically, Develocity for Bazel supports Build Cache to speed up build and test feedback cycles; Build Scan® that is like an X-ray for your build to make troubleshooting more efficient; and Failure Analytics to improve toolchain reliability.
> **[JetBrains](https://www.jetbrains.com/help/idea/bazel.html)**
>
> JetBrains is a leading provider of IDEs and developer tools. Since 2022, we’ve been active in the Bazel community, delivering robust polyglot support through plugins for CLion, GoLand, PyCharm, and IntelliJ IDEA. These plugins provide deep Bazel integration for large projects, enabling editing, navigation, testing, and debugging across multiple languages, including C++, Go, Python, Java, Kotlin, Scala, as well as Starlark and other configuration files.
> **[Tweag](https://www.tweag.io/group/scalable-builds/)**
>
> Tweag is one of Bazel’s earliest adopters, an active contributor of new features and new open source extensions since early 2018. We have been helping companies and teams achieve near byte-for-byte reproducibility, fully traceable all the way to production and conveniently auditable builds that can be cached correctly and run fast. Besides our consulting work, we also have an array of tools and extensions. Skyscope to visualize and explore complex Bazel build graphs with hundreds of thousands of nodes in your web browser. Open source Bazel extensions to achieve fully reproducible builds with the power of Nix, manage shell tools in a principled way, and build Haskell projects with Bazel. Finally, our open source Gazelle extensions to automate your Bazel migration and build maintenance.
> **[Nativelink](https://www.nativelink.com/)**
>
> NativeLink is the 100% free, open source, and permissively licensed build and test acceleration project written in Rust. It is created by a team of open source maintainers and the company is funded by Wellington Management, an asset manager with over one trillion dollars under management. Whether deployed on your infrastructure or on NativeLink’s cloud, our global Bazel, Reclient, and compiler experts provide 24x7 coverage, support small and large teams, and SSO included.
> **[VirtusLab](https://virtuslab.com/expertise/monorepo-expertise-with-bazel/)**
>
> VirtusLab specializes in managing monorepos and migrating codebases to Bazel. We offer a smooth transition that enhances your software’s creation, testing, and release processes. Our engineers will assist you in adopting industry-standard tooling and practices, including top-tier security measures. We believe that a seamless Developer Experience requires great tooling. By partnering with us, you will optimize build times, reduce costs, and empower your development teams to reach their peak performance.
> **[Buildkite](https://buildkite.com/)**
>
> Based in San Francisco and Sydney, Buildkite is a fast-growing software delivery provider that offers the industry’s first and only Scale-Out Delivery Platform. Buildkite’s Scale-Out Delivery platform is the only solution that provides the flexibility and scale required by the world’s most demanding companies for delivering software across a broad range of use cases, including AI/ML workloads and mobile application development. Global innovation leaders including Airbnb, Block, Canva, Cruise, Culture Amp, Elastic, Lyft, PagerDuty, Pinterest, PlanetScale, Rippling, Shopify, Slack, Tinder, Twilio, Uber, and Wayfair have standardized on Buildkite for software delivery. Buildkite delivers seamless Bazel integration, enabling teams to scale CI/CD for complex monorepos. Buildkite sponsors CI for the Bazel project as part of its commitment to developers, driving faster builds and broader adoption.
> **[Hermetiq](https://www.hermetiq.com/)**
>
> Hermetiq is the intelligence platform for Bazel, built for the era of agentic software development. Hermetiq delivers deep observability and analytics across cache performance, remote execution, and build failures — and exposes Bazel build data directly to AI agents via MCP so that you can ask any question about your builds directly to your AI Agent (Claude, Codex, etc) and get answers instantly. Backed by LAUNCH. Available as a cloud service or self-hosted deployment.
> **[Trunk](https://trunk.io)**
>
> Trunk is the developer experience platform for engineering teams working in large, shared codebases. Trunk keeps main green and engineers unblocked with two deeply integrated products: a parallel Merge Queue that reads Bazel build metadata to test non-overlapping changes simultaneously and batch them into a single CI run, and Flaky Tests, which automatically detects and quarantines flaky tests from Bazel test results without changing test code. Teams like Brex, Faire, Zillow, and Chainlink use Trunk to cut merge times and reclaim engineering hours lost to CI babysitting. Available as a cloud service or self-hosted.
# Recommended Rules
Source: https://bazel.build/community/recommended-rules
In the documentation, we provide a list of
[recommended rules](/rules).
This is a set of high quality rules, which will provide a good experience to our
users. We make a distinction between the supported rules, and the hundreds of
rules you can find on the Internet.
## Nomination
If a ruleset meets the requirements below, a rule maintainer can nominate it
to be part of the *recommended rules* by filing a
[GitHub issue](https://github.com/bazelbuild/bazel/).
After a review by the [Bazel core team](/contribute/policy), it
will be recommended on the Bazel website.
## Requirements for the rule maintainers
* The ruleset provides an important feature, useful to a large number of Bazel
users (for example, support for a widely popular language).
* The ruleset is well maintained. There must be at least two active maintainers.
* The ruleset is well documented, with examples, and easy to use.
* The ruleset follows the best practices and is performant (see
[the performance guide](/rules/performance)).
* The ruleset has sufficient test coverage.
* The ruleset is tested on
[BuildKite](https://github.com/bazelbuild/continuous-integration/blob/master/buildkite/README.md)
with the latest version of Bazel. Tests should always pass (when used as a
presubmit check).
* The ruleset is also tested with the upcoming incompatible changes. Breakages
should be fixed within two weeks. Migration issues should be reported to the
Bazel team quickly.
## Requirements for Bazel developers
* Recommended rules are frequently tested with Bazel at head (at least once a
day).
* No change in Bazel may break a recommended rule (with the default set of
flags). If it happens, the change should be fixed or rolled back.
## Demotion
If there is a concern that a particular ruleset is no longer meeting the
requirements, a [GitHub issue](https://github.com/bazelbuild/bazel/) should be
filed.
Rule maintainers will be contacted and need to respond in 2 weeks. Based on the
outcome, Bazel core team might make a decision to demote the rule set.
# Remote Execution Services
Source: https://bazel.build/community/remote-execution-services
Use the following services to run Bazel with remote execution:
* Manual
* Use the [gRPC protocol](https://github.com/bazelbuild/remote-apis)
directly to create your own remote execution service.
* Self-service
* [Buildbarn](https://github.com/buildbarn)
* [Buildfarm](https://github.com/bazelbuild/bazel-buildfarm)
* [BuildGrid](https://gitlab.com/BuildGrid/buildgrid)
* [NativeLink](https://github.com/TraceMachina/nativelink)
* Commercial
* [Aspect Build](https://www.aspect.build/) – Self-hosted remote cache and remote execution services.
* [Bitrise](https://bitrise.io/why/features/mobile-build-caching-for-better-build-test-performance) - Providing the world's leading mobile-first CI/CD and remote build caching platform.
* [BuildBuddy](https://www.buildbuddy.io) - Remote build execution,
caching, and results UI.
* [EngFlow Remote Execution](https://www.engflow.com) - Remote execution
and remote caching service with Build and Test UI. Can be self-hosted or hosted.
* [Hermetiq](https://www.hermetiq.com) - Build analytics, managed remote cache and remote execution with cache miss debugging, RBE cost tracking, and infrastructure telemetry.
* [NativeLink](https://github.com/TraceMachina/nativelink) - Remote build execution, caching, analytics, and simulation.
# Bazel Special Interest Groups
Source: https://bazel.build/community/sig
Bazel hosts Special Interest Groups (SIGs) to focus collaboration on particular
areas and to support communication and coordination between [Bazel owners, maintainers, and contributors](/contribute/policy). This policy
applies to [`bazelbuild`](http://github.com/bazelbuild).
SIGs do their work in public. The ideal scope for a SIG covers a well-defined
domain, where the majority of participation is from the community. SIGs may
focus on community maintained repositories in `bazelbuild` (such as language
rules) or focus on areas of code in the Bazel repository (such as Remote
Execution).
While not all SIGs will have the same level of energy, breadth of scope, or
governance models, there should be sufficient evidence that there are community
members willing to engage and contribute should the interest group be
established. Before joining, review the group's work, and then get in touch
with the SIG leader. Membership policies vary on a per-SIG basis.
See the complete list of
[Bazel SIGs](https://github.com/bazelbuild/community/tree/main/sigs).
### Non-goals: What a SIG is not
SIGs are intended to facilitate collaboration on shared work. A SIG is
therefore:
* *Not a support forum:* a mailing list and a SIG is not the same thing
* *Not immediately required:* early on in a project's life, you may not know
if you have shared work or collaborators
* *Not free labor:* energy is required to grow and coordinate the work
collaboratively
Bazel Owners take a conservative approach to SIG creation—thanks to the ease of
starting projects on GitHub, there are many avenues where collaboration can
happen without the need for a SIG.
## SIG lifecycle
This section covers how to create a SIG.
### Research and consultation
To propose a new SIG group, first gather evidence for approval, as specified
below. Some possible avenues to consider are:
* A well-defined problem or set of problems the group would solve
* Consultation with community members who would benefit, assessing both the
benefit and their willingness to commit
* For existing projects, evidence from issues and PRs that contributors care
about the topic
* Potential goals for the group to achieve
* Resource requirements of running the group
Even if the need for a SIG seems self-evident, the research and consultation is
still important to the success of the group.
### Create the new group
The new group should follow the below process for chartering. In particular, it
must demonstrate:
* A clear purpose and benefit to Bazel (either around a sub-project or
application area)
* Two or more contributors willing to act as group leads, existence of other
contributors, and evidence of demand for the group
* Each group needs to use at least one publicly accessible mailing list. A SIG
may reuse one of the public lists, such as
[bazel-discuss](https://groups.google.com/g/bazel-discuss), ask for a list
for @bazel.build, or create their own list
* Resources the SIG initially requires (usually, mailing list and regular
video call.)
* SIGs can serve documents and files from their directory in
[`bazelbuild/community`](https://github.com/bazelbuild/community)
or from their own repository in the
[`bazelbuild`](https://github.com/bazelbuild) GitHub
organization. SIGs may link to external resources if they choose to organize
their work outside of the `bazelbuild` GitHub organization
* Bazel Owners approve or reject SIG applications and consult other
stakeholders as necessary
Before entering the formal parts of the process, you should consult with
the Bazel product team, at [product@bazel.build](mailto:product@bazel.build). Most SIGs require conversation
and iteration before approval.
The formal request for the new group is done by submitting a charter as a PR to
[`bazelbuild/community`](https://github.com/bazelbuild/community),
and including the request in the comments on the PR following the template
below. On approval, the PR for the group is merged and the required resources
created.
### Template Request for New SIG
To request a new SIG, use the template in the community repo:
[SIG-request-template.md](https://github.com/bazelbuild/community/blob/main/governance/SIG-request-template.md).
### Chartering
To establish a group, you need a charter and must follow the Bazel
[code of conduct](https://github.com/bazelbuild/bazel/blob/HEAD/CODE_OF_CONDUCT.md).
Archives of the group will be public. Membership may either be open to all
without approval, or available on request, pending approval of the group
administrator.
The charter must nominate an administrator. As well as an administrator, the
group must include at least one person as lead (these may be the same person),
who serves as point of contact for coordination as required with the Bazel
product team.
Group creators must post their charter to the group mailing list. The community
repository in the Bazel GitHub organization archives such documents and
policies. As groups evolve their practices and conventions, they should update
their charters within the relevant part of the community repository.
### Collaboration and inclusion
While not mandated, the group should choose to make use of collaboration
via scheduled conference calls or chat channels to conduct meetings. Any such
meetings should be advertised on the mailing list, and notes posted to the
mailing list afterwards. Regular meetings help drive accountability and progress
in a SIG.
Bazel product team members may proactively monitor and encourage the group to
discussion and action as appropriate.
### Launch a SIG
Required activities:
* Notify Bazel general discussion groups
([bazel-discuss](https://groups.google.com/g/bazel-discuss),
[bazel-dev](https://groups.google.com/g/bazel-dev)).
Optional activities:
* Create a blog post for the Bazel blog
### Health and termination of SIGs
The Bazel owners make a best effort to ensure the health of SIGs. Bazel owners
occasionally request the SIG lead to report on the SIG's work, to inform the
broader Bazel community of the group's activity.
If a SIG no longer has a useful purpose or interested community, it may be
archived and cease operation. The Bazel product team reserves the right to
archive such inactive SIGs to maintain the overall health of the project,
though it is a less preferable outcome. A SIG may also opt to disband if
it recognizes it has reached the end of its useful life.
## Note
*This content has been adopted from Tensorflow’s
[SIG playbook](https://www.tensorflow.org/community/sig_playbook)
with modifications.*
# Who's Using Bazel
Source: https://bazel.build/community/users
Note: Using Bazel? You can add your company on
[StackShare](https://stackshare.io/bazel). To add yourself to this page,
contact [product@bazel.build](mailto:product@bazel.build).
This page lists companies and OSS projects that are known to use Bazel.
This does not constitute an endorsement.
## Companies using Bazel
### [acqio](https://acqio.com.br)

Acqio is a Fintech that provides payment products and services for small and
medium merchants. Acqio has a handful of monorepos and uses Bazel along with
Kubernetes to deliver fast and reliable microservices.
### [Adobe](https://www.adobe.com/)

Adobe has released Bazel [rules](https://github.com/adobe/rules_gitops) for
continuous, GitOps driven Kubernetes deployments.
### [Asana](https://asana.com)

Asana is a web and mobile application designed to help teams track their work.
In their own words:
> Bazel has increased reliability, stability, and speed for all of builds/tests
> at Asana. We no longer need to clean because of incorrect caches.
### [Ascend.io](https://ascend.io)
Ascend is a Palo Alto startup that offers solutions for large data sets
analysis. Their motto is *Big data is hard. We make it easy*.
### [ASML](https://asml.com)

ASML is an innovation leader in the semiconductor industry. We provide chipmakers
with everything they need – hardware, software and services – to mass produce
patterns on silicon through lithography.
### [Augment Code](https://augmentcode.com)
Augment Code is the first Developer AI for teams.
Every Augment feature is context aware. Every suggestion, completion, and
interaction reflects the components, APIs, and coding patterns in your
codebase to help your teams build better software.
### [Beeswax](https://www.beeswax.com/)
> Beeswax is a New York based startup that provides real time bidding as
> service. Bazel powers their Jenkins based continuous integration and deployment
> framework. Beeswax loves Bazel because it is blazingly fast, correct and well
> supported across many languages and platforms.
### [Braintree](https://www.braintreepayments.com)

Braintree, a PayPal subsidiary, develops payment solutions for websites and
applications. They use Bazel for parts of their internal build and Paul Gross
even posted a
[nice piece about how their switch to Bazel went](https://www.pgrs.net/2015/09/01/migrating-from-gradle-to-bazel/).
### [Canva](https://www.canva.com/)

Canva leverages Bazel to manage its large polyglot codebase, which includes
Java, TypeScript, Rust, Python, and more. Migration to Bazel has delivered
significant developer and compute infrastructure efficiencies, for example 5-6x
decreases in average CI build times, and it continues to become the foundation
of fast, reproducible, and standardised software builds at the company.
### [CarGurus](https://www.cargurus.com)

CarGurus is on a mission to build the world's most trusted and transparent
automotive marketplace and uses Bazel to build their polyglot monorepo.
### [Compass](https://www.compass.com)
Compass is a tech-driven real estate platform. With an elite team of real
estate, technology and business professionals, we aim to be the best and most
trusted source for home seekers.
### [Databricks](https://databricks.com)

Databricks provides cloud-based integrated workspaces based on Apache Spark™.
> The Databricks codebase is a Monorepo, containing the Scala code that powers
> most of our services, Javascript for front-end UI, Python for scripting,
> Jsonnet to configure our infrastructure, and much more \[...] Even though our
> monorepo contains a million lines of Scala, working with code within is fast
> and snappy.
> ([Speedy Scala Builds with Bazel at Databricks](https://databricks.com/blog/2019/02/27/speedy-scala-builds-with-bazel-at-databricks.html))
### [Dataform](https://dataform.co)
Dataform provides scalable analytics for data teams. They maintain a handful of
NPM packages and a documentation site in one single monorepo and they do it all
with Bazel.
After the migration to Bazel, they
[reported many benefits](https://github.com/bazelbuild/rules_nodejs#user-testimonials),
including:
> * Faster CI: we enabled the remote build caching which has reduced our average build time from 30 minutes to 5 (for the entire repository).
> * Improvements to local development: no more random bash scripts that you forget to run, incremental builds reduced to seconds from minutes
> * Developer setup time: New engineers can build all our code with just 3 dependencies - bazel, docker and the JVM. The last engineer to join our team managed to build all our code in \< 30 minutes on a brand new, empty laptop
### [Deep Silver FISHLABS](https://www.dsfishlabs.com)
Deep Silver FISHLABS is a developer of high-end 3D games. They use Bazel with
C++/Python/Go/C as a base for their internal build tooling and especially for
baking and deploying all their 3D Assets.
### [Dropbox](https://www.dropbox.com/)

At Dropbox, Bazel is a key component to our distributed build and test
environment. We use Bazel to combine TypeScript/Python/Go/C/Rust into reliable
production releases.
### [Engel & Völkers](https://www.engelvoelkers.com)
Engel & Völkers AG is a privately owned German company that, via a series of
franchised offices, provides services related to real estate transactions.
> One of our internal project has seen a decrease of compilation time from 11
> minutes to roughly 1 minute, this was an impressive achievement and we are
> currently working on bringing Bazel to more projects.
> ([Experimenting with Google Cloud Build and Bazel](https://www.engelvoelkers.com/en/tech/engineering/software-engineering/experimenting-with-google-cloud-build-and-bazel/))
### [Etsy](https://www.etsy.com/)

Etsy is an e-commerce website focused on handmade or vintage items and supplies,
as well as unique factory-manufactured items.
They use Bazel to build and test its Java-based search platform. Bazel produces
both packages for bare metal servers and repeatable Docker images.
### [Evertz.io](https://www.evertz.io/)
Evertz.io is a multi-tenant, serverless SaaS platform for offering cost
effective, multi-regional services worldwide to the Broadcast Media Industry,
created by [Evertz Microsystems](https://en.wikipedia.org/wiki/Evertz_Microsystems).
The website is fully built and deployed with an Angular and Bazel workflow
([source](https://twitter.com/MattMackay/status/1113947685508341762)).
### [FINDMINE](http://www.findmine.com)

FINDMINE is a automation technology for the retail industry that uses machine
learning to scale the currently manual and tedious process of product curation.
We use Bazel to mechanize our entire python package building, testing, and
deployment process.
### [Flexport](https://www.flexport.com/)
Flexport is a tech-enabled global freight forwarder; our mission is to make
global trade easier for everyone. At Flexport, we use Bazel to build/test our
Java/JavaScript services and client libraries and to generate Java and Ruby
code from protobuf definitions.
[Read about how we run individual JUnit 5 tests in isolation with Bazel.](https://flexport.engineering/connecting-bazel-and-junit5-by-transforming-arguments-46440c6ea068)
### [Foursquare](https://foursquare.com)

Foursquare's mission is to create technology that constructs meaningful
bridges between digital spaces and physical places. We manage millions of
lines of primarily Scala and Python code powering data-intensive
applications, including complex codegen and container build processes, with
Bazel.
### [GermanTechJobs](https://germantechjobs.de)

Bazel has simplified our workflows 10-fold and enabled shipping features at
scale.
### [Google](https://google.com)

Bazel was designed to be able to scale to Google's needs and meet Google's
requirements of reproducibility and platform/language support. All software at
Google is built using Bazel. Google uses Bazel and its rules for millions of
builds every day.
### [Huawei](http://www.huawei.com/)
> Huawei Technologies is using Bazel in about 30 projects, they are Java/Scala/Go
> projects, except for Go projects, others originally were built by Maven. We
> write a simple tool to translate a Maven-built project into Bazel-built one.
> More and more projects will use Bazel in recent future.
### [IMC Trading](https://imc.com)

> IMC is a global proprietary trading firm and market maker headquarted in
> Amsterdam. We are using Bazel to continuously build and test our
> Java/C++/Python/SystemVerilog projects.
### [Improbable.io](https://improbable.io/)
Improbable.io develops SpatialOS, a distributed operating system that enables
creating huge simulations inhabited by millions of complex entities.
### [Interaxon](https://www.choosemuse.com/)
InteraXon is a thought-controlled computing firm that creates hardware and
software platforms to convert brainwaves into digital signals.
## [JetBrains](https://www.jetbrains.com/)

JetBrains is a leading provider of IDEs and developer tools. Since 2022, we’ve been active in the Bazel community, delivering robust polyglot support through plugins for CLion, GoLang, PyCharm, and IntelliJ IDEA. We also use Bazel internally to build these products from our own large-scale monorepo.
### [Jupiter](https://jupiter.co/)
Jupiter is a company that provides delivery of groceries and household
essentials every week.
They use Bazel in their backend code, specifically to compile protos and Kotlin
to JVM binaries, using remote caching.
([source](https://starship.jupiter.co/jupiter-stack/))
### [Just](https://gojust.com/)
Just is an enterprise financial technology company, headquartered in Norway,
creating software solutions to transform how global corporate treasurers manage
risk and liquidity. Their entire application stack is built with Bazel.
### [Line](https://line.me/)
Line provides an app for instant communications, which is the most popular
messaging application in Japan.
They use Bazel on their codebase consisting of about 60% Swift and 40%
C/C++/Objective-C/Objective-C++
([source](https://twitter.com/thi_dt/status/1253334262020886532)).
> After switching to Bazel, we were able to achieve a huge improvement in the
> build times. This brought a significant improvement in the turn-around time
> during a QA period. Distributing a new build to our testers no longer means
> another hour waiting for building and testing.
> ([Improving Build Performance of LINE for iOS with Bazel](https://engineering.linecorp.com/en/blog/improving-build-performance-line-ios-bazel/))
### [LingoChamp](https://www.liulishuo.com/en)

LingoChamp provides professional solutions to English learners. We use Bazel
for our go, java and python projects.
### [LinkedIn](https://linkedin.com/)

LinkedIn, a subsidiary of Microsoft, is the world’s largest professional social
network. LinkedIn uses Bazel for building its iOS Apps.
### [Lucid Software](https://lucid.co/)

Lucid Software is a leader in visual collaboration, helping teams see and build the
future from idea to reality. With its products—[Lucidchart](https://www.lucidchart.com/),
[Lucidspark](https://lucidspark.com/), and [Lucidscale](https://lucidscale.com/)—teams
can align around a shared vision, clarify complexity, and collaborate visually, no
matter where they’re located.
Lucid uses Bazel to build millions of lines of Scala and TypeScript.
Migrating to Bazel has tremendously sped up its builds, reduced external
dependencies on the build environment, and simplified developers' experience
with the build system. Bazel has improved developer productivity at Lucid and
unlocked further growth.
### [Lyft](https://www.lyft.com/)
Lyft is using Bazel for their iOS ([source](https://twitter.com/SmileyKeith/status/1116486751806033920)) and Android Apps.
### [Meetup](http://www.meetup.com/)
Meetup is an online social networking portal that facilitates offline group
meetings.
The Meetup engineering team contributes to
[rules\_scala](https://github.com/bazelbuild/rules_scala) and is the
maintainer of [rules\_avro](https://github.com/meetup/rules_avro)
and [rules\_openapi](https://github.com/meetup/rules_openapi).
### [Nvidia](https://www.nvidia.com/)
> At Nvidia we have been using dazel(docker bazel) for python to work around
> some of bazel's python short comings. Everything else runs in normal bazel
> (Mostly Go / Scala/ C++/ Cuda)
> ([source](https://twitter.com/rwhitcomb/status/1080887723433447424))
### [Peloton Technology](http://www.peloton-tech.com)
Peloton Technology is an automated vehicle technology company that tackles truck
accidents and fuel use. They use Bazel to *enable reliable builds for automotive
safety systems*.
### [Pigweed](https://pigweed.dev)

Pigweed is an open-source solution for sustained, robust, and rapid embedded
product development for large teams. Pigweed has shipped in millions of
devices, including Google's suite of Pixel devices, Nest thermostats,
[satellites](https://www.spinlaunch.com/), and [autonomous aerial drones](https://www.flyzipline.com/).
Pigweed [uses Bazel as its primary build system](https://pigweed.dev/seed/0111-build-systems.html). The [Bazel for
Embedded][pw-bazel-great] blog post discusses why we think it's a great build
system for embedded projects!
[pw-bazel-great]: https://blog.bazel.build/2024/08/08/bazel-for-embedded.html#why-bazel-for-embedded
### [Pinterest](https://www.pinterest.com/)

Pinterest is the world’s catalog of ideas. They use Bazel to build various
backend services (Java/C++) and the iOS application (Objective-C/C++).
> We identified Bazel was the best fit for our goals to build a foundation for
> an order of magnitude improvement in performance, eliminate variability in
> build environments and adopt incrementally. As a result, we’re now shipping all
> our iOS releases using Bazel.
> [Developing fast & reliable iOS builds at Pinterest](https://medium.com/@Pinterest_Engineering/developing-fast-reliable-ios-builds-at-pinterest-part-one-cb1810407b92)
### [PubRef](https://github.com/pubref)
PubRef is an emerging scientific publishing platform. They use Bazel with
[rules\_closure](https://github.com/bazelbuild/rules_closure) to build the
frontend, native java rules to build the main backend,
[rules\_go](https://github.com/bazelbuild/rules_go),
[rules\_node](https://github.com/pubref/rules_node), and
[rules\_kotlin](https://github.com/pubref/rules_kotlin) to build assorted
backend services. [rules\_protobuf](https://github.com/pubref/rules_protobuf) is
used to assist with gRPC-based communication between backend services.
PubRef.org is based in Boulder, CO.
### [Redfin](https://redfin.com/)
Redfin is a next-generation real estate brokerage with full-service local
agents. They use Bazel to build and deploy the website and various backend
services.
> With the conversion mostly behind us, things are greatly improved! Our CI
> builds are faster (*way* faster: they used to take 40–90 minutes, and now dev
> builds average 5–6 minutes). Reliability is far higher, too. This is harder to
> quantify, but the shift from unexplained build failures being something that
> “just happens” to being viewed as real problems to be solved has put us on a
> virtuous cycle of ever-increasing reliability.
> ([We Switched from Maven to Bazel and Builds Got 10x Faster](https://redfin.engineering/we-switched-from-maven-to-bazel-and-builds-got-10x-faster-b265a7845854))
### [Ritual](https://ritual.co)

Ritual is a mobile pick up app, connecting restaurants with customers to offer
a simple, time-saving tool to get the food and beverages they want, without the
wait. Ritual uses Bazel for their backend services.
### [Snap](https://www.snap.com/en-US/)
Snap, the developer of Snapchat messaging app, has migrated from Buck to Bazel
in 2020 ([source](https://twitter.com/wew/status/1326957862816509953)). For more
details about their process, see their [engineering blog](https://eng.snap.com/blog/).
### [Spotify](https://spotify.com)
Spotify is using Bazel to build their iOS and Android Apps ([source](https://twitter.com/BalestraPatrick/status/1573355078995566594)).
### [Stripe](https://stripe.com)

Stripe provides mobile payment solutions. They use Bazel in their build and test pipelines, as detailed in their [engineering blog](https://stripe.com/blog/fast-secure-builds-choose-two).
### [Tinder](https://tinder.com)

Tinder migrated its iOS app from CocoaPods to Bazel
in 2021 ([source](https://medium.com/tinder/bazel-hermetic-toolchain-and-tooling-migration-c244dc0d3ae)).
### [Tink](https://tink.com/)

Tink is a european fintech, building the best way to connect to banks across
Europe.
They are using Bazel to build their backend services from a polyglot monorepo.
Engineers at Tink are organizing the [bazel build //stockholm/...](https://www.meetup.com/BazelSTHLM/)
meetup group.
### [Tokopedia](https://www.tokopedia.com/)
Tokopedia is an Indonesian technology company specializing in e-commerce, with
over 90 million monthly active users and over 7 million merchants on the
platform.
They wrote the article
[How Tokopedia Achieved 1000% Faster iOS Build Time](https://medium.com/tokopedia-engineering/how-tokopedia-achieved-1000-faster-ios-build-time-7664b2d8ae5),
where they explain how Bazel sped up their builds. The build duration went from
55 minutes to 10 minutes by using Bazel, and down to 5 minutes with remote
caching.
### [Trunk.io](https://trunk.io/merge/trunk-merge-and-bazel)

Trunk is a San Francisco-based company backed by Andreessen Horowitz and Initialized Capital. Trunk offers a powerful pull request merge service with first-class support for the Bazel build system. By leveraging Bazel's understanding of dependencies within a codebase, Trunk's merge service intelligently creates parallel merge lanes, allowing independent changes to be tested and merged simultaneously.
> Trunk’s internal monorepo builds modern C++ 20 and typescript all while leveraging bazel graph knowledge to selectively test and merge code.
### [Twitter](https://twitter.com/)
Twitter has made the decision to migrate from Pants to Bazel as their primary
build tool
([source](https://groups.google.com/forum/#!msg/pants-devel/PHVIbVDLhx8/LpSKIP5cAwAJ)).
### [Two Sigma](https://www.twosigma.com/)

Two Sigma is a New York-headquartered technology company dedicated to finding
value in the world’s data.
### [TypeDB](https://typedb.com)

TypeDB is a database technology that can be used to intuitively model
interconnected data. Through its type-theoretic and polymorphic query language,
TypeQL, the data can be accessed with simple, human-readable queries that run at
lightspeed.
Bazel enables the TypeDB team to build a highly-orchestrated CI and distribution
pipeline that manages many repositories in a wide variety of languages, and
deploys to numerous platforms seamlessly. The TypeDB team has also released
Bazel rules for assembling and deploying software distributions.
### [Uber](https://www.uber.com)
Uber is a ride-hailing company. With 900 active developers, Uber’s Go monorepo
is likely one of the largest Go repositories using Bazel. See the article
[Building Uber’s Go Monorepo with Bazel](https://eng.uber.com/go-monorepo-bazel/)
to learn more about their experience.
### [Uber Advanced Technologies Group](https://www.uber.com/info/atg/)

Uber Advanced Technologies Group is focused on autonomous vehicle efforts at
Uber, including trucking/freight and autonomous ride sharing. The organization
uses Bazel as its primary build system.
### [Vistar Media](http://vistarmedia.com)
Vistar Media is an advertising platform that enables brands to reach consumers
based on their behavior in the physical world. Their engineering team is
primarily based out of Philadelphia and is using Bazel for builds, deploys, to
speed up testing, and to consolidate repositories written with a variety of
different technologies.
### [VMware](https://www.vmware.com/)
VMware uses Bazel to produce deterministic, reliable builds while developing
innovative products for their customers.
### [Wix](https://www.wix.com/)
Wix is a cloud-based web development platform. Their backend uses Java and Scala
code. They use remote execution with Google Cloud Build.
> We have seen about 5 times faster clean builds when running with bazel remote
> execution which utilizes bazel’s great build/test parallelism capabilities when
> it dispatches build/test actions to a worker farm. Average build times are more
> than 10 times faster due to the utilization of bazel’s aggressive caching
> mechanism.
> ([Migrating to Bazel from Maven or Gradle? 5 crucial questions you should ask yourself](https://medium.com/wix-engineering/migrating-to-bazel-from-maven-or-gradle-5-crucial-questions-you-should-ask-yourself-f23ac6bca070))
### [Zenly](https://zen.ly/)
Zenly is a live map of your friends and family. It’s the most fun way to meet up
— or just see what’s up! — so you can feel together, even when you're apart.
***
## Open source projects using Bazel
### [Abseil](https://abseil.io/)
Abseil is an open-source collection of C++ code (compliant to C++11) designed
to augment the C++ standard library.
### [Angular](https://angular.io)

Angular is a popular web framework.
Angular is [built with Bazel](https://github.com/angular/angular/blob/master/docs/BAZEL.md).
### [Apollo](https://github.com/ApolloAuto/apollo)
Apollo is a high performance, flexible architecture which accelerates the
development, testing, and deployment of Autonomous Vehicles.
### [brpc](https://github.com/brpc/brpc)
An industrial-grade RPC framework used throughout Baidu, with 1,000,000+
instances(not counting clients) and thousands kinds of services, called
"baidu-rpc" inside Baidu.
### [cert-manager](https://github.com/jetstack/cert-manager)
cert-manager is a Kubernetes add-on to automate the management and issuance of
TLS certificates from various issuing sources. It will ensure certificates are
valid and up to date periodically, and attempt to renew certificates at an
appropriate time before expiry.
### [CallBuilder](https://github.com/google/CallBuilder)
A Java code generator that allows you to create a builder by writing one
function.
### [CPPItertools](https://github.com/ryanhaining/cppitertools)
C++ library providing range-based for loop add-ons inspired by the Python
builtins and itertools library. Like itertools and the Python3 builtins, this
library uses lazy evaluation wherever possible.
### [Copybara](https://github.com/google/copybara)
Copybara is a tool for transforming and moving code between repositories.
### [Dagger](https://google.github.io/dagger/)
Dagger is a fully static, compile-time dependency injection framework for both
Java and Android.
### [DAML](https://github.com/digital-asset/daml)
DAML is a smart contract language for building future-proof distributed
applications on a safe, privacy-aware runtime.
### [DeepMind Lab](https://github.com/deepmind/lab)
A customisable 3D platform for agent-based AI research.
### [Drake](https://github.com/RobotLocomotion/drake)
Drake is a C++ toolbox started at MIT and now led by the Toyota Research
Institute. It is a collection of tools for analyzing the dynamics of our robots
and building control systems for them, with a heavy emphasis on
optimization-based design/analysis.
### [Envoy](https://github.com/lyft/envoy)
C++ L7 proxy and communication bus
### [Error Prone](https://github.com/google/error-prone)
Catches common Java mistakes as compile-time errors. (Migration to Bazel is in
progress.)
### [Extensible Service Proxy](https://github.com/cloudendpoints/esp)
Extensible Service Proxy, a.k.a. ESP is a proxy which enables API management
capabilities for JSON/REST or gRPC API services. The current implementation is
based on an NGINX HTTP reverse proxy server.
### [FFruit](https://gitlab.com/perezd/ffruit/)
FFruit is a free & open source Android application to the popular service
[Falling Fruit](https://fallingfruit.org).
### [Gerrit Code Review](https://gerritcodereview.com)
Gerrit is a code review and project management tool for Git based projects.
### [Gitiles](https://gerrit.googlesource.com/gitiles/)
Gitiles is a simple repository browser for Git repositories, built on JGit.
### [Grakn](https://github.com/graknlabs/grakn)
Grakn ([https://grakn.ai/](https://grakn.ai/)) is the knowledge graph engine to organise complex
networks of data and make it queryable.
### [GRPC](http://www.grpc.io)
A language-and-platform-neutral remote procedure call system.
(Bazel is a supported, although not primary, build system.)
### [gVisor](https://github.com/google/gvisor)
gVisor is a container runtime sandbox.
### [Guetzli](https://github.com/google/guetzli/)
Guetzli is a JPEG encoder that aims for excellent compression density at high
visual quality.
### [Gulava](http://www.github.com/google/gulava/)
A Java code generator that lets you write Prolog-style predicates and use them
seamlessly from normal Java code.
### [Heron](https://github.com/apache/incubator-heron)
Heron is a realtime, distributed, fault-tolerant stream processing engine from
Twitter.
### [Internet Computer Protocol](https://internetcomputer.org/)

The Internet Computer Protocol is a publicly available blockchain network that
enables replicated execution of general-purpose computation, serving hundreds
of thousands of applications and their users.
### [Jazzer](https://github.com/CodeIntelligenceTesting/jazzer)

Jazzer is a fuzzer for Java and other JVM-based languages that integrates with JUnit 5.
### [JGit](https://eclipse.org/jgit/)
JGit is a lightweight, pure Java library implementing the Git version control
system.
### [Jsonnet](https://jsonnet.org/)
An elegant, formally-specified config generation language for JSON.
(Bazel is a supported build system.)
### [Kythe](https://github.com/google/kythe)
An ecosystem for building tools that work with code.
### [ls-lint](https://github.com/loeffel-io/ls-lint)

An extremely fast directory and filename linter - Bring some structure to your
project file system.
### [Nomulus](https://github.com/google/nomulus)
Top-level domain name registry service on Google App Engine.
### [ONOS : Open Network Operating System](https://github.com/opennetworkinglab/onos)

ONOS is the only SDN controller platform that supports the transition from
legacy “brown field” networks to SDN “green field” networks. This enables
exciting new capabilities, and disruptive deployment and operational cost points
for network operators.
### [PetitParser for Java](https://github.com/petitparser/java-petitparser)
Grammars for programming languages are traditionally specified statically.
They are hard to compose and reuse due to ambiguities that inevitably arise.
PetitParser combines ideas from scannnerless parsing, parser combinators,
parsing expression grammars and packrat parsers to model grammars and parsers
as objects that can be reconfigured dynamically.
### [PlaidML](https://github.com/plaidml/plaidml)
PlaidML is a framework for making deep learning work everywhere.
### [Project V](https://www.v2ray.com/)

Project V is a set of tools to help you build your own privacy network over
internet.
### [Prysmatic Labs Ethereum 2.0 Implementation](https://github.com/prysmaticlabs/prysm)
Prysm is a sharding client for Ethereum 2.0, a blockchain-based distributed
computing platform.
### [Ray](https://github.com/ray-project/ray)
Ray is a flexible, high-performance distributed execution framework.
### [Resty](https://github.com/go-resty/resty)
Resty is a Simple HTTP and REST client library for Go (inspired by Ruby
rest-client).
### [Roughtime](https://roughtime.googlesource.com/roughtime)
Roughtime is a project that aims to provide secure time synchronisation.
### [Selenium](https://github.com/SeleniumHQ/selenium)
Selenium is a portable framework for testing web applications.
### [Semantic](https://github.com/github/semantic)
Semantic is a Haskell library and command line tool for parsing, analyzing, and
comparing source code. It is developed by GitHub (and used for example for the
code navigation).
### [Served](https://github.com/meltwater/served)
Served is a C++ library for building high performance RESTful web servers.
### [Sonnet](https://github.com/deepmind/sonnet)
Sonnet is a library built on top of TensorFlow for building complex neural
networks.
### [Sorbet](https://github.com/sorbet/sorbet)
Sorbet is a fast, powerful type checker for a subset of Ruby. It scales to
codebases with millions of lines of code and can be adopted incrementally.
### [Tink](https://github.com/google/tink)
Tink is a multi-language, cross-platform, open source library that provides
cryptographic APIs that are secure, easy to use correctly, and hard(er) to
misuse.
### [TensorFlow](http://tensorflow.org)

An open source software library for machine intelligence.
### [Turbo Santa](https://github.com/turbo-santa/turbo-santa-common)
A platform-independent GameBoy emulator.
### [Wycheproof](https://github.com/google/wycheproof)
Project Wycheproof tests crypto libraries against known attacks.
### [XIOSim](https://github.com/s-kanev/XIOSim)
XIOSim is a detailed user-mode microarchitectural simulator for the x86
architecture.
### [ZhihuDailyPurify](https://github.com/izzyleung/ZhihuDailyPurify)
ZhihuDailyPurify is a light weight version of Zhihu Daily, a Chinese
question-and-answer webs.
# Guide for rolling out breaking changes
Source: https://bazel.build/contribute/breaking-changes
It is inevitable that we will make breaking changes to Bazel. We will have to
change our designs and fix the things that do not quite work. However, we need
to make sure that community and Bazel ecosystem can follow along. To that end,
Bazel project has adopted a
[backward compatibility policy](/release/backward-compatibility).
This document describes the process for Bazel contributors to make a breaking
change in Bazel to adhere to this policy.
1. Follow the [design document policy](/contribute/design-documents).
2. [File a GitHub issue.](#github-issue)
3. [Implement the change.](#implementation)
4. [Update labels.](#labels)
5. [Update repositories.](#update-repos)
6. [Flip the incompatible flag.](#flip-flag)
## GitHub issue
[File a GitHub issue](https://github.com/bazelbuild/bazel/issues)
in the Bazel repository.
[See example.](https://github.com/bazelbuild/bazel/issues/6611)
We recommend that:
* The title starts with the name of the flag (the flag name will start with
`incompatible_`).
* You add the label
[`incompatible-change`](https://github.com/bazelbuild/bazel/labels/incompatible-change).
* The description contains a description of the change and a link to relevant
design documents.
* The description contains a migration recipe, to explain users how they should
update their code. Ideally, when the change is mechanical, include a link to a
migration tool.
* The description includes an example of the error message users will get if
they don't migrate. This will make the GitHub issue more discoverable from
search engines. Make sure that the error message is helpful and actionable.
When possible, the error message should include the name of the incompatible
flag.
For the migration tool, consider contributing to
[Buildifier](https://github.com/bazelbuild/buildtools/blob/master/buildifier/README.md).
It is able to apply automated fixes to `BUILD`, `WORKSPACE`, and `.bzl` files.
It may also report warnings.
## Implementation
Create a new flag in Bazel. The default value must be false. The help text
should contain the URL of the GitHub issue. As the flag name starts with
`incompatible_`, it needs metadata tags:
```java theme={null}
metadataTags = {
OptionMetadataTag.INCOMPATIBLE_CHANGE,
},
```
In the commit description, add a brief summary of the flag.
Also add [`RELNOTES:`](/contribute/release-notes) in the following form:
`RELNOTES: --incompatible_name_of_flag has been added. See #xyz for details`
The commit should also update the relevant documentation, so that there is no
window of commits in which the code is inconsistent with the docs. Since our
documentation is versioned, changes to the docs will not be inadvertently
released prematurely.
## Labels
Once the commit is merged and the incompatible change is ready to be adopted, add the label
[`migration-ready`](https://github.com/bazelbuild/bazel/labels/migration-ready)
to the GitHub issue.
If a problem is found with the flag and users are not expected to migrate yet:
remove the flags `migration-ready`.
If you plan to flip the flag in the next major release, add label \`breaking-change-X.0" to the issue.
## Updating repositories
Bazel CI tests a list of important projects at
[Bazel@HEAD + Downstream](https://buildkite.com/bazel/bazel-at-head-plus-downstream). Most of them are often
dependencies of other Bazel projects, therefore it's important to migrate them to unblock the migration for the broader community. To monitor the migration status of those projects, you can use the [`bazelisk-plus-incompatible-flags` pipeline](https://buildkite.com/bazel/bazelisk-plus-incompatible-flags).
Check how this pipeline works [here](https://github.com/bazelbuild/continuous-integration/tree/master/buildkite#checking-incompatible-changes-status-for-downstream-projects).
Our dev support team monitors the [`migration-ready`](https://github.com/bazelbuild/bazel/labels/migration-ready) label. Once you add this label to the GitHub issue, they will handle the following:
1. Create a comment in the GitHub issue to track the list of failures and downstream projects that need to be migrated ([see example](https://github.com/bazelbuild/bazel/issues/17032#issuecomment-1353077469))
2. File Github issues to notify the owners of every downstream project broken by your incompatible change ([see example](https://github.com/bazelbuild/intellij/issues/4208))
3. Follow up to make sure all issues are addressed before the target release date
Migrating projects in the downstream pipeline is NOT entirely the responsibility of the incompatible change author, but you can do the following to accelerate the migration and make life easier for both Bazel users and the Bazel Green Team.
1. Send PRs to fix downstream projects.
2. Reach out to the Bazel community for help on migration (e.g. [Bazel Rules Authors SIG](https://bazel-contrib.github.io/SIG-rules-authors/)).
## Flipping the flag
Before flipping the default value of the flag to true, please make sure that:
* Core repositories in the ecosystem are migrated.
On the [`bazelisk-plus-incompatible-flags` pipeline](https://buildkite.com/bazel/bazelisk-plus-incompatible-flags),
the flag should appear under `The following flags didn't break any passing Bazel team owned/co-owned projects`.
* All issues in the checklist are marked as fixed/closed.
* User concerns and questions have been resolved.
When the flag is ready to flip in Bazel, but blocked on internal migration at Google, please consider setting the flag value to false in the internal `blazerc` file to unblock the flag flip. By doing this, we can ensure Bazel users depend on the new behaviour by default as early as possible.
When changing the flag default to true, please:
* Use `RELNOTES[INC]` in the commit description, with the
following format:
`RELNOTES[INC]: --incompatible_name_of_flag is flipped to true. See #xyz for
details`
You can include additional information in the rest of the commit description.
* Use `Fixes #xyz` in the description, so that the GitHub issue gets closed
when the commit is merged.
* Review and update documentation if needed.
* File a new issue `#abc` to track the removal of the flag.
## Removing the flag
After the flag is flipped at HEAD, it should be removed from Bazel eventually.
When you plan to remove the incompatible flag:
* Consider leaving more time for users to migrate if it's a major incompatible change.
Ideally, the flag should be available in at least one major release.
* For the commit that removes the flag, use `Fixes #abc` in the description
so that the GitHub issue gets closed when the commit is merged.
# The Bazel codebase
Source: https://bazel.build/contribute/codebase
This document is a description of the codebase and how Bazel is structured. It
is intended for people willing to contribute to Bazel, not for end-users.
## Introduction
The codebase of Bazel is large (\~350KLOC production code and \~260 KLOC test
code) and no one is familiar with the whole landscape: everyone knows their
particular valley very well, but few know what lies over the hills in every
direction.
In order for people midway upon the journey not to find themselves within a
forest dark with the straightforward pathway being lost, this document tries to
give an overview of the codebase so that it's easier to get started with
working on it.
The public version of the source code of Bazel lives on GitHub at
[github.com/bazelbuild/bazel](http://github.com/bazelbuild/bazel). This is not
the "source of truth"; it's derived from a Google-internal source tree that
contains additional functionality that is not useful outside Google. The
long-term goal is to make GitHub the source of truth.
Contributions are accepted through the regular GitHub pull request mechanism,
and manually imported by a Googler into the internal source tree, then
re-exported back out to GitHub.
## Client/server architecture
The bulk of Bazel resides in a server process that stays in RAM between builds.
This allows Bazel to maintain state between builds.
This is why the Bazel command line has two kinds of options: startup and
command. In a command line like this:
```
bazel --host_jvm_args=-Xmx8G build -c opt //foo:bar
```
Some options (`--host_jvm_args=`) are before the name of the command to be run
and some are after (`-c opt`); the former kind is called a "startup option" and
affects the server process as a whole, whereas the latter kind, the "command
option", only affects a single command.
Each server instance has a single associated workspace (collection of source
trees known as "repositories") and each workspace usually has a single active
server instance. This can be circumvented by specifying a custom output base
(see the "Directory layout" section for more information).
Bazel is distributed as a single ELF executable that is also a valid .zip file.
When you type `bazel`, the above ELF executable implemented in C++ (the
"client") gets control. It sets up an appropriate server process using the
following steps:
1. Checks whether it has already extracted itself. If not, it does that. This
is where the implementation of the server comes from.
2. Checks whether there is an active server instance that works: it is running,
it has the right startup options and uses the right workspace directory. It
finds the running server by looking at the directory `$OUTPUT_BASE/server`
where there is a lock file with the port the server is listening on.
3. If needed, kills the old server process
4. If needed, starts up a new server process
After a suitable server process is ready, the command that needs to be run is
communicated to it over a gRPC interface, then the output of Bazel is piped back
to the terminal. Only one command can be running at the same time. This is
implemented using an elaborate locking mechanism with parts in C++ and parts in
Java. There is some infrastructure for running multiple commands in parallel,
since the inability to run `bazel version` in parallel with another command
is somewhat embarrassing. The main blocker is the life cycle of `BlazeModule`s
and some state in `BlazeRuntime`.
At the end of a command, the Bazel server transmits the exit code the client
should return. An interesting wrinkle is the implementation of `bazel run`: the
job of this command is to run something Bazel just built, but it can't do that
from the server process because it doesn't have a terminal. So instead it tells
the client what binary it should `exec()` and with what arguments.
When one presses Ctrl-C, the client translates it to a Cancel call on the gRPC
connection, which tries to terminate the command as soon as possible. After the
third Ctrl-C, the client sends a SIGKILL to the server instead.
The source code of the client is under `src/main/cpp` and the protocol used to
communicate with the server is in `src/main/protobuf/command_server.proto` .
The main entry point of the server is `BlazeRuntime.main()` and the gRPC calls
from the client are handled by `CommandServer.serveAndAwaitTermination()`.
## Directory layout
Bazel creates a somewhat complicated set of directories during a build. A full
description is available in [Output directory layout](/remote/output-directories).
The "main repo" is the source tree Bazel is run in. It usually corresponds to
something you checked out from source control. The root of this directory is
known as the "workspace root".
Bazel puts all of its data under the "output user root". This is usually
`$HOME/.cache/bazel/_bazel_${USER}`, but can be overridden using the
`--output_user_root` startup option.
The "install base" is where Bazel is extracted to. This is done automatically
and each Bazel version gets a subdirectory based on its checksum under the
install base. It's at `$OUTPUT_USER_ROOT/install` by default and can be changed
using the `--install_base` command line option.
The "output base" is the place where the Bazel instance attached to a specific
workspace writes to. Each output base has at most one Bazel server instance
running at any time. It's usually at `$OUTPUT_USER_ROOT/`. It can be changed using the `--output_base` startup option,
which is, among other things, useful for getting around the limitation that only
one Bazel instance can be running in any workspace at any given time.
The output directory contains, among other things:
* The fetched external repositories at `$OUTPUT_BASE/external`.
* The exec root, a directory that contains symlinks to all the source
code for the current build. It's located at `$OUTPUT_BASE/execroot`. During
the build, the working directory is `$EXECROOT/`. We are planning to change this to `$EXECROOT`, although it's a
long term plan because it's a very incompatible change.
* Files built during the build.
## The process of executing a command
Once the Bazel server gets control and is informed about a command it needs to
execute, the following sequence of events happens:
1. `BlazeCommandDispatcher` is informed about the new request. It decides
whether the command needs a workspace to run in (almost every command except
for ones that don't have anything to do with source code, such as version or
help) and whether another command is running.
2. The right command is found. Each command must implement the interface
`BlazeCommand` and must have the `@Command` annotation (this is a bit of an
antipattern, it would be nice if all the metadata a command needs was
described by methods on `BlazeCommand`)
3. The command line options are parsed. Each command has different command line
options, which are described in the `@Command` annotation.
4. An event bus is created. The event bus is a stream for events that happen
during the build. Some of these are exported to outside of Bazel under the
aegis of the Build Event Protocol in order to tell the world how the build
goes.
5. The command gets control. The most interesting commands are those that run a
build: build, test, run, coverage and so on: this functionality is
implemented by `BuildTool`.
6. The set of target patterns on the command line is parsed and wildcards like
`//pkg:all` and `//pkg/...` are resolved. This is implemented in
`AnalysisPhaseRunner.evaluateTargetPatterns()` and reified in Skyframe as
`TargetPatternPhaseValue`.
7. The loading/analysis phase is run to produce the action graph (a directed
acyclic graph of commands that need to be executed for the build).
8. The execution phase is run. This means running every action required to
build the top-level targets that are requested are run.
## Command line options
The command line options for a Bazel invocation are parsed into an
`OptionsParsingResult` object, which holds instances of `OptionsBase`
subclasses populated with the parsed values. An "option class" is a subclass
of `OptionsBase` and groups related command line options together.
There are two main kinds of option classes:
1. **Configuration options:** These options affect how targets are built,
for example, defining the target platform or compilation mode. They are
defined in subclasses of `FragmentOptions` (e.g., `CppOptions`,
`JavaOptions`), which is itself a subclass of `OptionsBase`.
`FragmentOptions` instances are collected into a `BuildOptions` object,
which is used to create the `BuildConfiguration` for a configured target.
These options are available during the analysis phase via
`RuleContext.getFragment()` in Java or `ctx.fragments` in Starlark.
2. **Other command options:** These options affect other aspects of Bazel's
behavior. They are defined in classes that extend `OptionsBase` directly,
but are not `FragmentOptions`. Examples include `ExecutionOptions`, which
influences how actions are executed, and `CommonCommandOptions`, which
contains options applicable to many commands. These are not part of
`BuildOptions`.
Some configuration options (for example, whether to do C++ include scanning with
`--cc_include_scanning`) are read in the execution phase. But that always
requires explicit plumbing since `BuildConfiguration` is not available then. For
more information, see the section "Configurations".
**WARNING:** We like to pretend that `OptionsBase` instances are immutable and
use them that way (such as a part of `SkyKeys`). This is not the case and
modifying them is a really good way to break Bazel in subtle ways that are hard
to debug. Unfortunately, making them actually immutable is a large endeavor.
(Modifying a `FragmentOptions` immediately after construction before anyone else
gets a chance to keep a reference to it and before `equals()` or `hashCode()` is
called on it is okay.)
Bazel learns about option classes in the following ways:
1. Some are hard-wired into Bazel (`CommonCommandOptions`).
2. From the `@Command` annotation on each Bazel command, which
lists option classes applicable to that command.
3. From `ConfiguredRuleClassProvider` (these are `FragmentOptions` for
individual programming languages that become part of `BuildOptions`).
4. Starlark rules can also define their own options, known as build settings
(see [here](/extending/config)).
Each option (excluding Starlark-defined options) is a member variable of an
`OptionsBase` subclass that has the `@Option` annotation, which specifies
the name and the type of the command line option along with some help text.
The Java type of the value of a command line option is usually something simple
(a string, an integer, a Boolean, a label, etc.). However, we also support
options of more complicated types; in this case, the job of converting from the
command line string to the data type falls to an implementation of
`com.google.devtools.common.options.Converter`.
## The source tree, as seen by Bazel
Bazel is in the business of building software, which happens by reading and
interpreting the source code. The totality of the source code Bazel operates on
is called "the workspace" and it is structured into repositories, packages and
rules.
### Repositories
A "repository" is a source tree on which a developer works; it usually
represents a single project. Bazel's ancestor, Blaze, operated on a monorepo,
that is, a single source tree that contains all source code used to run the build.
Bazel, in contrast, supports projects whose source code spans multiple
repositories. The repository from which Bazel is invoked is called the "main
repository", the others are called "external repositories".
A repository is marked by a repo boundary file (`MODULE.bazel`, `REPO.bazel`, or
in legacy contexts, `WORKSPACE` or `WORKSPACE.bazel`) in its root directory. The
main repo is the source tree where you're invoking Bazel from. External repos
are defined in various ways; see [external dependencies overview](/external/overview) for more information.
Code of external repositories is symlinked or downloaded under
`$OUTPUT_BASE/external`.
When running the build, the whole source tree needs to be pieced together; this
is done by `SymlinkForest`, which symlinks every package in the main repository
to `$EXECROOT` and every external repository to either `$EXECROOT/external` or
`$EXECROOT/..`.
### Packages
Every repository is composed of packages, a collection of related files and
a specification of the dependencies. These are specified by a file called
`BUILD` or `BUILD.bazel`. If both exist, Bazel prefers `BUILD.bazel`; the reason
why `BUILD` files are still accepted is that Bazel's ancestor, Blaze, used this
file name. However, it turned out to be a commonly used path segment, especially
on Windows, where file names are case-insensitive.
Packages are independent of each other: changes to the `BUILD` file of a package
cannot cause other packages to change. The addition or removal of `BUILD` files
*can* change other packages, since recursive globs stop at package boundaries
and thus the presence of a `BUILD` file stops the recursion.
The evaluation of a `BUILD` file is called "package loading". It's implemented
in the class `PackageFactory`, works by calling the Starlark interpreter and
requires knowledge of the set of available rule classes. The result of package
loading is a `Package` object. It's mostly a map from a string (the name of a
target) to the target itself.
A large chunk of complexity during package loading is globbing: Bazel does not
require every source file to be explicitly listed and instead can run globs
(such as `glob(["**/*.java"])`). Unlike the shell, it supports recursive globs that
descend into subdirectories (but not into subpackages). This requires access to
the file system and since that can be slow, we implement all sorts of tricks to
make it run in parallel and as efficiently as possible.
Globbing is implemented in the following classes:
* `LegacyGlobber`, a fast and blissfully Skyframe-unaware globber
* `SkyframeHybridGlobber`, a version that uses Skyframe and reverts back to
the legacy globber in order to avoid "Skyframe restarts" (described below)
The `Package` class itself contains some members that are exclusively used to
parse the "external" package (related to external dependencies) and which do not
make sense for real packages. This is
a design flaw because objects describing regular packages should not contain
fields that describe something else. These include:
* The repository mappings
* The registered toolchains
* The registered execution platforms
Ideally, there would be more separation between parsing the "external" package
from parsing regular packages so that `Package` does not need to cater for the
needs of both. This is unfortunately difficult to do because the two are
intertwined quite deeply.
### Labels, Targets, and Rules
Packages are composed of targets, which have the following types:
1. **Files:** things that are either the input or the output of the build. In
Bazel parlance, we call them *artifacts* (discussed elsewhere). Not all
files created during the build are targets; it's common for an output of
Bazel not to have an associated label.
2. **Rules:** these describe steps to derive their outputs from their inputs. They
are generally associated with a programming language (such as `cc_library`,
`java_library` or `py_library`), but there are some language-agnostic ones
(such as `genrule` or `filegroup`)
3. **Package groups:** discussed in the [Visibility](#visibility) section.
The name of a target is called a *Label*. The syntax of labels is
`@repo//pac/kage:name`, where `repo` is the name of the repository the Label is
in, `pac/kage` is the directory its `BUILD` file is in and `name` is the path of
the file (if the label refers to a source file) relative to the directory of the
package. When referring to a target on the command line, some parts of the label
can be omitted:
1. If the repository is omitted, the label is taken to be in the main
repository.
2. If the package part is omitted (such as `name` or `:name`), the label is taken
to be in the package of the current working directory (relative paths
containing uplevel references (..) are not allowed)
A kind of a rule (such as "C++ library") is called a "rule class". Rule classes may
be implemented either in Starlark (the `rule()` function) or in Java (so called
"native rules", type `RuleClass`). In the long term, every language-specific
rule will be implemented in Starlark, but some legacy rule families (such as Java
or C++) are still in Java for the time being.
Starlark rule classes need to be imported at the beginning of `BUILD` files
using the `load()` statement, whereas Java rule classes are "innately" known by
Bazel, by virtue of being registered with the `ConfiguredRuleClassProvider`.
Rule classes contain information such as:
1. Its attributes (such as `srcs`, `deps`): their types, default values,
constraints, etc.
2. The configuration transitions and aspects attached to each attribute, if any
3. The implementation of the rule
4. The transitive info providers the rule "usually" creates
**Terminology note:** In the codebase, we often use "Rule" to mean the target
created by a rule class. But in Starlark and in user-facing documentation,
"Rule" should be used exclusively to refer to the rule class itself; the target
is just a "target". Also note that despite `RuleClass` having "class" in its
name, there is no Java inheritance relationship between a rule class and targets
of that type.
## Skyframe
The evaluation framework underlying Bazel is called Skyframe. Its model is that
everything that needs to be built during a build is organized into a directed
acyclic graph with edges pointing from any piece of data to its dependencies,
that is, other pieces of data that need to be known to construct it.
The nodes in the graph are called `SkyValue`s and their names are called
`SkyKey`s. Both are deeply immutable; only immutable objects should be
reachable from them. This invariant almost always holds, and in case it doesn't
(such as for the individual options classes `BuildOptions`, which is a member of
`BuildConfigurationValue` and its `SkyKey`) we try really hard not to change
them or to change them in only ways that are not observable from the outside.
From this it follows that everything that is computed within Skyframe (such as
configured targets) must also be immutable.
The most convenient way to observe the Skyframe graph is to run `bazel dump --skyframe=deps`, which dumps the graph, one `SkyValue` per line. It's best
to do it for tiny builds, since it can get pretty large.
Skyframe lives in the `com.google.devtools.build.skyframe` package. The
similarly-named package `com.google.devtools.build.lib.skyframe` contains the
implementation of Bazel on top of Skyframe. More information about Skyframe is
available [here](/reference/skyframe).
To evaluate a given `SkyKey` into a `SkyValue`, Skyframe will invoke the
`SkyFunction` corresponding to the type of the key. During the function's
evaluation, it may request other dependencies from Skyframe by calling the
various overloads of `SkyFunction.Environment.getValue()`. This has the
side-effect of registering those dependencies into Skyframe's internal graph, so
that Skyframe will know to re-evaluate the function when any of its dependencies
change. In other words, Skyframe's caching and incremental computation work at
the granularity of `SkyFunction`s and `SkyValue`s.
Whenever a `SkyFunction` requests a dependency that is unavailable, `getValue()`
will return null. The function should then yield control back to Skyframe by
itself returning null. At some later point, Skyframe will evaluate the
unavailable dependency, then restart the function from the beginning — only this
time the `getValue()` call will succeed with a non-null result.
A consequence of this is that any computation performed inside the `SkyFunction`
prior to the restart must be repeated. But this does not include work done to
evaluate dependency `SkyValues`, which are cached. Therefore, we commonly work
around this issue by:
1. Declaring dependencies in batches (by using `getValuesAndExceptions()`) to
limit the number of restarts.
2. Breaking up a `SkyValue` into separate pieces computed by different
`SkyFunction`s, so that they can be computed and cached independently. This
should be done strategically, since it has the potential to increase memory
usage.
3. Storing state between restarts, either using
`SkyFunction.Environment.getState()`, or keeping an ad hoc static cache
"behind the back of Skyframe". With complex SkyFunctions, state management
between restarts can get tricky, so
[`StateMachine`s](/contribute/statemachine-guide) were introduced for a
structured approach to logical concurrency, including hooks to suspend and
resume hierarchical computations within a `SkyFunction`. Example:
[`DependencyResolver#computeDependencies`][statemachine_example]
uses a `StateMachine` with `getState()` to compute the potentially huge set
of direct dependencies of a configured target, which otherwise can result in
expensive restarts.
[statemachine_example]: https://developers.google.com/devsite/reference/markdown/links#reference_links
Fundamentally, Bazel needs these types of workarounds because hundreds of
thousands of in-flight Skyframe nodes is common, and Java's support of
lightweight threads [does not outperform][virtual_threads] the
`StateMachine` implementation as of 2023.
[virtual_threads]: /contribute/statemachine-guide#epilogue_eventually_removing_callbacks
## Starlark
Starlark is the domain-specific language people use to configure and extend
Bazel. It's conceived as a restricted subset of Python that has far fewer types,
more restrictions on control flow, and most importantly, strong immutability
guarantees to enable concurrent reads. It is not Turing-complete, which
discourages some (but not all) users from trying to accomplish general
programming tasks within the language.
Starlark is implemented in the `net.starlark.java` package.
It also has an independent Go implementation
[here](https://github.com/google/starlark-go). The Java
implementation used in Bazel is currently an interpreter.
Starlark is used in several contexts, including:
1. **`BUILD` files.** This is where new build targets are defined. Starlark
code running in this context only has access to the contents of the `BUILD`
file itself and `.bzl` files loaded by it.
2. **The `MODULE.bazel` file.** This is where external dependencies are
defined. Starlark code running in this context only has very limited access
to a few predefined directives.
3. **`.bzl` files.** This is where new build rules, repo rules, module
extensions are defined. Starlark code here can define new functions and load
from other `.bzl` files.
The dialects available for `BUILD` and `.bzl` files are slightly different
because they express different things. A list of differences is available
[here](/rules/language#differences-between-build-and-bzl-files).
More information about Starlark is available [here](/rules/language).
## The loading/analysis phase
The loading/analysis phase is where Bazel determines what actions are needed to
build a particular rule. Its basic unit is a "configured target", which is,
quite sensibly, a (target, configuration) pair.
It's called the "loading/analysis phase" because it can be split into two
distinct parts, which used to be serialized, but they can now overlap in time:
1. Loading packages, that is, turning `BUILD` files into the `Package` objects
that represent them
2. Analyzing configured targets, that is, running the implementation of the
rules to produce the action graph
Each configured target in the transitive closure of the configured targets
requested on the command line must be analyzed bottom-up; that is, leaf nodes
first, then up to the ones on the command line. The inputs to the analysis of
a single configured target are:
1. **The configuration.** ("how" to build that rule; for example, the target
platform but also things like command line options the user wants to be
passed to the C++ compiler)
2. **The direct dependencies.** Their transitive info providers are available
to the rule being analyzed. They are called like that because they provide a
"roll-up" of the information in the transitive closure of the configured
target, such as all the .jar files on the classpath or all the .o files that
need to be linked into a C++ binary)
3. **The target itself**. This is the result of loading the package the target
is in. For rules, this includes its attributes, which is usually what
matters.
4. **The implementation of the configured target.** For rules, this can either
be in Starlark or in Java. All non-rule configured targets are implemented
in Java.
The output of analyzing a configured target is:
1. The transitive info providers that configured targets that depend on it can
access
2. The artifacts it can create and the actions that produce them.
The API offered to Java rules is `RuleContext`, which is the equivalent of the
`ctx` argument of Starlark rules. Its API is more powerful, but at the same
time, it's easier to do Bad Things™, for example to write code whose time or
space complexity is quadratic (or worse), to make the Bazel server crash with a
Java exception or to violate invariants (such as by inadvertently modifying an
`Options` instance or by making a configured target mutable)
The algorithm that determines the direct dependencies of a configured target
lives in `DependencyResolver.dependentNodeMap()`.
### Configurations
Configurations are the "how" of building a target: for what platform, with what
command line options, etc.
The same target can be built for multiple configurations in the same build. This
is useful, for example, when the same code is used for a tool that's run during
the build and for the target code and we are cross-compiling or when we are
building a fat Android app (one that contains native code for multiple CPU
architectures)
Conceptually, the configuration is a `BuildOptions` instance. However, in
practice, `BuildOptions` is wrapped by `BuildConfiguration` that provides
additional sundry pieces of functionality. It propagates from the top of the
dependency graph to the bottom. If it changes, the build needs to be
re-analyzed.
This results in anomalies like having to re-analyze the whole build if, for
example, the number of requested test runs changes, even though that only
affects test targets (we have plans to "trim" configurations so that this is
not the case, but it's not ready yet).
When a rule implementation needs part of the configuration, it needs to declare
it in its definition using `RuleClass.Builder.requiresConfigurationFragments()`.
This is both to avoid mistakes (such as Python rules using the Java fragment) and
to facilitate configuration trimming so that if Python options change, C++
targets don't need to be re-analyzed.
The configuration of a rule is not necessarily the same as that of its "parent"
rule. The process of changing the configuration in a dependency edge is called a
"configuration transition". It can happen in two places:
1. On a dependency edge. These transitions are specified in
`Attribute.Builder.cfg()` and are functions from a `Rule` (where the
transition happens) and a `BuildOptions` (the original configuration) to one
or more `BuildOptions` (the output configuration).
2. On any incoming edge to a configured target. These are specified in
`RuleClass.Builder.cfg()`.
The relevant classes are `TransitionFactory` and `ConfigurationTransition`.
Configuration transitions are used, for example:
1. To declare that a particular dependency is used during the build and it
should thus be built in the execution architecture
2. To declare that a particular dependency must be built for multiple
architectures (such as for native code in fat Android APKs)
If a configuration transition results in multiple configurations, it's called a
*split transition.*
Configuration transitions can also be implemented in Starlark (documentation
[here](/extending/config))
### Transitive info providers
Transitive info providers are a way (and the *only* way) for configured targets
to learn things about other configured targets that they depend on, and the only
way to tell things about themselves to other configured targets that depend on
them. The reason why "transitive" is in their name is that this is usually some
sort of roll-up of the transitive closure of a configured target.
There is generally a 1:1 correspondence between Java transitive info providers
and Starlark ones (the exception is `DefaultInfo` which is an amalgamation of
`FileProvider`, `FilesToRunProvider` and `RunfilesProvider` because that API was
deemed to be more Starlark-ish than a direct transliteration of the Java one).
Their key is one of the following things:
1. A Java Class object. This is only available for providers that are not
accessible from Starlark. These providers are a subclass of
`TransitiveInfoProvider`.
2. A string. This is legacy and heavily discouraged since it's susceptible to
name clashes. Such transitive info providers are direct subclasses of
`build.lib.packages.Info` .
3. A provider symbol. This can be created from Starlark using the `provider()`
function and is the recommended way to create new providers. The symbol is
represented by a `Provider.Key` instance in Java.
New providers implemented in Java should be implemented using `BuiltinProvider`.
`NativeProvider` is deprecated (we haven't had time to remove it yet) and
`TransitiveInfoProvider` subclasses cannot be accessed from Starlark.
### Configured targets
Configured targets are implemented as `RuleConfiguredTargetFactory`. There is a
subclass for each rule class implemented in Java. Starlark configured targets
are created through `StarlarkRuleConfiguredTargetUtil.buildRule()` .
Configured target factories should use `RuleConfiguredTargetBuilder` to
construct their return value. It consists of the following things:
1. Their `filesToBuild`, the hazy concept of "the set of files this rule
represents." These are the files that get built when the configured target
is on the command line or in the srcs of a genrule.
2. Their runfiles, regular and data.
3. Their output groups. These are various "other sets of files" the rule can
build. They can be accessed using the output\_group attribute of the
filegroup rule in BUILD and using the `OutputGroupInfo` provider in Java.
### Runfiles
Some binaries need data files to run. A prominent example is tests that need
input files. This is represented in Bazel by the concept of "runfiles". A
"runfiles tree" is a directory tree of the data files for a particular binary.
It is created in the file system as a symlink tree with individual symlinks
pointing to the files in the source or output trees.
A set of runfiles is represented as a `Runfiles` instance. It is conceptually a
map from the path of a file in the runfiles tree to the `Artifact` instance that
represents it. It's a little more complicated than a single `Map` for two
reasons:
* Most of the time, the runfiles path of a file is the same as its execpath.
We use this to save some RAM.
* There are various legacy kinds of entries in runfiles trees, which also need
to be represented.
Runfiles are collected using `RunfilesProvider`: an instance of this class
represents the runfiles a configured target (such as a library) and its transitive
closure needs and they are gathered like a nested set (in fact, they are
implemented using nested sets under the cover): each target unions the runfiles
of its dependencies, adds some of its own, then sends the resulting set upwards
in the dependency graph. A `RunfilesProvider` instance contains two `Runfiles`
instances, one for when the rule is depended on through the "data" attribute and
one for every other kind of incoming dependency. This is because a target
sometimes presents different runfiles when depended on through a data attribute
than otherwise. This is undesired legacy behavior that we haven't gotten around
removing yet.
Runfiles of binaries are represented as an instance of `RunfilesSupport`. This
is different from `Runfiles` because `RunfilesSupport` has the capability of
actually being built (unlike `Runfiles`, which is just a mapping). This
necessitates the following additional components:
* **The input runfiles manifest.** This is a serialized description of the
runfiles tree. It is used as a proxy for the contents of the runfiles tree
and Bazel assumes that the runfiles tree changes if and only if the contents
of the manifest change.
* **The output runfiles manifest.** This is used by runtime libraries that
handle runfiles trees, notably on Windows, which sometimes doesn't support
symbolic links.
* **Command line arguments** for running the binary whose runfiles the
`RunfilesSupport` object represents.
### Aspects
Aspects are a way to "propagate computation down the dependency graph". They are
described for users of Bazel
[here](/extending/aspects). A good
motivating example is protocol buffers: a `proto_library` rule should not know
about any particular language, but building the implementation of a protocol
buffer message (the "basic unit" of protocol buffers) in any programming
language should be coupled to the `proto_library` rule so that if two targets in
the same language depend on the same protocol buffer, it gets built only once.
Just like configured targets, they are represented in Skyframe as a `SkyValue`
and the way they are constructed is very similar to how configured targets are
built: they have a factory class called `ConfiguredAspectFactory` that has
access to a `RuleContext`, but unlike configured target factories, it also knows
about the configured target it is attached to and its providers.
The set of aspects propagated down the dependency graph is specified for each
attribute using the `Attribute.Builder.aspects()` function. There are a few
confusingly-named classes that participate in the process:
1. `AspectClass` is the implementation of the aspect. It can be either in Java
(in which case it's a subclass) or in Starlark (in which case it's an
instance of `StarlarkAspectClass`). It's analogous to
`RuleConfiguredTargetFactory`.
2. `AspectDefinition` is the definition of the aspect; it includes the
providers it requires, the providers it provides and contains a reference to
its implementation, such as the appropriate `AspectClass` instance. It's
analogous to `RuleClass`.
3. `AspectParameters` is a way to parametrize an aspect that is propagated down
the dependency graph. It's currently a string to string map. A good example
of why it's useful is protocol buffers: if a language has multiple APIs, the
information as to which API the protocol buffers should be built for should
be propagated down the dependency graph.
4. `Aspect` represents all the data that's needed to compute an aspect that
propagates down the dependency graph. It consists of the aspect class, its
definition and its parameters.
5. `RuleAspect` is the function that determines which aspects a particular rule
should propagate. It's a `Rule` -> `Aspect` function.
A somewhat unexpected complication is that aspects can attach to other aspects;
for example, an aspect collecting the classpath for a Java IDE will probably
want to know about all the .jar files on the classpath, but some of them are
protocol buffers. In that case, the IDE aspect will want to attach to the
(`proto_library` rule + Java proto aspect) pair.
The complexity of aspects on aspects is captured in the class
`AspectCollection`.
### Platforms and toolchains
Bazel supports multi-platform builds, that is, builds where there may be
multiple architectures where build actions run and multiple architectures for
which code is built. These architectures are referred to as *platforms* in Bazel
parlance (full documentation
[here](/extending/platforms))
A platform is described by a key-value mapping from *constraint settings* (such as
the concept of "CPU architecture") to *constraint values* (such as a particular CPU
like x86\_64). We have a "dictionary" of the most commonly used constraint
settings and values in the `@platforms` repository.
The concept of *toolchain* comes from the fact that depending on what platforms
the build is running on and what platforms are targeted, one may need to use
different compilers; for example, a particular C++ toolchain may run on a
specific OS and be able to target some other OSes. Bazel must determine the C++
compiler that is used based on the set execution and target platforms
(documentation for toolchains
[here](/extending/toolchains)).
In order to do this, toolchains are annotated with the set of execution and
target platform constraints they support. In order to do this, the definition of
a toolchain is split into two parts:
1. A `toolchain()` rule that describes the set of execution and target
constraints a toolchain supports and tells what kind (such as C++ or Java) of
toolchain it is (the latter is represented by the `toolchain_type()` rule)
2. A language-specific rule that describes the actual toolchain (such as
`cc_toolchain()`)
This is done in this way because we need to know the constraints for every
toolchain in order to do toolchain resolution and language-specific
`*_toolchain()` rules contain much more information than that, so they take more
time to load.
Execution platforms are specified in one of the following ways:
1. In the MODULE.bazel file using the `register_execution_platforms()` function
2. On the command line using the --extra\_execution\_platforms command line
option
The set of available execution platforms is computed in
`RegisteredExecutionPlatformsFunction` .
The target platform for a configured target is determined by
`PlatformOptions.computeTargetPlatform()` . It's a list of platforms because we
eventually want to support multiple target platforms, but it's not implemented
yet.
The set of toolchains to be used for a configured target is determined by
`ToolchainResolutionFunction`. It is a function of:
* The set of registered toolchains (in the MODULE.bazel file and the
configuration)
* The desired execution and target platforms (in the configuration)
* The set of toolchain types that are required by the configured target (in
`UnloadedToolchainContextKey)`
* The set of execution platform constraints of the configured target (the
`exec_compatible_with` attribute), in `UnloadedToolchainContextKey`
Its result is an `UnloadedToolchainContext`, which is essentially a map from
toolchain type (represented as a `ToolchainTypeInfo` instance) to the label of
the selected toolchain. It's called "unloaded" because it does not contain the
toolchains themselves, only their labels.
Then the toolchains are actually loaded using `ResolvedToolchainContext.load()`
and used by the implementation of the configured target that requested them.
We also have a legacy system that relies on there being one single "host"
configuration and target configurations being represented by various
configuration flags, such as `--cpu` . We are gradually transitioning to the above
system. In order to handle cases where people rely on the legacy configuration
values, we have implemented
[platform mappings](https://docs.google.com/document/d/1Vg_tPgiZbSrvXcJ403vZVAGlsWhH9BUDrAxMOYnO0Ls)
to translate between the legacy flags and the new-style platform constraints.
Their code is in `PlatformMappingFunction` and uses a non-Starlark "little
language".
### Constraints
Sometimes one wants to designate a target as being compatible with only a few
platforms. Bazel has (unfortunately) multiple mechanisms to achieve this end:
* Rule-specific constraints
* `environment_group()` / `environment()`
* Platform constraints
Rule-specific constraints are mostly used within Google for Java rules; they are
on their way out and they are not available in Bazel, but the source code may
contain references to it. The attribute that governs this is called
`constraints=` .
#### environment\_group() and environment()
These rules are a legacy mechanism and are not widely used.
All build rules can declare which "environments" they can be built for, where an
"environment" is an instance of the `environment()` rule.
There are various ways supported environments can be specified for a rule:
1. Through the `restricted_to=` attribute. This is the most direct form of
specification; it declares the exact set of environments the rule supports.
2. Through the `compatible_with=` attribute. This declares environments a rule
supports in addition to "standard" environments that are supported by
default.
3. Through the package-level attributes `default_restricted_to=` and
`default_compatible_with=`.
4. Through default specifications in `environment_group()` rules. Every
environment belongs to a group of thematically related peers (such as "CPU
architectures", "JDK versions" or "mobile operating systems"). The
definition of an environment group includes which of these environments
should be supported by "default" if not otherwise specified by the
`restricted_to=` / `environment()` attributes. A rule with no such
attributes inherits all defaults.
5. Through a rule class default. This overrides global defaults for all
instances of the given rule class. This can be used, for example, to make
all `*_test` rules testable without each instance having to explicitly
declare this capability.
`environment()` is implemented as a regular rule whereas `environment_group()`
is both a subclass of `Target` but not `Rule` (`EnvironmentGroup`) and a
function that is available by default from Starlark
(`StarlarkLibrary.environmentGroup()`) which eventually creates an eponymous
target. This is to avoid a cyclic dependency that would arise because each
environment needs to declare the environment group it belongs to and each
environment group needs to declare its default environments.
A build can be restricted to a certain environment with the
`--target_environment` command line option.
The implementation of the constraint check is in
`RuleContextConstraintSemantics` and `TopLevelConstraintSemantics`.
#### Platform constraints
The current "official" way to describe what platforms a target is compatible
with is by using the same constraints used to describe toolchains and platforms.
It was implemented in pull request
[#10945](https://github.com/bazelbuild/bazel/pull/10945).
### Visibility
If you work on a large codebase with a lot of developers (like at Google), you
want to take care to prevent everyone else from arbitrarily depending on your
code. Otherwise, as per [Hyrum's law](https://www.hyrumslaw.com/),
people *will* come to rely on behaviors that you considered to be implementation
details.
Bazel supports this by the mechanism called *visibility*: you can limit which
targets can depend on a particular target using the
[visibility](/reference/be/common-definitions#common-attributes) attribute. This
attribute is a little special because, although it holds a list of labels, these
labels may encode a pattern over package names rather than a pointer to any
particular target. (Yes, this is a design flaw.)
This is implemented in the following places:
* The `RuleVisibility` interface represents a visibility declaration. It can
be either a constant (fully public or fully private) or a list of labels.
* Labels can refer to either package groups (predefined list of packages), to
packages directly (`//pkg:__pkg__`) or subtrees of packages
(`//pkg:__subpackages__`). This is different from the command line syntax,
which uses `//pkg:*` or `//pkg/...`.
* Package groups are implemented as their own target (`PackageGroup`) and
configured target (`PackageGroupConfiguredTarget`). We could probably
replace these with simple rules if we wanted to. Their logic is implemented
with the help of: `PackageSpecification`, which corresponds to a
single pattern like `//pkg/...`; `PackageGroupContents`, which corresponds
to a single `package_group`'s `packages` attribute; and
`PackageSpecificationProvider`, which aggregates over a `package_group` and
its transitive `includes`.
* The conversion from visibility label lists to dependencies is done in
`DependencyResolver.visitTargetVisibility` and a few other miscellaneous
places.
* The actual check is done in
`CommonPrerequisiteValidator.validateDirectPrerequisiteVisibility()`
### Nested sets
Oftentimes, a configured target aggregates a set of files from its dependencies,
adds its own, and wraps the aggregate set into a transitive info provider so
that configured targets that depend on it can do the same. Examples:
* The C++ header files used for a build
* The object files that represent the transitive closure of a `cc_library`
* The set of .jar files that need to be on the classpath for a Java rule to
compile or run
* The set of Python files in the transitive closure of a Python rule
If we did this the naive way by using, for example, `List` or `Set`, we'd end up with
quadratic memory usage: if there is a chain of N rules and each rule adds a
file, we'd have 1+2+...+N collection members.
In order to get around this problem, we came up with the concept of a
`NestedSet`. It's a data structure that is composed of other `NestedSet`
instances and some members of its own, thereby forming a directed acyclic graph
of sets. They are immutable and their members can be iterated over. We define
multiple iteration orders (`NestedSet.Order`): preorder, postorder, topological
(a node always comes after its ancestors) and "don't care, but it should be the
same each time".
The same data structure is called `depset` in Starlark.
### Artifacts and Actions
The actual build consists of a set of commands that need to be run to produce
the output the user wants. The commands are represented as instances of the
class `Action` and the files are represented as instances of the class
`Artifact`. They are arranged in a bipartite, directed, acyclic graph called the
"action graph".
Artifacts come in two kinds: source artifacts (ones that are available
before Bazel starts executing) and derived artifacts (ones that need to be
built). Derived artifacts can themselves be multiple kinds:
1. **Regular artifacts.** These are checked for up-to-dateness by computing
their checksum, with mtime as a shortcut; we don't checksum the file if its
ctime hasn't changed.
2. **Unresolved symlink artifacts.** These are checked for up-to-dateness by
calling readlink(). Unlike regular artifacts, these can be dangling
symlinks. Usually used in cases where one then packs up some files into an
archive of some sort.
3. **Tree artifacts.** These are not single files, but directory trees. They
are checked for up-to-dateness by checking the set of files in it and their
contents. They are represented as a `TreeArtifact`.
4. **Constant metadata artifacts.** Changes to these artifacts don't trigger a
rebuild. This is used exclusively for build stamp information: we don't want
to do a rebuild just because the current time changed.
There is no fundamental reason why source artifacts cannot be tree artifacts or
unresolved symlink artifacts; it's just that we haven't implemented it yet. At
the moment, source symlinks are always resolved, and while source directories
are supported, their contents are entirely opaque to build rules and thus don't
support the same kind of lazy command line expansion as tree artifacts do.
Actions are best understood as a command that needs to be run, the environment
it needs and the set of outputs it produces. The following things are the main
components of the description of an action:
* The command line that needs to be run
* The input artifacts it needs
* The environment variables that need to be set
* Annotations that describe the environment (such as platform) it needs to run in
\\
There are also a few other special cases, like writing a file whose content is
known to Bazel. They are a subclass of `AbstractAction`. Most of the actions are
a `SpawnAction` or a `StarlarkAction` (the same, they should arguably not be
separate classes), although Java and C++ have their own action types
(`JavaCompileAction`, `CppCompileAction` and `CppLinkAction`).
We eventually want to move everything to `SpawnAction`; `JavaCompileAction` is
pretty close, but C++ is a bit of a special-case due to .d file parsing and
include scanning.
The action graph is mostly "embedded" into the Skyframe graph: conceptually, the
execution of an action is represented as an invocation of
`ActionExecutionFunction`. The mapping from an action graph dependency edge to a
Skyframe dependency edge is described in
`ActionExecutionFunction.getInputDeps()` and `Artifact.key()` and has a few
optimizations in order to keep the number of Skyframe edges low:
* Derived artifacts do not have their own `SkyValue`s. Instead,
`Artifact.getGeneratingActionKey()` is used to find out the key for the
action that generates it
* Nested sets have their own Skyframe key.
### Shared actions
Some actions are generated by multiple configured targets; Starlark rules are
more limited since they are only allowed to put their derived actions into a
directory determined by their configuration and their package (but even so,
rules in the same package can conflict), but rules implemented in Java can put
derived artifacts anywhere.
This is considered to be a misfeature, but getting rid of it is really hard
because it produces significant savings in execution time when, for example, a
source file needs to be processed somehow and that file is referenced by
multiple rules (handwave-handwave). This comes at the cost of some RAM: each
instance of a shared action needs to be stored in memory separately.
If two actions generate the same output file, they must be exactly the same:
have the same inputs, the same outputs and run the same command line. This
equivalence relation is implemented in `Actions.canBeShared()` and it is
verified between the analysis and execution phases by looking at every Action.
This is implemented in `SkyframeActionExecutor.findAndStoreArtifactConflicts()`
and is one of the few places in Bazel that requires a "global" view of the
build.
## The execution phase
This is when Bazel actually starts running build actions, such as commands that
produce outputs.
The first thing Bazel does after the analysis phase is to determine what
Artifacts need to be built. The logic for this is encoded in
`TopLevelArtifactHelper`; roughly speaking, it's the `filesToBuild` of the
configured targets on the command line and the contents of a special output
group for the explicit purpose of expressing "if this target is on the command
line, build these artifacts".
The next step is creating the execution root. Since Bazel has the option to read
source packages from different locations in the file system (`--package_path`),
it needs to provide locally executed actions with a full source tree. This is
handled by the class `SymlinkForest` and works by taking note of every target
used in the analysis phase and building up a single directory tree that symlinks
every package with a used target from its actual location. An alternative would
be to pass the correct paths to commands (taking `--package_path` into account).
This is undesirable because:
* It changes action command lines when a package is moved from a package path
entry to another (used to be a common occurrence)
* It results in different command lines if an action is run remotely than if
it's run locally
* It requires a command line transformation specific to the tool in use
(consider the difference between such as Java classpaths and C++ include paths)
* Changing the command line of an action invalidates its action cache entry
* `--package_path` is slowly and steadily being deprecated
Then, Bazel starts traversing the action graph (the bipartite, directed graph
composed of actions and their input and output artifacts) and running actions.
The execution of each action is represented by an instance of the `SkyValue`
class `ActionExecutionValue`.
Since running an action is expensive, we have a few layers of caching that can
be hit behind Skyframe:
* `ActionExecutionFunction.stateMap` contains data to make Skyframe restarts
of `ActionExecutionFunction` cheap
* The local action cache contains data about the state of the file system
* Remote execution systems usually also contain their own cache
### The local action cache
This cache is another layer that sits behind Skyframe; even if an action is
re-executed in Skyframe, it can still be a hit in the local action cache. It
represents the state of the local file system and it's serialized to disk which
means that when one starts up a new Bazel server, one can get local action cache
hits even though the Skyframe graph is empty.
This cache is checked for hits using the method
`ActionCacheChecker.getTokenIfNeedToExecute()` .
Contrary to its name, it's a map from the path of a derived artifact to the
action that emitted it. The action is described as:
1. The set of its input and output files and their checksum
2. Its "action key", which is usually the command line that was executed, but
in general, represents everything that's not captured by the checksum of the
input files (such as for `FileWriteAction`, it's the checksum of the data
that's written)
There is also a highly experimental "top-down action cache" that is still under
development, which uses transitive hashes to avoid going to the cache as many
times.
### Input discovery and input pruning
Some actions are more complicated than just having a set of inputs. Changes to
the set of inputs of an action come in two forms:
* An action may discover new inputs before its execution or decide that some
of its inputs are not actually necessary. The canonical example is C++,
where it's better to make an educated guess about what header files a C++
file uses from its transitive closure so that we don't need to send every
file to remote executors; therefore, we have an option not to register every
header file as an "input", but scan the source file for transitively
included headers and only mark those header files as inputs that are
mentioned in `#include` statements (we overestimate so that we don't need to
implement a full C preprocessor) This option is currently hard-wired to
"false" in Bazel and is only used at Google.
* An action may realize that some files were not used during its execution. In
C++, this is called ".d files": the compiler tells which header files were
used after the fact, and in order to avoid the embarrassment of having worse
incrementality than Make, Bazel makes use of this fact. This offers a better
estimate than the include scanner because it relies on the compiler.
These are implemented using methods on Action:
1. `Action.discoverInputs()` is called. It should return a nested set of
Artifacts that are determined to be required. These must be source artifacts
so that there are no dependency edges in the action graph that don't have an
equivalent in the configured target graph.
2. The action is executed by calling `Action.execute()`.
3. At the end of `Action.execute()`, the action can call
`Action.updateInputs()` to tell Bazel that not all of its inputs were
needed. This can result in incorrect incremental builds if a used input is
reported as unused.
When an action cache returns a hit on a fresh Action instance (such as created
after a server restart), Bazel calls `updateInputs()` itself so that the set of
inputs reflects the result of input discovery and pruning done before.
Starlark actions can make use of the facility to declare some inputs as unused
using the `unused_inputs_list=` argument of
`ctx.actions.run()`.
### Various ways to run actions: Strategies/ActionContexts
Some actions can be run in different ways. For example, a command line can be
executed locally, locally but in various kinds of sandboxes, or remotely. The
concept that embodies this is called an `ActionContext` (or `Strategy`, since we
successfully went only halfway with a rename...)
The life cycle of an action context is as follows:
1. When the execution phase is started, `BlazeModule` instances are asked what
action contexts they have. This happens in the constructor of
`ExecutionTool`. Action context types are identified by a Java `Class`
instance that refers to a sub-interface of `ActionContext` and which
interface the action context must implement.
2. The appropriate action context is selected from the available ones and is
forwarded to `ActionExecutionContext` and `BlazeExecutor` .
3. Actions request contexts using `ActionExecutionContext.getContext()` and
`BlazeExecutor.getStrategy()` (there should really be only one way to do
it…)
Strategies are free to call other strategies to do their jobs; this is used, for
example, in the dynamic strategy that starts actions both locally and remotely,
then uses whichever finishes first.
One notable strategy is the one that implements persistent worker processes
(`WorkerSpawnStrategy`). The idea is that some tools have a long startup time
and should therefore be reused between actions instead of starting one anew for
every action (This does represent a potential correctness issue, since Bazel
relies on the promise of the worker process that it doesn't carry observable
state between individual requests)
If the tool changes, the worker process needs to be restarted. Whether a worker
can be reused is determined by computing a checksum for the tool used using
`WorkerFilesHash`. It relies on knowing which inputs of the action represent
part of the tool and which represent inputs; this is determined by the creator
of the Action: `Spawn.getToolFiles()` and the runfiles of the `Spawn` are
counted as parts of the tool.
More information about strategies (or action contexts!):
* Information about various strategies for running actions is available
[here](https://jmmv.dev/2019/12/bazel-strategies.html).
* Information about the dynamic strategy, one where we run an action both
locally and remotely to see whichever finishes first is available
[here](https://jmmv.dev/series.html#Bazel%20dynamic%20execution).
* Information about the intricacies of executing actions locally is available
[here](https://jmmv.dev/2019/11/bazel-process-wrapper.html).
### The local resource manager
Bazel *can* run many actions in parallel. The number of local actions that
*should* be run in parallel differs from action to action: the more resources an
action requires, the fewer instances should be running at the same time to avoid
overloading the local machine.
This is implemented in the class `ResourceManager`: each action has to be
annotated with an estimate of the local resources it requires in the form of a
`ResourceSet` instance (CPU and RAM). Then when action contexts do something
that requires local resources, they call `ResourceManager.acquireResources()`
and are blocked until the required resources are available.
A more detailed description of local resource management is available
[here](https://jmmv.dev/2019/12/bazel-local-resources.html).
### The structure of the output directory
Each action requires a separate place in the output directory where it places
its outputs. The location of derived artifacts is usually as follows:
```
$EXECROOT/bazel-out//bin//
```
How is the name of the directory that is associated with a particular
configuration determined? There are two conflicting desirable properties:
1. If two configurations can occur in the same build, they should have
different directories so that both can have their own version of the same
action; otherwise, if the two configurations disagree about such as the command
line of an action producing the same output file, Bazel doesn't know which
action to choose (an "action conflict")
2. If two configurations represent "roughly" the same thing, they should have
the same name so that actions executed in one can be reused for the other if
the command lines match: for example, changes to the command line options to
the Java compiler should not result in C++ compile actions being re-run.
So far, we have not come up with a principled way of solving this problem, which
has similarities to the problem of configuration trimming. A longer discussion
of options is available
[here](https://docs.google.com/document/d/1fZI7wHoaS-vJvZy9SBxaHPitIzXE_nL9v4sS4mErrG4/edit).
The main problematic areas are Starlark rules (whose authors usually aren't
intimately familiar with Bazel) and aspects, which add another dimension to the
space of things that can produce the "same" output file.
The current approach is that the path segment for the configuration is
`-` with various suffixes added so that configuration
transitions implemented in Java don't result in action conflicts. In addition, a
checksum of the set of Starlark configuration transitions is added so that users
can't cause action conflicts. It is far from perfect. This is implemented in
`OutputDirectories.buildMnemonic()` and relies on each configuration fragment
adding its own part to the name of the output directory.
## Tests
Bazel has rich support for running tests. It supports:
* Running tests remotely (if a remote execution backend is available)
* Running tests multiple times in parallel (for deflaking or gathering timing
data)
* Sharding tests (splitting test cases in same test over multiple processes
for speed)
* Re-running flaky tests
* Grouping tests into test suites
Tests are regular configured targets that have a TestProvider, which describes
how the test should be run:
* The artifacts whose building result in the test being run. This is a "cache
status" file that contains a serialized `TestResultData` message
* The number of times the test should be run
* The number of shards the test should be split into
* Some parameters about how the test should be run (such as the test timeout)
### Determining which tests to run
Determining which tests are run is an elaborate process.
First, during target pattern parsing, test suites are recursively expanded. The
expansion is implemented in `TestsForTargetPatternFunction`. A somewhat
surprising wrinkle is that if a test suite declares no tests, it refers to
*every* test in its package. This is implemented in `Package.beforeBuild()` by
adding an implicit attribute called `$implicit_tests` to test suite rules.
Then, tests are filtered for size, tags, timeout and language according to the
command line options. This is implemented in `TestFilter` and is called from
`TargetPatternPhaseFunction.determineTests()` during target parsing and the
result is put into `TargetPatternPhaseValue.getTestsToRunLabels()`. The reason
why rule attributes which can be filtered for are not configurable is that this
happens before the analysis phase, therefore, the configuration is not
available.
This is then processed further in `BuildView.createResult()`: targets whose
analysis failed are filtered out and tests are split into exclusive and
non-exclusive tests. It's then put into `AnalysisResult`, which is how
`ExecutionTool` knows which tests to run.
In order to lend some transparency to this elaborate process, the `tests()`
query operator (implemented in `TestsFunction`) is available to tell which tests
are run when a particular target is specified on the command line. It's
unfortunately a reimplementation, so it probably deviates from the above in
multiple subtle ways.
### Running tests
The way the tests are run is by requesting cache status artifacts. This then
results in the execution of a `TestRunnerAction`, which eventually calls the
`TestActionContext` chosen by the `--test_strategy` command line option that
runs the test in the requested way.
Tests are run according to an elaborate protocol that uses environment variables
to tell tests what's expected from them. A detailed description of what Bazel
expects from tests and what tests can expect from Bazel is available
[here](/reference/test-encyclopedia). At the
simplest, an exit code of 0 means success, anything else means failure.
In addition to the cache status file, each test process emits a number of other
files. They are put in the "test log directory" which is the subdirectory called
`testlogs` of the output directory of the target configuration:
* `test.xml`, a JUnit-style XML file detailing the individual test cases in
the test shard
* `test.log`, the console output of the test. stdout and stderr are not
separated.
* `test.outputs`, the "undeclared outputs directory"; this is used by tests
that want to output files in addition to what they print to the terminal.
There are two things that can happen during test execution that cannot during
building regular targets: exclusive test execution and output streaming.
Some tests need to be executed in exclusive mode, for example not in parallel with
other tests. This can be elicited either by adding `tags=["exclusive"]` to the
test rule or running the test with `--test_strategy=exclusive` . Each exclusive
test is run by a separate Skyframe invocation requesting the execution of the
test after the "main" build. This is implemented in
`SkyframeExecutor.runExclusiveTest()`.
Unlike regular actions, whose terminal output is dumped when the action
finishes, the user can request the output of tests to be streamed so that they
get informed about the progress of a long-running test. This is specified by the
`--test_output=streamed` command line option and implies exclusive test
execution so that outputs of different tests are not interspersed.
This is implemented in the aptly-named `StreamedTestOutput` class and works by
polling changes to the `test.log` file of the test in question and dumping new
bytes to the terminal where Bazel runs.
Results of the executed tests are available on the event bus by observing
various events (such as `TestAttempt`, `TestResult` or `TestingCompleteEvent`).
They are dumped to the Build Event Protocol and they are emitted to the console
by `AggregatingTestListener`.
### Coverage collection
Coverage is reported by the tests in LCOV format in the files
`bazel-testlogs/$PACKAGE/$TARGET/coverage.dat` .
To collect coverage, each test execution is wrapped in a script called
`collect_coverage.sh` .
This script sets up the environment of the test to enable coverage collection
and determine where the coverage files are written by the coverage runtime(s).
It then runs the test. A test may itself run multiple subprocesses and consist
of parts written in multiple different programming languages (with separate
coverage collection runtimes). The wrapper script is responsible for converting
the resulting files to LCOV format if necessary, and merges them into a single
file.
The interposition of `collect_coverage.sh` is done by the test strategies and
requires `collect_coverage.sh` to be on the inputs of the test. This is
accomplished by the implicit attribute `:coverage_support` which is resolved to
the value of the configuration flag `--coverage_support` (see
`TestConfiguration.TestOptions.coverageSupport`)
Some languages do offline instrumentation, meaning that the coverage
instrumentation is added at compile time (such as C++) and others do online
instrumentation, meaning that coverage instrumentation is added at execution
time.
Another core concept is *baseline coverage*. This is the coverage of a library,
binary, or test if no code in it was run. The problem it solves is that if you
want to compute the test coverage for a binary, it is not enough to merge the
coverage of all of the tests because there may be code in the binary that is not
linked into any test. Therefore, what we do is to emit a coverage file for every
binary which contains only the files we collect coverage for with no covered
lines. The default baseline coverage file for a target is at
`bazel-testlogs/$PACKAGE/$TARGET/baseline_coverage.dat`, but rules are
encouraged to generate their own baseline coverage files with more meaningful
content than just the names of the source files.
We track two groups of files for coverage collection for each rule: the set of
instrumented files and the set of instrumentation metadata files.
The set of instrumented files is just that, a set of files to instrument. For
online coverage runtimes, this can be used at runtime to decide which files to
instrument. It is also used to implement baseline coverage.
The set of instrumentation metadata files is the set of extra files a test needs
to generate the LCOV files Bazel requires from it. In practice, this consists of
runtime-specific files; for example, gcc emits .gcno files during compilation.
These are added to the set of inputs of test actions if coverage mode is
enabled.
Whether or not coverage is being collected is stored in the
`BuildConfiguration`. This is handy because it is an easy way to change the test
action and the action graph depending on this bit, but it also means that if
this bit is flipped, all targets need to be re-analyzed (some languages, such as
C++ require different compiler options to emit code that can collect coverage,
which mitigates this issue somewhat, since then a re-analysis is needed anyway).
The coverage support files are depended on through labels in an implicit
dependency so that they can be overridden by the invocation policy, which allows
them to differ between the different versions of Bazel. Ideally, these
differences would be removed, and we standardized on one of them.
We also generate a "coverage report" which merges the coverage collected for
every test in a Bazel invocation. This is handled by
`CoverageReportActionFactory` and is called from `BuildView.createResult()` . It
gets access to the tools it needs by looking at the `:coverage_report_generator`
attribute of the first test that is executed.
## The query engine
Bazel has a
[little language](/query/guide)
used to ask it various things about various graphs. The following query kinds
are provided:
* `bazel query` is used to investigate the target graph
* `bazel cquery` is used to investigate the configured target graph
* `bazel aquery` is used to investigate the action graph
Each of these is implemented by subclassing `AbstractBlazeQueryEnvironment`.
Additional query functions can be done by subclassing `QueryFunction`
. In order to allow streaming query results, instead of collecting them to some
data structure, a `query2.engine.Callback` is passed to `QueryFunction`, which
calls it for results it wants to return.
The result of a query can be emitted in various ways: labels, labels and rule
classes, XML, protobuf and so on. These are implemented as subclasses of
`OutputFormatter`.
A subtle requirement of some query output formats (proto, definitely) is that
Bazel needs to emit *all* the information that package loading provides so that
one can diff the output and determine whether a particular target has changed.
As a consequence, attribute values need to be serializable, which is why there
are only so few attribute types without any attributes having complex Starlark
values. The usual workaround is to use a label, and attach the complex
information to the rule with that label. It's not a very satisfying workaround
and it would be very nice to lift this requirement.
## The module system
Bazel can be extended by adding modules to it. Each module must subclass
`BlazeModule` (the name is a relic of the history of Bazel when it used to be
called Blaze) and gets information about various events during the execution of
a command.
They are mostly used to implement various pieces of "non-core" functionality
that only some versions of Bazel (such as the one we use at Google) need:
* Interfaces to remote execution systems
* New commands
The set of extension points `BlazeModule` offers is somewhat haphazard. Don't
use it as an example of good design principles.
## The event bus
The main way BlazeModules communicate with the rest of Bazel is by an event bus
(`EventBus`): a new instance is created for every build, various parts of Bazel
can post events to it and modules can register listeners for the events they are
interested in. For example, the following things are represented as events:
* The list of build targets to be built has been determined
(`TargetParsingCompleteEvent`)
* The top-level configurations have been determined
(`BuildConfigurationEvent`)
* A target was built, successfully or not (`TargetCompleteEvent`)
* A test was run (`TestAttempt`, `TestSummary`)
Some of these events are represented outside of Bazel in the
[Build Event Protocol](/remote/bep)
(they are `BuildEvent`s). This allows not only `BlazeModule`s, but also things
outside the Bazel process to observe the build. They are accessible either as a
file that contains protocol messages or Bazel can connect to a server (called
the Build Event Service) to stream events.
This is implemented in the `build.lib.buildeventservice` and
`build.lib.buildeventstream` Java packages.
## External repositories
Note: The information in this section is out of date, as code in this area has
undergone extensive change in the past couple of years. Please refer to
[external dependencies overview](/external/overview) for more up-to-date
information.
Whereas Bazel was originally designed to be used in a monorepo (a single source
tree containing everything one needs to build), Bazel lives in a world where
this is not necessarily true. "External repositories" are an abstraction used to
bridge these two worlds: they represent code that is necessary for the build but
is not in the main source tree.
### The WORKSPACE file
The set of external repositories is determined by parsing the WORKSPACE file.
For example, a declaration like this:
```
local_repository(name="foo", path="/foo/bar")
```
Results in the repository called `@foo` being available. Where this gets
complicated is that one can define new repository rules in Starlark files, which
can then be used to load new Starlark code, which can be used to define new
repository rules and so on…
To handle this case, the parsing of the WORKSPACE file (in
`WorkspaceFileFunction`) is split up into chunks delineated by `load()`
statements. The chunk index is indicated by `WorkspaceFileKey.getIndex()` and
computing `WorkspaceFileFunction` until index X means evaluating it until the
Xth `load()` statement.
### Fetching repositories
Before the code of the repository is available to Bazel, it needs to be
*fetched*. This results in Bazel creating a directory under
`$OUTPUT_BASE/external/`.
Fetching the repository happens in the following steps:
1. `PackageLookupFunction` realizes that it needs a repository and creates a
`RepositoryName` as a `SkyKey`, which invokes `RepositoryLoaderFunction`
2. `RepositoryLoaderFunction` forwards the request to
`RepositoryDelegatorFunction` for unclear reasons (the code says it's to
avoid re-downloading things in case of Skyframe restarts, but it's not a
very solid reasoning)
3. `RepositoryDelegatorFunction` finds out the repository rule it's asked to
fetch by iterating over the chunks of the WORKSPACE file until the requested
repository is found
4. The appropriate `RepositoryFunction` is found that implements the repository
fetching; it's either the Starlark implementation of the repository or a
hard-coded map for repositories that are implemented in Java.
There are various layers of caching since fetching a repository can be very
expensive:
1. There is a cache for downloaded files that is keyed by their checksum
(`RepositoryCache`). This requires the checksum to be available in the
WORKSPACE file, but that's good for hermeticity anyway. This is shared by
every Bazel server instance on the same workstation, regardless of which
workspace or output base they are running in.
2. A "marker file" is written for each repository under `$OUTPUT_BASE/external`
that contains a checksum of the rule that was used to fetch it. If the Bazel
server restarts but the checksum does not change, it's not re-fetched. This
is implemented in `RepositoryDelegatorFunction.DigestWriter` .
3. The `--distdir` command line option designates another cache that is used to
look up artifacts to be downloaded. This is useful in enterprise settings
where Bazel should not fetch random things from the Internet. This is
implemented by `DownloadManager` .
Once a repository is downloaded, the artifacts in it are treated as source
artifacts. This poses a problem because Bazel usually checks for up-to-dateness
of source artifacts by calling stat() on them, and these artifacts are also
invalidated when the definition of the repository they are in changes. Thus,
`FileStateValue`s for an artifact in an external repository need to depend on
their external repository. This is handled by `ExternalFilesHelper`.
### Repository mappings
It can happen that multiple repositories want to depend on the same repository,
but in different versions (this is an instance of the "diamond dependency
problem"). For example, if two binaries in separate repositories in the build
want to depend on Guava, they will presumably both refer to Guava with labels
starting `@guava//` and expect that to mean different versions of it.
Therefore, Bazel allows one to re-map external repository labels so that the
string `@guava//` can refer to one Guava repository (such as `@guava1//`) in the
repository of one binary and another Guava repository (such as `@guava2//`) in the
repository of the other.
Alternatively, this can also be used to **join** diamonds. If a repository
depends on `@guava1//`, and another depends on `@guava2//`, repository mapping
allows one to re-map both repositories to use a canonical `@guava//` repository.
The mapping is specified in the WORKSPACE file as the `repo_mapping` attribute
of individual repository definitions. It then appears in Skyframe as a member of
`WorkspaceFileValue`, where it is plumbed to:
* `Package.Builder.repositoryMapping` which is used to transform label-valued
attributes of rules in the package by
`RuleClass.populateRuleAttributeValues()`
* `Package.repositoryMapping` which is used in the analysis phase (for
resolving things like `$(location)` which are not parsed in the loading
phase)
* `BzlLoadFunction` for resolving labels in load() statements
## JNI bits
The server of Bazel is *mostly* written in Java. The exception is the parts that
Java cannot do by itself or couldn't do by itself when we implemented it. This
is mostly limited to interaction with the file system, process control and
various other low-level things.
The C++ code lives under src/main/native and the Java classes with native
methods are:
* `NativePosixFiles` and `NativePosixFileSystem`
* `ProcessUtils`
* `WindowsFileOperations` and `WindowsFileProcesses`
* `com.google.devtools.build.lib.platform`
## Console output
Emitting console output seems like a simple thing, but the confluence of running
multiple processes (sometimes remotely), fine-grained caching, the desire to
have a nice and colorful terminal output and having a long-running server makes
it non-trivial.
Right after the RPC call comes in from the client, two `RpcOutputStream`
instances are created (for stdout and stderr) that forward the data printed into
them to the client. These are then wrapped in an `OutErr` (an (stdout, stderr)
pair). Anything that needs to be printed on the console goes through these
streams. Then these streams are handed over to
`BlazeCommandDispatcher.execExclusively()`.
Output is by default printed with ANSI escape sequences. When these are not
desired (`--color=no`), they are stripped by an `AnsiStrippingOutputStream`. In
addition, `System.out` and `System.err` are redirected to these output streams.
This is so that debugging information can be printed using
`System.err.println()` and still end up in the terminal output of the client
(which is different from that of the server). Care is taken that if a process
produces binary output (such as `bazel query --output=proto`), no munging of stdout
takes place.
Short messages (errors, warnings and the like) are expressed through the
`EventHandler` interface. Notably, these are different from what one posts to
the `EventBus` (this is confusing). Each `Event` has an `EventKind` (error,
warning, info, and a few others) and they may have a `Location` (the place in
the source code that caused the event to happen).
Some `EventHandler` implementations store the events they received. This is used
to replay information to the UI caused by various kinds of cached processing,
for example, the warnings emitted by a cached configured target.
Some `EventHandler`s also allow posting events that eventually find their way to
the event bus (regular `Event`s do *not* appear there). These are
implementations of `ExtendedEventHandler` and their main use is to replay cached
`EventBus` events. These `EventBus` events all implement `Postable`, but not
everything that is posted to `EventBus` necessarily implements this interface;
only those that are cached by an `ExtendedEventHandler` (it would be nice and
most of the things do; it's not enforced, though)
Terminal output is *mostly* emitted through `UiEventHandler`, which is
responsible for all the fancy output formatting and progress reporting Bazel
does. It has two inputs:
* The event bus
* The event stream piped into it through Reporter
The only direct connection the command execution machinery (for example the rest of
Bazel) has to the RPC stream to the client is through `Reporter.getOutErr()`,
which allows direct access to these streams. It's only used when a command needs
to dump large amounts of possible binary data (such as `bazel query`).
## Profiling Bazel
Bazel is fast. Bazel is also slow, because builds tend to grow until just the
edge of what's bearable. For this reason, Bazel includes a profiler which can be
used to profile builds and Bazel itself. It's implemented in a class that's
aptly named `Profiler`. It's turned on by default, although it records only
abridged data so that its overhead is tolerable; the command line
`--record_full_profiler_data` makes it record everything it can.
It emits a profile in the Chrome profiler format; it's best viewed in Chrome.
Its data model is that of task stacks: one can start tasks and end tasks and
they are supposed to be neatly nested within each other. Each Java thread gets
its own task stack. **TODO:** How does this work with actions and
continuation-passing style?
The profiler is started and stopped in `BlazeRuntime.initProfiler()` and
`BlazeRuntime.afterCommand()` respectively and attempts to be live for as long
as possible so that we can profile everything. To add something to the profile,
call `Profiler.instance().profile()`. It returns a `Closeable`, whose closure
represents the end of the task. It's best used with try-with-resources
statements.
We also do rudimentary memory profiling in `MemoryProfiler`. It's also always on
and it mostly records maximum heap sizes and GC behavior.
## Testing Bazel
Bazel has two main kinds of tests: ones that observe Bazel as a "black box" and
ones that only run the analysis phase. We call the former "integration tests"
and the latter "unit tests", although they are more like integration tests that
are, well, less integrated. We also have some actual unit tests, where they are
necessary.
Of integration tests, we have two kinds:
1. Ones implemented using a very elaborate bash test framework under
`src/test/shell`
2. Ones implemented in Java. These are implemented as subclasses of
`BuildIntegrationTestCase`
`BuildIntegrationTestCase` is the preferred integration testing framework as it
is well-equipped for most testing scenarios. As it is a Java framework, it
provides debuggability and seamless integration with many common development
tools. There are many examples of `BuildIntegrationTestCase` classes in the
Bazel repository.
Analysis tests are implemented as subclasses of `BuildViewTestCase`. There is a
scratch file system you can use to write `BUILD` files, then various helper
methods can request configured targets, change the configuration and assert
various things about the result of the analysis.
# Design Documents
Source: https://bazel.build/contribute/design-documents
If you're planning to add, change, or remove a user-facing feature, or make a
*significant architectural change* to Bazel, you **must** write a design
document and have it reviewed before you can submit the change.
Here are some examples of significant changes:
* Addition or deletion of native build rules
* Breaking-changes to native rules
* Changes to a native build rule semantics that affect the behavior of more
than a single rule
* Changes to Bazel's rule definition API
* Changes to the APIs that Bazel uses to connect to other systems
* Changes to the Starlark language, semantics, or APIs
* Changes that could have a pervasive effect on Bazel performance or memory
usage (for better or for worse)
* Changes to widely used internal APIs
* Changes to flags and command-line interface.
## Reasons for design reviews
When you write a design document, you can coordinate with other Bazel developers
and seek guidance from Bazel's core team. For example, when a proposal adds,
removes, or modifies any function or object available in BUILD, MODULE.bazel, or
bzl files, add the [Starlark team](/contribute/maintainers-guide) as reviewers.
Design documents are reviewed before submission because:
* Bazel is a very complex system; seemingly innocuous local changes can have
significant global consequences.
* The team gets many feature requests from users; such requests need to be
evaluated not only for technical feasibility but importance with regards to
other feature requests.
* Bazel features are frequently implemented by people outside the core team;
such contributors have widely varying levels of Bazel expertise.
* The Bazel team itself has varying levels of expertise; no single team member
has a complete understanding of every corner of Bazel.
* Changes to Bazel must account for backward compatibility and avoid breaking
changes.
Bazel's design review policy helps to maximize the likelihood that:
* all feature requests get a baseline level of scrutiny.
* the right people will weigh in on designs before we've invested in an
implementation that may not work.
To help you get started, take a look at the design documents in the
[Bazel Proposals Repository](https://github.com/bazelbuild/proposals).
Designs are works in progress, so implementation details can change over time
and with feedback. The published design documents capture the initial design,
and *not* the ongoing changes as designs are implemented. Always go to the
documentation for descriptions of current Bazel functionality.
## Contributor Workflow
As a contributor, you can write a design document, send pull requests and
request reviewers for your proposal.
### Write the design document
All design documents must have a header that includes:
* author
* date of last major change
* list of reviewers, including one (and only one)
[lead reviewer](#lead-reviewer)
* current status (*draft*, *in review*, *approved*, *rejected*,
*being implemented*, *implemented*)
* link to discussion thread (*to be added after the announcement*)
The document can be written either [as a world-readable Google Doc](#gdocs)
or [using Markdown](#markdown). Read below about for a
[Markdown / Google Docs comparison](#markdown-versus-gdocs).
Proposals that have a user-visible impact must have a section documenting the
impact on backward compatibility (and a rollout plan if needed).
### Create a Pull Request
Share your design doc by creating a pull request (PR) to add the document to
[the design index](https://github.com/bazelbuild/proposals). Add
your markdown file or a document link to your PR.
When possible, [choose a lead reviewer](#lead-reviewer).
and cc other reviewers. If you don't choose a lead reviewer, a Bazel
maintainer will assign one to your PR.
After you create your PR, reviewers can make preliminary comments during the
code review. For example, the lead reviewer can suggest extra reviewers, or
point out missing information. The lead reviewer approves the PR when they
believe the review process can start. This doesn't mean the proposal is perfect
or will be approved; it means that the proposal contains enough information to
start the discussion.
### Announce the new proposal
Send an announcement to
[bazel-dev](https://groups.google.com/forum/#!forum/bazel-dev) when
the PR is submitted.
You may copy other groups (for example,
[bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss),
to get feedback from Bazel end-users).
### Iterate with reviewers
Anyone interested can comment on your proposal. Try to answer questions,
clarify the proposal, and address concerns.
Discussion should happen on the announcement thread. If the proposal is in a
Google Doc, comments may be used instead (Note that anonymous comments are
allowed).
### Update the status
Create a new PR to update the status of the proposal, when iteration is
complete. Send the PR to the same lead reviewer and cc the other reviewers.
To officially accept the proposal, the lead reviewer approves the PR after
ensuring that the other reviewers agree with the decision.
There must be at least 1 week between the first announcement and the approval of
a proposal. This ensures that users had enough time to read the document and
share their concerns.
Implementation can begin before the proposal is accepted, for example as a
proof-of-concept or an experimentation. However, you cannot submit the change
before the review is complete.
### Choosing a lead reviewer
A lead reviewer should be a domain expert who is:
* Knowledgeable of the relevant subsystems
* Objective and capable of providing constructive feedback
* Available for the entire review period to lead the process
Consider checking the contacts for various [team labels](/contribute/maintainers-guide#team-labels).
## Markdown vs Google Docs
Decide what works best for you, since both are accepted.
Benefits of using Google Docs:
* Effective for brainstorming, since it is easy to get started with.
* Collaborative editing.
* Quick iteration.
* Easy way to suggest edits.
Benefits of using Markdown files:
* Clean URLs for linking.
* Explicit record of revisions.
* No forgetting to set up access rights before publicizing a link.
* Easily searchable with search engines.
* Future-proof: Plain text is not at the mercy of any specific tool
and doesn't require an Internet connection.
* It is possible to update them even if the author is not around anymore.
* They can be processed automatically (update/detect dead links, fetch
list of authors, etc.).
You can choose to first iterate on a Google Doc, and then convert it to
Markdown for posterity.
### Using Google Docs
For consistency, use the [Bazel design doc template](https://docs.google.com/document/d/1cE5zrjrR40RXNg64XtRFewSv6FrLV6slGkkqxBumS1w/template/preview).
It includes the necessary header and creates visual
consistency with other Bazel related documents.
To make your document readable to the world, click on
**Share** > **Advanced** > **Change…**, and
choose "On - Anyone with the link". If you allow comments on the document,
anyone can comment anonymously, even without a Google account.
### Using Markdown
Documents are stored on GitHub and use the
[GitHub flavor of Markdown](https://guides.github.com/features/mastering-markdown/)
([Specification](https://github.github.com/gfm/)).
Create a PR to update an existing document. Significant changes should be
reviewed by the document reviewers. Trivial changes (such as typos, formatting)
can be approved by anyone.
## Reviewer workflow
A reviewer comments, reviews and approves design documents.
### General reviewer responsibilities
You're responsible for reviewing design documents, asking for additional
information if needed, and approving a design that passes the review process.
#### When you receive a new proposal
1. Take a quick look at the document.
2. Comment if critical information is missing, or if the design doesn't fit
with the goals of the project.
3. Suggest additional reviewers.
4. Approve the PR when it is ready for review.
#### During the review process
1. Engage in a dialogue with the design author about issues that are problematic
or require clarification.
2. If appropriate, invite comments from non-reviewers who should be aware of
the design.
3. Decide which comments must be addressed by the author as a prerequisite to
approval.
4. Write "LGTM" (*Looks Good To Me*) in the discussion thread when you are
happy with the current state of the proposal.
Follow this process for all design review requests. Do not approve designs
affecting Bazel if they are not in the
[design index](https://github.com/bazelbuild/proposals).
### Lead reviewer responsibilities
You're responsible for making the go / no-go decision on implementation
of a pending design. If you're not able to do this, you should identify a
suitable delegate (reassign the PR to the delegate), or reassign the bug to a
Bazel manager for further disposition.
#### During the review process
1. Ensure that the comment and design iteration process moves forward
constructively.
2. Prior to approval, ensure that concerns from other reviewers have been
resolved.
#### After approval by all reviewers
1. Make sure there has been at least 1 week since the announcement on the
mailing list.
2. Make sure the PR updates the status.
3. Approve the PR sent by the proposal author.
#### Rejecting designs
1. Make sure the PR author sends a PR; or send them a PR.
2. The PR updates the status of the document.
3. Add a comment to the document explaining why the design can't be approved in
its current state, and outlining next steps, if any (such as "revisit invalid
assumptions and resubmit").
# Contribute to Bazel documentation
Source: https://bazel.build/contribute/docs
Thank you for contributing to Bazel's documentation!
## How docs work
Bazel documentation lives in two repositories:
* [`bazelbuild/bazel`](https://github.com/bazelbuild/bazel) — all doc content in the `docs/` folder. This is where you make changes.
* [`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs) — the hosting and navigation layer (Mintlify config, sidebar, PR previews).
Content changes always go to `bazelbuild/bazel`. Navigation changes go to `bazel-contrib/bazel-docs`.
## Contributing
* **Make a change or add a page** — see [Docs contribution workflow](/contribute/docs-contribution-workflow) for step-by-step instructions, from a quick typo fix to adding a new page.
* **Update the sidebar navigation** — see [Update the docs navigation](/contribute/docs-navigation) for instructions on adding your new page to the left-hand nav in `bazel-contrib/bazel-docs`.
# Docs contribution workflow
Source: https://bazel.build/contribute/docs-contribution-workflow
This page guides you through contributing to the Bazel
documentation, from a one-line typo fix to adding a new page. For style
guidance, see the [Bazel docs style guide](/contribute/docs-style-guide).
## Bazel docs structure
The source of truth for Bazel documentation is `bazelbuild/bazel`, where docs
live alongside the code. `bazel-contrib/bazel-docs` is the hosting and pipeline
layer: it syncs content from `bazelbuild/bazel`, generates PR previews, and
holds Mintlify configuration. **Content changes always go to `bazelbuild/bazel`.**
| Repository | What it contains |
| - | - |
| [`bazelbuild/bazel`](https://github.com/bazelbuild/bazel) | All doc content (`docs/` folder). This is where you make changes. |
| [`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs) | Hosting pipeline. Syncs from `bazelbuild/bazel`, generates PR previews, and deploys to [preview.bazel.build](https://preview.bazel.build). |
Bazel docs use [MDX format](https://mdxjs.com/), Markdown with a YAML
frontmatter block at the top. Every page must start with:
```
---
title: 'Your Page Title'
---
```
## Prerequisites
Before you start, you need:
* A [GitHub account](https://github.com)
* A fork of [`bazelbuild/bazel`](https://github.com/bazelbuild/bazel)
* [Git](https://git-scm.com/)
* The [Mintlify CLI](https://www.mintlify.com/docs/cli/install) for local preview.
## Make a minor change
For small isolated changes, such as a typo, broken link, phrasing tweaks, you can edit directly in the GitHub web UI without
cloning anything.
1. Find the file in
[`bazelbuild/bazel/docs/`](https://github.com/bazelbuild/bazel/tree/master/docs)
on GitHub.
2. To edit the file, click the **pencil icon** in the top-right corner.
3. Make your edit.
4. Click **Commit changes...**, provide a commit message, and click **Propose changes"**.
5. GitHub prompts you to open a pull request. Set the base branch to
**`master`** and click **Create pull request** it.
## Update existing content
Use this workflow for anything larger than a typo, such as rewording a section,
correcting outdated information, or adding a paragraph to an existing page.
### Set up locally
Fork [`bazelbuild/bazel`](https://github.com/bazelbuild/bazel) on GitHub first, then clone the repo and add the upstream remote:
```bash theme={null}
git clone https://github.com/YOUR_USERNAME/bazel.git
cd bazel
git remote add upstream https://github.com/bazelbuild/bazel.git
```
### Make and preview your changes
Check out a new branch off of `master`.
```bash theme={null}
git fetch upstream
git checkout -b my-doc-fix upstream/master
```
Edit the file in `docs/`, for example, `docs/concepts/labels.mdx`.
To preview locally, you need a local copy of `bazel-contrib/bazel-docs`:
```bash theme={null}
# One-time setup
git clone https://github.com/bazel-contrib/bazel-docs.git
cd bazel-docs
```
Copy your changed file(s) into the local `bazel-docs` mirror to preview them:
```bash theme={null}
cp ~/path/to/bazel/docs/concepts/labels.mdx concepts/labels.mdx
# Start the local dev server
mintlify dev
```
Open [http://localhost:3000](http://localhost:3000) to render your changes.
### Commit and open a PR
Add, commit, and push your changes:
```bash theme={null}
git add --all # stage all changes
git commit -m "docs: your commit msg here"
git push origin my-doc-fix # push to GitHub
```
Open a pull request on GitHub from your fork to **`bazelbuild/bazel` master**.
## Add a new section to an existing page
Follow the same workflow as [Update existing content](#updating-content). A few things to keep in mind:
**Add a heading anchor ID.** Every heading should have an explicit `{#id}` so
URLs to that section stay stable even if the heading text changes:
```md theme={null}
## My new section {#my-new-section}
```
**Use sentence case for headings.** Write "Getting started" not
"Getting Started".
**Keep the heading hierarchy consistent.** Pages use H2 (`##`) for top-level
sections and H3 (`###`) for subsections. Don't skip levels.
**Update the page if there's a table of contents or "On this page" intro.**
Some pages have an introductory list of topics. Add your section there too.
## Add a new page
1. Create the MDX file in the appropriate `docs/` subdirectory.
Every file must start with frontmatter:
```
---
title: 'Your Page Title'
---
```
2. Add your page to the sidebar navigation. This requires a separate change
in `bazel-contrib/bazel-docs`. See
[Update the docs navigation](/contribute/docs-navigation) for instructions.
For an initial PR, you can skip this and ask a maintainer to help.
3. Follow the same branch, commit, and PR steps as [Update existing content](#updating-content).
## MDX basics for doc contributors
MDX is mostly standard Markdown with a few differences.
### Self-closing HTML tags
JSX requires void elements to be self-closing. Use `` and
` `, not `` or ` `.
### Links
Use root-relative paths for internal links. Don't include the `.mdx` extension in the links:
```md theme={null}
[labels](/concepts/labels)
[style guide](/contribute/docs-style-guide)
```
### Code blocks
Always specify a language for syntax highlighting:
````md theme={null}
```bash
bazel build //my/example:app
```
````
Common languages used in Bazel docs: `bash`, `python`, `starlark`, `json`,
`posix-terminal`.
### Images
Place images in the `images/` subdirectory alongside your MDX file and
reference them with a root-relative path:
```md theme={null}

```
Use self-closing syntax: Markdown image syntax does not require the trailing `/>`,
but `` tags must self-close when you use them directly:
```md theme={null}
```
### Notes and callouts
Mintlify supports callout components. Use them for important warnings or tips:
```md theme={null}
This is a note.
This is a warning.
```
For a full list of Mintlify formatting components (tabs, accordions, cards,
and more), see the [Mintlify text formatting docs](https://mintlify.com/docs/create/text).
## What to expect after submitting
* The Google CLA bot checks that you've signed the
[Contributor License Agreement](https://cla.developers.google.com/). You
only need to do this once.
* CI runs a docs validation check.
* A maintainer reviews your PR and might request edits. Response times vary.
* Once approved, a maintainer merges your changes to `master`. They appear on
the live site after the next sync.
> [!TIP]
>
> If your new page does not appear in the sidebar of the PR preview, use the
> black file-changes icon in the preview to navigate directly to it. New pages
> do not appear in the sidebar until you update the navigation in
> `bazel-contrib/bazel-docs`.
## Get help
* Join the [Bazel community Slack](https://slack.bazel.build) and ask in the
`#documentation` channel. This is the best place for quick questions about
the docs platform or contribution process.
* File an issue in [`bazelbuild/bazel`](https://github.com/bazelbuild/bazel/issues)
with the label `type: documentation`.
* For questions about the docs platform, open an
issue in [`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs/issues).
# Update the docs navigation
Source: https://bazel.build/contribute/docs-navigation
Add a new page to the Bazel docs sidebar, or
reorganize existing navigation groups. `bazel-contrib/bazel-docs` controls navigation, which is a separate repo from where doc content lives (`bazelbuild/bazel`).
## How navigation works
`docs.json` in [`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs)
defines the Bazel docs sidebar. Mintlify reads this file to build the
left-hand navigation tree.
`docs.json` contains a `navigation` array of groups, each with a list of pages:
```json theme={null}
{
"navigation": [
{
"group": "Contribute",
"pages": [
"contribute/index",
"contribute/docs-contribution-workflow",
"contribute/docs-style-guide"
]
}
]
}
```
Each entry in `pages` is a root-relative path to an `.mdx` file, without the
`.mdx` extension.
## Prerequisites
* A fork of [`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs)
* The [Mintlify CLI](https://www.mintlify.com/docs/cli/install) for local validation
## Add a page to an existing group
1. Clone your fork of `bazel-contrib/bazel-docs` and add the upstream remote:
```bash theme={null}
git clone https://github.com/YOUR_USERNAME/bazel-docs.git
cd bazel-docs
git remote add upstream https://github.com/bazel-contrib/bazel-docs.git
```
2. Check out a new branch:
```bash theme={null}
git fetch upstream
git checkout -b add-my-page-to-nav upstream/main
```
3. Open `docs.json` and find the group where your page belongs. Add the
path to the `pages` array:
```json theme={null}
{
"group": "Contribute",
"pages": [
"contribute/index",
"contribute/docs-contribution-workflow",
"contribute/docs-navigation",
"contribute/docs-style-guide"
]
}
```
4. Validate that `docs.json` is well-formed:
```bash theme={null}
mint validate
```
Run this from the `bazel-docs` root (where `docs.json` lives).
5. Commit and open a PR against `bazel-contrib/bazel-docs` main:
```bash theme={null}
git add docs.json
git commit -m "docs: Add my-page to navigation"
git push origin add-my-page-to-nav
```
Open a pull request targeting **`bazel-contrib/bazel-docs` main**.
## Add a new navigation group
If your new page does not fit into any existing group, add a new group object
to the `navigation` array in `docs.json`:
```json theme={null}
{
"group": "My New Section",
"pages": [
"my-section/index",
"my-section/getting-started"
]
}
```
Position it in the array where you want it to appear in the sidebar.
## Getting help
If you are unsure where a page belongs, ask in the `#documentation` channel on
the [Bazel community Slack](https://slack.bazel.build) or open an issue in
[`bazel-contrib/bazel-docs`](https://github.com/bazel-contrib/bazel-docs/issues).
# Bazel docs style guide
Source: https://bazel.build/contribute/docs-style-guide
Thank you for contributing to Bazel's documentation. This serves as a quick
documentation style guide to get you started. For any style questions not
answered by this guide, follow the
[Google developer documentation style guide](https://developers.google.com/style).
## Defining principles
Bazel docs should uphold these principles:
* **Concise.** Use as few words as possible.
* **Clear.** Use plain language. Write without jargon for a fifth-grade
reading level.
* **Consistent.** Use the same words or phrases for repeated concepts
throughout the docs.
* **Correct.** Write in a way where the content stays correct for as long as
possible by avoiding time-based information and promises for the future.
## Writing
This section contains basic writing tips.
### Headings
* Page-level headings start at H2. (H1 headings are used as page titles.)
* Make headers as short as is sensible. This way, they fit in the TOC
without wrapping.
* Yes: Permissions
* No: A brief note on permissions
* Use sentence case for headings
* Yes: Set up your workspace
* No: Set Up Your Workspace
* Try to make headings task-based or actionable. If headings are conceptual,
it may be based around understanding, but write to what the user does.
* Yes: Preserving graph order
* No: On the preservation of graph order
### Names
* Capitalize proper nouns, such as Bazel and Starlark.
* Yes: At the end of the build, Bazel prints the requested targets.
* No: At the end of the build, bazel prints the requested targets.
* Keep it consistent. Don't introduce new names for existing concepts. Where
applicable, use the term defined in the
[Glossary](/reference/glossary).
* For example, if you're writing about issuing commands on a
terminal, don't use both terminal and command line on the page.
### Page scope
* Each page should have one purpose and that should be defined at the
beginning. This helps readers find what they need quicker.
* Yes: This page covers how to install Bazel on Windows.
* No: (No introductory sentence.)
* At the end of the page, tell the reader what to do next. For pages where
there is no clear action, you can include links to similar concepts,
examples, or other avenues for exploration.
### Subject
In Bazel documentation, the audience should primarily be users—the people using
Bazel to build their software.
* Address your reader as "you". (If for some reason you can't use "you",
use gender-neutral language, such as they.)
* Yes: To build Java code using Bazel,
you must install a JDK.
* **MAYBE:** For users to build Java code with Bazel, they must install a JDK.
* No: For a user to build Java code with
Bazel, he or she must install a JDK.
* If your audience is NOT general Bazel users, define the audience at the
beginning of the page or in the section. Other audiences can include
maintainers, contributors, migrators, or other roles.
* Avoid "we". In user docs, there is no author; just tell people what's
possible.
* Yes: As Bazel evolves, you should update your code base to maintain
compatibility.
* No: Bazel is evolving, and we will make changes to Bazel that at
times will be incompatible and require some changes from Bazel users.
### Temporal
Where possible, avoid terms that orient things in time, such as referencing
specific dates (Q2 2022) or saying "now", "currently", or "soon." These go
stale quickly and could be incorrect if it's a future projection. Instead,
specify a version level instead, such as "Bazel X.x and higher supports
\ or a GitHub issue link.
* Yes: Bazel 0.10.0 or later supports
remote caching.
* No: Bazel will soon support remote
caching, likely in October 2017.
### Tense
* Use present tense. Avoid past or future tense unless absolutely necessary
for clarity.
* Yes: Bazel issues an error when it
finds dependencies that don't conform to this rule.
* No: If Bazel finds a dependency that
does not conform to this rule, Bazel will issue an error.
* Where possible, use active voice (where a subject acts upon an object) not
passive voice (where an object is acted upon by a subject). Generally,
active voice makes sentences clearer because it shows who is responsible. If
using active voice detracts from clarity, use passive voice.
* Yes: Bazel initiates X and uses the
output to build Y.
* No: X is initiated by Bazel and then
afterward Y will be built with the output.
### Tone
Write with a business friendly tone.
* Avoid colloquial language. It's harder to translate phrases that are
specific to English.
* Yes: Good rulesets
* No: So what is a good ruleset?
* Avoid overly formal language. Write as though you're explaining the
concept to someone who is curious about tech, but doesn't know the details.
## Formatting
### File type
For readability, wrap lines at 80 characters. Long links or code snippets
may be longer, but should start on a new line. For example:
Note: Where possible, use Markdown instead of HTML in your files. Follow the
[GitHub Markdown Syntax Guide](https://guides.github.com/features/mastering-markdown/#syntax)
for recommended Markdown style.
### Links
* Use descriptive link text instead of "here" or "below". This practice
makes it easier to scan a doc and is better for screen readers.
* Yes: For more details, see \[Installing Bazel].
* No: For more details, see \[here].
* End the sentence with the link, if possible.
* Yes: For more details, see \[link].
* No: See \[link] for more information.
### Lists
* Use an ordered list to describe how to accomplish a task with steps
* Use an unordered list to list things that aren't task based. (There should
still be an order of sorts, such as alphabetical, importance, etc.)
* Write with parallel structure. For example:
1. Make all the list items sentences.
2. Start with verbs that are the same tense.
3. Use an ordered list if there are steps to follow.
### Placeholders
* Use angle brackets to denote a variable that users should change.
In Markdown, escape the angle brackets with a back slash: `\`.
* Yes: `bazel help `: Prints
help and options for ``
* No: bazel help *command*: Prints help
and options for "command"
* Especially for complicated code samples, use placeholders that make sense
in context.
### Table of contents
Use the auto-generated TOC supported by the site. Don't add a manual TOC.
## Code
Code samples are developers' best friends. You probably know how to write these
already, but here are a few tips.
If you're referencing a small snippet of code, you can embed it in a sentence.
If you want the reader to use the code, such as copying a command, use a code
block.
### Code blocks
* Keep it short. Eliminate all redundant or unnecessary text from a code
sample.
* In Markdown, specify the type of code block by adding the sample's language.
````
```shell
...
````
* Separate commands and output into different code blocks.
### Inline code formatting
* Use code style for filenames, directories, paths, and small bits of code.
* Use inline code styling instead of *italics*, "quotes," or **bolding**.
* Yes: `bazel help `: Prints
help and options for ``
* No: bazel help *command*: Prints help
and options for "command"
# Guide for Bazel Maintainers
Source: https://bazel.build/contribute/maintainers-guide
This is a guide for the maintainers of the Bazel open source project.
If you are looking to contribute to Bazel, read [Contributing to Bazel](/contribute) instead.
The objectives of this page are to:
1. Serve as the maintainers' source of truth for the project's contribution
process.
2. Set expectations between the community contributors and the project
maintainers.
Bazel's [core group of contributors](/contribute/policy) has dedicated
subteams to manage aspects of the open source project. These are:
* **Release Process**: Manage Bazel's release process.
* **Green Team**: Monitor Bazel CI health and report breakages.
* **Developer Experience Gardeners**: Encourage external contributions, review
issues and pull requests, and make our development workflow more open.
## Releases
* [Release Playbook](https://github.com/bazelbuild/continuous-integration/blob/master/docs/release-playbook.md)
* [Testing local changes with downstream projects](https://github.com/bazelbuild/continuous-integration/blob/master/docs/downstream-testing.md)
## Continuous Integration
Read the Green team's guide to Bazel's CI infrastructure on the
[bazelbuild/continuous-integration](https://github.com/bazelbuild/continuous-integration/blob/master/buildkite/README.md)
repository.
## Lifecycle of an Issue
1. A user creates an issue by choosing one of the
[issue templates](https://github.com/bazelbuild/bazel/issues/new/choose)
and it enters the pool of [unreviewed open issues](https://github.com/bazelbuild/bazel/issues?utf8=%E2%9C%93\&q=is%3Aissue+is%3Aopen+-label%3Auntriaged+-label%3Ap2+-label%3Ap1+-label%3Ap3+-label%3Ap4+-label%3Ateam-Starlark+-label%3Ateam-Rules-CPP+-label%3Ateam-Rules-Java+-label%3Ateam-XProduct+-label%3Ateam-Android+-label%3Ateam-Apple+-label%3Ateam-Configurability++-label%3Ateam-Performance+-label%3Ateam-Rules-Server+-label%3Ateam-Core+-label%3Ateam-Rules-Python+-label%3Ateam-Remote-Exec+-label%3Ateam-Local-Exec+-label%3Ateam-Bazel).
2. A member on the Developer Experience (DevEx) subteam rotation reviews the
issue.
1. If the issue is **not a bug** or a **feature request**, the DevEx member
will usually close the issue and redirect the user to
[StackOverflow](https://stackoverflow.com/questions/tagged/bazel) and
[bazel-discuss](https://groups.google.com/forum/#!forum/bazel-discuss) for
higher visibility on the question.
2. If the issue belongs in one of the rules repositories owned by the
community, like [rules\_apple](https://github.com/bazelbuild/rules_apple),
the DevEx member will [transfer this issue](https://docs.github.com/en/free-pro-team@latest/github/managing-your-work-on-github/transferring-an-issue-to-another-repository)
to the correct repository.
3. If the issue is vague or has missing information, the DevEx member will
assign the issue back to the user to request for more information before
continuing. This usually occurs when the user does not choose the right
[issue template](https://github.com/bazelbuild/bazel/issues/new/choose)
or provides incomplete information.
3. After reviewing the issue, the DevEx member decides if the issue requires
immediate attention. If it does, they will assign the **P0**
[priority](#priority) label and an owner from the list of team leads.
4. The DevEx member assigns the `untriaged` label and exactly one [team label](#team-labels) for routing.
5. The DevEx member also assigns exactly one `type:` label, such as `type: bug`
or `type: feature request`, according to the type of the issue.
6. For platform-specific issues, the DevEx member assigns one `platform:` label,
such as `platform:apple` for Mac-specific issues.
7. If the issue is low priority and can be worked on by a new community
contributor, the DevEx member assigns the `good first issue` label.
At this stage, the issue enters the pool of [untriaged open issues](https://github.com/bazelbuild/bazel/issues?q=is%3Aissue+is%3Aopen+label%3Auntriaged).
Each Bazel subteam will triage all issues under labels they own, preferably on a
weekly basis. The subteam will review and evaluate the issue and provide a
resolution, if possible. If you are an owner of a team label, see [this section](#label-own) for more information.
When an issue is resolved, it can be closed.
## Lifecycle of a Pull Request
1. A user creates a pull request.
2. If you a member of a Bazel team and sending a PR against your own area,
you are responsible for assigning your team label and finding the best
reviewer.
3. Otherwise, during daily triage, a DevEx member assigns one
[team label](#team-labels) and the team's technical lead (TL) for routing.
1. The TL may optionally assign someone else to review the PR.
4. The assigned reviewer reviews the PR and works with the author until it is
approved or dropped.
5. If approved, the reviewer **imports** the PR's commit(s) into Google's
internal version control system for further tests. As Bazel is the same build
system used internally at Google, we need to test all PR commits against the
internal test suite. This is the reason why we do not merge PRs directly.
6. If the imported commit passes all internal tests, the commit will be squashed
and exported back out to GitHub.
7. When the commit merges into master, GitHub automatically closes the PR.
## My team owns a label. What should I do?
Subteams need to triage all issues in the [labels they own](#team-labels),
preferably on a weekly basis.
### Issues
1. Filter the list of issues by your team label **and** the `untriaged` label.
2. Review the issue.
3. Identify a [priority level](#priority) and assign the label.
4. The issue may have already been prioritized by the DevEx subteam if it's a
P0. Re-prioritize if needed.
5. Each issue needs to have exactly one [priority label](#priority). If an
issue is either P0 or P1 we assume that is actively worked on.
6. Remove the `untriaged` label.
Note that you need to be in the [bazelbuild organization](https://github.com/bazelbuild) to be able to add or remove labels.
### Pull Requests
Pull requests (PRs) are a primary way that external contributors add value to
Bazel. As an open source project, it is important to ensure that PRs are
reviewed and handled in a timely and efficient manner.
* **Triage**
Regularly review incoming PRs with the `awaiting-review` label and your team
label. This can be done either with a rotation or a regular triage meeting.
We expect each PR receives an initial response within 7 business days.
* **Response**
* If the PR looks good, approve it and apply the `awaiting-PR-merge`
label. The gTech team will import the PR as a CL.
* Otherwise, leave your feedback and replace the `awaiting-review` label
with the `awaiting-user-response` label. The DevEx subteam will
regularly update the label if the PR author responds.
* For PRs with major changes, consider asking for a design doc or a
prior discussion in an issue.
* **Closure**
Due to limited resources, it's important to close PRs that don't meet
Bazel's standards or that we don't have the capacity to review or maintain.
* If the PR is not aligned with Bazel's goals, close it with an
explanation.
* If the PR is too large and complex, close it with a request to break it
down into smaller pieces.
* If the PR code quality doesn't meet our standards, close it with an
explanation.
* If the future maintenance cost of the code is too high, close it with an
explanation.
* If the PR has been awaiting user response for a long time and the
contributor hasn't responded, the PR will be automatically marked as
stale after 30 days and closed after another 30 days.
When closing a PR, be polite and explain the reason for closure.
## Priority
The following definitions for priority will be used by the maintainers to triage
issues.
* [**P0**](https://github.com/bazelbuild/bazel/labels/P0) - Major broken
functionality that causes a Bazel release (minus release candidates) to be
unusable, or a downed service that severely impacts development of the Bazel
project. This includes regressions introduced in a new release that blocks a
significant number of users, or an incompatible breaking change that was not
compliant to the [Breaking Change](https://docs.google.com/document/d/1q5GGRxKrF_mnwtaPKI487P8OdDRh2nN7jX6U-FXnHL0/edit?pli=1#heading=h.ceof6vpkb3ik)
policy. No practical workaround exists.
* [**P1**](https://github.com/bazelbuild/bazel/labels/P1) - Critical defect or
feature which should be addressed in the next release, or a serious issue that
impacts many users (including the development of the Bazel project), but a
practical workaround exists. Typically does not require immediate action. In
high demand and planned in the current quarter's roadmap.
* [**P2**](https://github.com/bazelbuild/bazel/labels/P2) - Defect or feature
that should be addressed but we don't currently work on. Moderate live issue
in a released Bazel version that is inconvenient for a user that needs to be
addressed in an future release and/or an easy workaround exists.
* [**P3**](https://github.com/bazelbuild/bazel/labels/P3) - Desirable minor bug
fix or enhancement with small impact. Not prioritized into Bazel roadmaps or
any imminent release, however community contributions are encouraged.
* [**P4**](https://github.com/bazelbuild/bazel/labels/P4) - Low priority defect
or feature request that is unlikely to get closed. Can also be kept open for a
potential re-prioritization if more users are impacted.
## Team labels
* [`team-Android`](https://github.com/bazelbuild/bazel/labels/team-Android): Issues for Android team
* Contact: [ahumesky](https://github.com/ahumesky)
* [`team-Bazel`](https://github.com/bazelbuild/bazel/labels/team-Bazel): General Bazel product/strategy issues
* Contact: [meisterT](https://github.com/meisterT)
* [`team-CLI`](https://github.com/bazelbuild/bazel/labels/team-CLI): Console UI
* Contact: [meisterT](https://github.com/meisterT)
* [`team-Configurability`](https://github.com/bazelbuild/bazel/labels/team-Configurability): Issues for Configurability team. Includes: Core build configuration and transition system. Does *not* include: Changes to new or existing flags
* Contact: [gregestren](https://github.com/gregestren)
* [`team-Core`](https://github.com/bazelbuild/bazel/labels/team-Core): Skyframe, bazel query, BEP, options parsing, bazelrc
* Contact: [haxorz](https://github.com/haxorz)
* [`team-Documentation`](https://github.com/bazelbuild/bazel/labels/team-Documentation): Issues for Documentation team
* [`team-ExternalDeps`](https://github.com/bazelbuild/bazel/labels/team-ExternalDeps): External dependency handling, Bzlmod, remote repositories, WORKSPACE file
* Contact: [meteorcloudy](https://github.com/meteorcloudy)
* [`team-Loading-API`](https://github.com/bazelbuild/bazel/labels/team-Loading-API): BUILD file and macro processing: labels, package(), visibility, glob
* Contact: [brandjon](https://github.com/brandjon)
* [`team-Local-Exec`](https://github.com/bazelbuild/bazel/labels/team-Local-Exec): Issues for Execution (Local) team
* Contact: [meisterT](https://github.com/meisterT)
* [`team-OSS`](https://github.com/bazelbuild/bazel/labels/team-OSS): Issues for Bazel OSS team: installation, release process, Bazel packaging, website, docs infrastructure
* Contact: [meteorcloudy](https://github.com/meteorcloudy)
* [`team-Performance`](https://github.com/bazelbuild/bazel/labels/team-Performance): Issues for Bazel Performance team
* Contact: [meisterT](https://github.com/meisterT)
* [`team-Remote-Exec`](https://github.com/bazelbuild/bazel/labels/team-Remote-Exec): Issues for Execution (Remote) team
* Contact: [coeuvre](https://github.com/coeuvre)
* [`team-Rules-API`](https://github.com/bazelbuild/bazel/labels/team-Rules-API): API for writing rules/aspects: providers, runfiles, actions, artifacts
* Contact: [pzembrod](https://github.com/pzembrod)
* [`team-Rules-CPP`](https://github.com/bazelbuild/bazel/labels/team-Rules-CPP) / [`team-Rules-ObjC`](https://github.com/bazelbuild/bazel/labels/team-Rules-ObjC): Issues for C++/Objective-C rules, including native Apple rule logic
* Contact: [pzembrod](https://github.com/pzembrod)
* [`team-Rules-Java`](https://github.com/bazelbuild/bazel/labels/team-Rules-Java): Issues for Java rules
* Contact: [hvadehra](https://github.com/hvadehra)
* [`team-Rules-Python`](https://github.com/bazelbuild/bazel/labels/team-Rules-Python): Issues for the native Python rules
* Contact: [rickeylev](https://github.com/rickeylev)
* [`team-Rules-Server`](https://github.com/bazelbuild/bazel/labels/team-Rules-Server): Issues for server-side rules included with Bazel
* Contact: [pzembrod](https://github.com/pzembrod)
* [`team-Starlark-Integration`](https://github.com/bazelbuild/bazel/labels/team-Starlark-Integration): Non-API Bazel + Starlark integration. Includes: how Bazel triggers the Starlark interpreter, Stardoc, builtins injection, character encoding. Does *not* include: BUILD or .bzl language issues.
* Contact: [brandjon](https://github.com/brandjon)
* [`team-Starlark-Interpreter`](https://github.com/bazelbuild/bazel/labels/team-Starlark-Interpreter): Issues for the Starlark interpreter (anything in [java.net.starlark](https://github.com/bazelbuild/bazel/tree/master/src/main/java/net/starlark/java)). BUILD and .bzl API issues (which represent Bazel's *integration* with Starlark) go in `team-Build-Language`.
* Contact: [brandjon](https://github.com/brandjon)
For new issues, we deprecated the `category: *` labels in favor of the team
labels.
See the full list of labels [here](https://github.com/bazelbuild/bazel/labels).
# Naming a Bazel related project
Source: https://bazel.build/contribute/naming
First, thank you for contributing to the Bazel ecosystem! Please reach out to
the Bazel community on the
[bazel-discuss mailing list](https://groups.google.com/forum/#!forum/bazel-discuss) to share your project and its suggested name.
If you are building a Bazel related tool or sharing your Skylark rules,
we recommend following these guidelines for the name of your project:
## Naming Starlark rules
See [Deploying new Starlark rules](/rules/deploying)
in the docs.
## Naming other Bazel related tools
This section applies if you are building a tool to enrich the Bazel ecosystem.
For example, a new IDE plugin or a new build system migrator.
Picking a good name for your tool can be hard. If we’re not careful and use too
many codenames, the Bazel ecosystem could become very difficult to understand
for newcomers.
Follow these guidelines for naming Bazel tools:
1. Prefer **not introducing a new brand name**: "*Bazel*" is already a new brand
for our users, we should avoid confusing them with too many new names.
2. Prefer **using a name that includes "Bazel"**: This helps to express that it
is a Bazel related tool, it also helps people find it with a search engine.
3. Prefer **using names that are descriptive about what the tool is doing**:
Ideally, the name should not need a subtitle for users to have a first good
guess at what the tool does. Using english words separated by spaces is a good
way to achieve this.
4. **It is not a requirement to use a floral or food theme**: Bazel evokes
[basil](https://en.wikipedia.org/wiki/Basil), the plant. You do not need to
look for a name that is a plant, food or that relates to "basil."
5. **If your tool relates to another third party brand, use it only as a
descriptor**: For example, use "Bazel migrator for Cmake" instead of
"Cmake Bazel migrator".
These guidelines also apply to the GitHub repository URL. Reading the repository
URL should help people understand what the tool does. Of course, the repository
name can be shorter and must use dashes instead of spaces and lower case letters.
Examples of good names:
* *Bazel for Eclipse*: Users will understand that if they want to use Bazel
with Eclipse, this is where they should be looking. It uses a third party brand
as a descriptor.
* *Bazel buildfarm*: A "buildfarm" is a
[compile farm](https://en.wikipedia.org/wiki/Compile_farm). Users
will understand that this project relates to building on servers.
Examples of names to avoid:
* *Ocimum*: The [scientific name of basil](https://en.wikipedia.org/wiki/Ocimum)
does not relate enough to the Bazel project.
* *Bazelizer*: The tool behind this name could do a lot of things, this name is
not descriptive enough.
Note that these recommendations are aligned with the
[guidelines](https://opensource.google.com/docs/releasing/preparing/#name)
Google uses when open sourcing a project.
# Patch Acceptance Process
Source: https://bazel.build/contribute/patch-acceptance
This page outlines how contributors can propose and make changes to the Bazel
code base.
1. Read the [Bazel Contribution policy](/contribute/policy).
2. Create a [GitHub issue](https://github.com/bazelbuild/bazel/) to
discuss your plan and design. Pull requests that change or add behavior
need a corresponding issue for tracking.
3. If you're proposing significant changes, write a
[design document](/contribute/design-documents).
4. Ensure you've signed a [Contributor License Agreement](https://cla.developers.google.com).
5. Prepare a git commit that implements the feature. Don't forget to add tests
and update the documentation. If your change has user-visible effects, please
[add release notes](/contribute/release-notes). If it is an incompatible change,
read the [guide for rolling out breaking changes](/contribute/breaking-changes).
If you use AI assistance, review the
[AI-assisted contributions guidelines](/contribute/ai-assisted-contributions).
6. Create a pull request on
[GitHub](https://github.com/bazelbuild/bazel/pulls). If you're new to GitHub,
read [about pull requests](https://help.github.com/articles/about-pull-requests/). Note that
we restrict permissions to create branches on the main Bazel repository, so
you will need to push your commit to [your own fork of the repository](https://help.github.com/articles/working-with-forks/).
7. A Bazel maintainer should assign you a reviewer within 7 business days
(excluding holidays in the USA and Germany). If you aren't assigned a
reviewer in that time, you can ping `@bazelbuild/triage` on the PR.
8. Work with the reviewer to complete a code review. For each change, create a
new commit and push it to make changes to your pull request. If the review
takes too long (for instance, if the reviewer is unresponsive), you can ping
`@bazelbuild/triage` on the PR.
9. After your review is complete, a Bazel maintainer applies your patch to
Google's internal version control system.
This triggers internal presubmit checks
that may suggest more changes. If you haven't expressed a preference, the
maintainer submitting your change may add "trivial" changes (such as
[linting](https://en.wikipedia.org/wiki/Lint_\(software\))) that don't affect
design. If deeper changes are required or you'd prefer to apply
changes directly, you and the reviewer should communicate preferences
clearly in review comments.
After internal submission, the patch is exported as a Git commit,
at which point the GitHub pull request is closed. All final changes
are attributed to you.
# Policy
Source: https://bazel.build/contribute/policy
translation: human
page\_type: lcat
----------------
## title: 'Contribution policy'
This page covers Bazel's governance model and contribution policy.
## Governance model
The [Bazel project](https://github.com/bazelbuild) is led and managed by Google
and has a large community of contributors outside of Google. Some Bazel
components (such as specific rules repositories under the
[bazelbuild](https://github.com/bazelbuild) organization) are led,
maintained, and managed by members of the community. The Google Bazel team
reviews suggestions to add community-owned repositories (such as rules) to the
[bazelbuild](https://github.com/bazelbuild) GitHub organization.
### Contributor roles
Here are outlines of the roles in the Bazel project, including their
responsibilities:
* **Owners**: The Google Bazel team. Owners are responsible for:
* Strategy, maintenance, and leadership of the Bazel project.
* Building and maintaining Bazel's core functionality.
* Appointing Maintainers and approving new repositories.
* **Maintainers**: The Google Bazel team and designated GitHub users.
Maintainers are responsible for:
* Building and maintaining the primary functionality of their repository.
* Reviewing and approving contributions to areas of the Bazel code base.
* Supporting users and contributors with timely and transparent issue
management, PR review, and documentation.
* Releasing, testing and collaborating with Bazel Owners.
* **Contributors**: All users who contribute code or documentation to the
Bazel project.
* Creating well-written PRs to contribute to Bazel's codebase and
documentation.
* Using standard channels, such as GitHub Issues, to propose changes and
report issues.
### Becoming a Maintainer
Bazel Owners may appoint Maintainers to lead well-defined areas of code, such as
rule sets. Contributors with a record of consistent, responsible past
contributions who are planning major contributions in the future could be
considered to become qualified Maintainers.
## Contribution policy
The Bazel project accepts contributions from external contributors. Here are the
contribution policies for Google-managed and Community-managed areas of code.
* **Licensing**. All Maintainers and Contributors must sign the
[Google’s Contributor License Agreement](https://cla.developers.google.com/clas).
* **Contributions**. Owners and Maintainers should make every effort to accept
worthwhile contributions. All contributions must be:
* Well written and well tested
* Discussed and approved by the Maintainers of the relevant area of code.
Discussions and approvals happen on GitHub Issues and in GitHub PRs.
Larger contributions require a
[design review](/contribute/design-documents).
* Added to Bazel's Continuous Integration system if not already present.
* Supportable and aligned with Bazel product direction
* **Code review**. All changes in all `bazelbuild` repositories require
review:
* All PRs must be approved by an Owner or Maintainer.
* Only Owners and Maintainers can merge PRs.
* **Compatibility**. Owners may need to reject or request modifications to PRs
in the unlikely event that the change requires substantial modifications to
internal Google systems.
* **AI-assisted contributions**. AI tools are welcome to assist contributions,
provided contributors understand the change, own and support the code,
write concise summaries for humans, and respect project complexity. See the
[AI-assisted contributions policy](/contribute/ai-assisted-contributions).
* **Documentation**. Where relevant, feature contributions should include
documentation updates.
For more details on contributing to Bazel, see our
[contribution guidelines](/contribute/).
# Writing release notes
Source: https://bazel.build/contribute/release-notes
This document is targeted at Bazel contributors.
Commit descriptions in Bazel include a `RELNOTES:` tag followed by a release
note. This is used by the Bazel team to track changes in each release and write
the release announcement.
## Overview
* Is your change a bugfix? In that case, you don't need a release note. Please
include a reference to the GitHub issue.
* If the change adds / removes / changes Bazel in a user-visible way, then it
may be advantageous to mention it.
If the change is significant, follow the [design document policy](/contribute/design-documents) first.
## Guidelines
The release notes will be read by our users, so it should be short (ideally one
sentence), avoid jargon (Bazel-internal terminology), should focus on what the
change is about.
* Include a link to the relevant documentation. Almost any release note should
contain a link. If the description mentions a flag, a feature, a command name,
users will probably want to know more about it.
* Use backquotes around code, symbols, flags, or any word containing an
underscore.
* Do not just copy and paste bug descriptions. They are often cryptic and only
make sense to us and leave the user scratching their head. Release notes are
meant to explain what has changed and why in user-understandable language.
* Always use present tense and the format "Bazel now supports Y" or "X now does
Z." We don't want our release notes to sound like bug entries. All release
note entries should be informative and use a consistent style and language.
* If something has been deprecated or removed, use "X has been deprecated" or "X
has been removed." Not "is removed" or "was removed."
* If Bazel now does something differently, use "X now $newBehavior instead of
$oldBehavior" in present tense. This lets the user know in detail what to
expect when they use the new release.
* If Bazel now supports or no longer supports something, use "Bazel now supports
/ no longer supports X".
* Explain why something has been removed / deprecated / changed. One sentence is
enough but we want the user to be able to evaluate impact on their builds.
* Do NOT make any promises about future functionality. Avoid "this flag will be
removed" or "this will be changed." It introduces uncertainty. The first thing
the user will wonder is "when?" and we don't want them to start worrying about
their current builds breaking at some unknown time.
## Process
As part of the [release process](https://github.com/bazelbuild/continuous-integration/blob/master/docs/release-playbook.md),
we collect the `RELNOTES` tags of every commit. We copy everything in a [Google Doc](https://docs.google.com/document/d/1wDvulLlj4NAlPZamdlEVFORks3YXJonCjyuQMUQEmB0/edit)
where we review, edit, and organize the notes.
The release manager sends an email to the
[bazel-dev](https://groups.google.com/forum/#!forum/bazel-dev) mailing-list.
Bazel contributors are invited to contribute to the document and make sure
their changes are correctly reflected in the announcement.
Later, the announcement will be submitted to the [Bazel blog](https://blog.bazel.build/), using the [bazel-blog repository](https://github.com/bazelbuild/bazel-blog/tree/master/_posts).
# Searching the codebase
Source: https://bazel.build/contribute/search
## Product overview
Bazel's [code search and source browsing interface](https://source.bazel.build)
is a web-based tool for browsing Bazel source code repositories. You can
use these features to navigate among different repositories, branches, and
files. You can also view history, diffs, and blame information.
## Getting started
Note: For the best experience, use the latest version of Chrome, Safari, or
Firefox.
To access the code search and source browsing interface, open
[https://source.bazel.build](https://source.bazel.build) in your web browser.
The main screen appears. This screen contains the following components:
1. The Breadcrumb toolbar. This toolbar displays your current location in the
repository and allows you to move quickly to another location such as another
repository, or another location within a repository, such as a file, branch, or
commit.
2. A list of repositories that you can browse.
At the top of the screen is a search box. You can use this box to search for
specific files and code.
## Working with repositories
### Opening a repository
To open a repository, click its name from the main screen.
Alternatively, you can use the Breadcrumb toolbar to browse for a
specificrepository. This toolbar displays your current location in the
repository and allows you to move quickly to another location such as another
repository, or another location within a repository, such as a file, branch, or
commit.
### Switch repositories
To switch to a different repository, select the repository from the Breadcrumb toolbar.
### View a repository at a specific commit
To view a repository at a specific commit:
1. From the view of the repository, select the file.
2. From the Breadcrumb toolbar, open the **Branch** menu.
3. In the submenu that appears, click **Commit**.
4. Select the commit you want to view.
The interface now shows the repository as it existed at that commit.
### Open a branch, commit, or tag
By default, the code search and source browsing interface opens a repository to
the default branch. To open a different branch, from the Breadcrumb toolbar,
click the **Branch/Commit/Tag** menu. A submenu opens, allowing you to select a
branch using a branch name, a tag name, or through a search box.
* To select a branch using a branch name, select **Branch** and then click the
name of the branch.
* To select a branch using a tag name, select **Tag** and
then click the tag name.
* To select a branch using a commit id, select **Commit** and then click the
commit id.
* To search for a branch, commit, or tag, select the corresponding item and
type a search term in the search box.
## Working with files
When you select a repository from the main screen, the screen changes to display
a view of that repository. If a README file exists, its contents appear in the
file pane, located on the right side of the screen. Otherwise, a list of
repository's files and folders appear. On the left side of the screen is a tree
view of the repository's files and folders. You can use this tree to browse and
open specific files.
Notice that, when you are viewing a repository, the Breadcrumb toolbar now has
three components:
* A **Repository** menu, from which you can select different repositories
* A **Branch/Commit/Tag** menu, from which you can select specific branches,
tags, or commits
* A **File path** box, which displays the name of the current file or folder
and its corresponding path
### Open a file
You can open a file by browsing to its directory and selecting it. The view of
the repository updates to show the contents of the file in the file pane, and
its location in the repository in the tree pane.
### View file changes
To view file changes:
1. From the view of the repository, select the file.
2. Click **BLAME**, located in the upper-right corner.
The file pane updates to display who made changes to the file and when.
### View change history
To view the change history of a file:
1. From the view of the repository, select the file.
2. Click **HISTORY**, located in the upper-right corner.
The **Change history** pane appears, showing the commits for this file.
### View code reviews
For Gerrit code reviews, you can open the tool directly from the Change History pane.
To view the code review for a file:
1. From the view of the repository, select the file.
2. Click **HISTORY**, located in the upper-right corner. The Change History pane
appears, showing the commits for this file.
3. Hover over a commit. A **More** button (three vertical dots) appears.
4. Click the **More** button.
5. Select **View code review**.
The Gerrit Code Review tool opens in a new browser window.
### Open a file at a specific commit
To open a file at a specific commit:
1. From the view of the repository, select the file.
2. Click **HISTORY**, located in the upper-right corner. The Change History pane
appears, showing the commits for this file.
3. Hover over a commit. A **VIEW** button appears.
4. Click the **VIEW** button.
### Compare a file to a different commit
To compare a file at a different commit:
1. From the view of the repository, select the file. To compare from two
different commits, first open the file at that commit.
2. Hover over a commit. A **DIFF** button appears.
3. Click the **DIFF** button.
The file pane updates to display a side-by-side comparison between the two
files. The oldest of the two commits is always on the left.
In the Change History pane, both commits are highlighted, and a label indicates
if the commit is displayed on the left or the right.
To change either file, hover over the commit in the Change History pane. Then,
click either the **Left** or **Right** button to have the open the commit on the
left or right side of the diff.
### Browsing cross references
Another way to browse source repositories is through the use of cross
references. These references appear automatically as hyperlinks within a given
source file.
To make cross references easier to identify, click **Cross References**,
located in the upper-right corner. This option displays an underline below all
cross references in a file.
**Note:** If **Cross References** is grayed out, it indicates that
cross references are not available for that file.
Click a cross reference to open the Cross Reference pane. This pane contains
two sections:
* A **Definition** section, which lists the file or files that define the
reference
* A **References** section, which lists the files in which the reference also
appears
Both sections display the name of the file, as well as the line or lines
that contains the reference. To open a file from the Cross Reference pane,
click the line number entry. The file appears in a new section of the pane,
allowing you to continue to browse the file while keeping the original file
in view.
You can continue to browse cross references using the Cross Reference pane, just
as you can in the File pane. When you do, the pane displays a breadcrumb trail,
which you can use to navigate between different cross references.
## Searching for code
You can search for specific files or code snippets using the search box located
at the top of the screen. Searches are always against the default branch.
All searches use [RE2 regular expressions](https://github.com/google/re2/wiki/Syntax)
by default. If you do not want to use regular expressions, enclose your search
in double quotes ( " ).
**Note:** To quickly search for a specific file, either add a backslash in front
of the period, or enclose the entire file name in quotes.
```
foo\.java
"foo.java"
```
You can refine your search using the following filters.
**Filter**
**Other options**
**Description**
**Example**
lang:
language:
Perform an exact match by file language.
lang:java test
file:
filepath:\
path:\
f:
case:yes
Make the search case sensitive. By default, searches are not case-sensitive.