A User's Guide to Bazel

Related Documentation

Contents

Introduction

What is Bazel?

Bazel is a build system that emphasizes correctness and reproducibility of the build, speed of clean and incremental builds, and integration of the toolchain with IDEs and analysis tools. It is both a specification for code organization and a language for expressing software dependencies and the steps involved in a build.

Background reading

Various aspects of the Bazel build system are described in other documents. The BUILD Concept Reference introduces the primary concepts of the Bazel build system; this is a place to start if you are new to Bazel. The Bazel BUILD Encyclopedia of Functions describes all the functions of the Bazel build language, including the syntax and semantics of the current build rules. Getting Started with BUILD files is a tutorial on how to write BUILD files.

Bazel concepts

Running the bazel tool is easy. Simply go to your workspace root and type bazel. (Bazel may also be invoked from the subdirectories of your workspace.)

  % bazel help
  Usage: bazel <command> <options> ...

  Available commands:
    analyze-profile     Analyzes build profile data.
    build               Builds the specified targets.
    canonicalize-flags  Canonicalize Bazel flags.
    clean               Removes output files and optionally stops the server.
    help                Prints help for commands, or the index.
    info                Displays runtime info about the Bazel server.
    query               Executes a dependency graph query.
    run                 Runs the specified target.
    shutdown            Stops the Bazel server.
    test                Builds and runs the specified test targets.
    version             Prints version information for Bazel.

  Getting more help:
    bazel help <command>
                     Prints help and options for <command>.
    bazel help startup_options
                     Options for the JVM hosting Bazel.
    bazel help target-syntax
                     Explains the syntax for specifying targets.
    bazel help info-keys
                     Displays a list of keys used by the info command.

The bazel tool performs many functions, called commands; users of Perforce, CVS and Subversion will be familiar with this "Swiss army knife" arrangement. The most commonly used one is of course bazel build. You can browse the online help messages using bazel help. The links in the message above refer to the relevant section of this document.

Client/server implementation

The Bazel system is implemented as a long-lived server process. This allows it to perform many optimizations not possible with a batch-oriented implementation, such as caching of BUILD files, dependency graphs, and other metadata from one build to the next. This improves the speed of incremental builds, and allows different commands, such as build and query to share the same cache of loaded packages, making queries very fast.

When you run bazel, you're running the client. The client finds the server based on the path of the workspace directory and your userid, so if you build in multiple workspaces, you'll have multiple Bazel server processes. Multiple users on the same workstation can build concurrently in the same workspace. If the client cannot find a running server instance, it starts a new one. The server process will stop after a period of inactivity (3 hours, by default).

For the most part, the fact that there is a server running is invisible to the user, but sometimes it helps to bear this in mind. For example, if you're running scripts that perform a lot of automated builds in different directories, it's important to ensure that you don't accumulate a lot of idle servers; you can do this by explicitly shutting them down when you're finished with them, or by specifying a short timeout period.

The name of a Bazel server process appears in the output of ps x or ps -e f as bazel(dirname), where dirname is the basename of the directory enclosing the root of the Bazel workspace. For example:

  % ps -e f
  16143 ?        Sl     3:00 bazel(src-jrluser2) -server -Djava.library.path=...

This makes it easier to find out which server process belongs to a given workspace. (Beware that with certain other options to ps, Bazel server processes may be named just java.) Bazel servers can be stopped using the shutdown command.

In some cases, such as in continuous builds, it may be desirable to disable client/server mode and instead run Bazel as a batch application. See the --batch switch below.

.bazelrc, the Bazel configuration file, the --bazelrc=file option, and the --config=value option

Bazel accepts many options. Typically, some of these are varied frequently (e.g. --subcommands) while others stay the same across several builds (e.g. --package_path). To avoid having to specify these constant options every time you do a build or run some other Bazel command, Bazel allows you to specify options in a configuration file.

Bazel looks for an optional configuration file in the location specified by the --bazelrc=file option. If this option is not specified then, by default, Bazel looks for the file called .bazelrc in one of two directories: first, in the workspace root directory, then in your home directory. If it finds a file in the first (workspace-specific) location, it will not look at the second (global) location.

The --bazelrc=file option must appear before the command name (e.g. build), and must use the = syntax—a space is not allowed.

The option --bazelrc=/dev/null effectively disables the use of a configuration file. We strongly recommend that you use this option when performing release builds, or automated tests that invoke Bazel.

Aside from the configuration file described above, Bazel also looks for a master configuration file next to the binary. The name of this file is the same as the name of the binary with the string .bazelrc attached. This file is not intended to be user-modifiable; its purpose is for the Bazel team to be able to turn experimental features on or off immediately without releasing a new Bazel version, should an urgent need arise. Reading of this file can be disabled using the --nomaster_bazelrc option.

Like all UNIX "rc" files, the .bazelrc file is a text file with a line-based grammar. Lines starting # are considered comments and are ignored, as are blank lines. Each line contains a sequence of words, which are tokenized according to the same rules as the Bourne shell. The first word on each line is the name of a Bazel command, such as build or query. The remaining words are the default options that apply to that command. More than one line may be used for a command; the options are combined as if they had appeared on a single line. (Users of CVS, another tool with a "Swiss army knife" command-line interface, will find the syntax familiar to that of .cvsrc.)

Startup options may be specified in the .bazelrc file using the command startup. These options are described in the interactive help at bazel help startup_options. Options specified in the command line always take precedence over those from a configuration file, and options in the user-specific configuration file always take precedence over the master one. Options may include words other than flags, such as the names of build targets, etc; these are always prepended to the explicit argument list provided on the command-line, if any.

Common command options may be specified in the .bazelrc file using the command common.

In addition, commands may have :name suffixes. These options are ignored by default, but can be pulled in through the --config=name option, either on the command line or in a .bazelrc file. The intention is that these bundle command line options that are commonly used together, for example --config=releasemode.

The command named import is special: if Bazel encounters such a line in a .bazelrc file, it parses the contents of the file referenced by the import statement, too. Options specified in an imported file take precedence over ones specified before the import statement, options specified after the import statement take precedence over the ones in the imported file, and options in files imported later take precedence over files imported earlier.

Here's an example ~/.bazelrc file:

  # Bob's Bazel option defaults

  startup --batch --host_jvm_args=-XX:-UseParallelGC
  import /home/bobs_project/bazelrc
  build --package_path %workspace%:/home/bob/stuff/bazel --keep_going --jobs 600
  build --color=yes
  query --keep_going

  build:releasemode --define buildtype="Release" --test_timeout=3600

Building programs with Bazel

The most important function of Bazel is, of course, building code. Type bazel build followed by the name of the target you wish to build. Here's a typical session:

  % bazel build //foo
  Welcome to Bazel
  ____Loading package: foo
  ____Loading package: bar
  ____Loading package: baz
  ____Loading complete.  Analyzing...
  ____Building 1 target...
  ____[0%] Executing Genrule //bar:helper_rule
  ____[10%] Executing Genrule //baz:another_helper_rule
  ____[95%] Building foo/foo.jar
  Target //foo:foo up-to-date:
    bazel-bin/foo/foo.jar
    bazel-bin/foo/foo
  ____Elapsed time: 9.905s

Bazel prints a welcome message, followed by progress messages as it loads all the packages in the transitive closure of dependencies of the requested target and analyzes them for correctness, then executes the compilers and other tools of the build.

Bazel prints progress messages during the execution phase of the build, showing the current build step that is being started, and approximately what fraction of the build is complete. If the estimate of the total workload includes steps that are already up-to-date, progress will advance rapidly when this is discovered. Since progress is reported when steps are started, rather than completed, the reported progress will never reach 100%, and, if multiple steps are started with no intervening completions, the reported progress will not change.

At the end of the build Bazel prints which targets were requested, whether or not they were successfully built, and if so, where the output files can be found. Scripts that run builds can reliably parse this output; see --show_result for more details.

Typing the same command again:

  % bazel build //foo
  Welcome to Bazel
  ____Loading complete.  Analyzing...
  ____Building 1 target...
  Target //foo:foo up-to-date:
    bazel-bin/foo/foo.jar
    bazel-bin/base/foo
  ____Elapsed time: 0.280s

we see an incremental build: in this case, there are no packages to re-load, since nothing has changed, and no build steps to execute. In most cases, this results in dramatically faster output time.

Setting up a Bazel workspace

Before you can start a build, you will need a Bazel workspace. This is simply a directory tree that contains all the source files needed to build your application. Bazel allows you to perform a build from a completely read-only volume.

Setting up a --package_path

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:

  % bazel build --package_path %workspace%:/some/other/root

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, we recommend that you specify it in your Bazel configuration file 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

  % mkdir -p foo/bazel
  % cd foo/bazel
  % bazel build --package_path /some/other/path //foo

Specifying targets to build

Bazel allows a number of ways to specify the targets to be built. Collectively, these are known as target patterns. The on-line help displays a summary of supported patterns:

% bazel help target-syntax

Target pattern syntax
=====================

The Bazel label syntax (as used in BUILD files) is used to specify a
single target.  Bazel target patterns generalize this syntax to sets
of targets, and also support working directory-relative forms, recursion,
subtraction and filtering.  Examples:

Specifying a single target:

  //foo/bar:wiz     The single target '//foo/bar:wiz'.
  foo/bar/wiz       Equivalent to the first existing one of these:
                      //foo/bar:wiz
                      //foo:bar/wiz
  //foo/bar         Equivalent to '//foo/bar:bar'.

Specifying all rules in a package:

  //foo/bar:all       Matches all rules in package 'foo/bar'.

Specifying all rules recursively beneath a package:

  //foo/...:all     Matches all rules in all packages beneath directory 'foo'.
  //foo/...           (ditto)

Working-directory relative forms:  (assume cwd = 'bazel/foo')

  Target patterns which do not begin with '//' are taken relative to
  the working directory.  Patterns which begin with '//' are always
  absolute.

  ...:all           Equivalent to  '//foo/...:all'.
  ...                 (ditto)

  bar/...:all       Equivalent to  '//foo/bar/...:all'.
  bar/...             (ditto)

  bar:wiz           Equivalent to '//foo/bar:wiz'.
  :foo              Equivalent to '//foo:foo'.

  bar:all           Equivalent to '//foo/bar:all'.
  :all              Equivalent to '//foo:all'.

Note: The "..." (recursive) syntax does not follow directory symlinks.

Summary of target wildcards:

  :all,             Match all rules in the specified packages.
  :*, :all-targets  Match all targets (rules and files) in the specified
                      packages, including .par and _deploy.jar files.

Subtractive patterns:

  Target patterns may be preceded by '-', meaning they should be
  subtracted from the set of targets accumulated by preceding
  patterns.  For example:

    % bazel build -- bigtable/... -bigtable/contrib/...

  builds everything in 'bigtable', except 'contrib'.  As usual, the
  '--' is required to prevent '-b' from being interpreted as an
  option.

Whereas Bazel labels are used to specify individual targets, e.g. for declaring dependencies in BUILD files, Bazel's target patterns are a syntax for specifying multiple targets: they are a generalization of the label syntax for sets of targets, using wildcards. In the simplest case, any valid label is also a valid target pattern, identifying a set of exactly one target.

foo/... is a wildcard over packages, indicating all packages recursively beneath directory foo (for all roots of the package path). :all (or :all-rules) is a wildcard over targets, matching all rules within a package. These two may be combined, as in foo/...:all, and when both wildcards are used, this may be abbreviated to foo/....

In addition, :* (or :all-targets) is a wildcard that matches every target in the matched packages, including files that aren't normally built by any rule, such as _deploy.jar files associated with java_binary rules and .par files associated with py_binary rules. This implies that :* denotes a superset of :all; while potentially confusing, this syntax does allow the familiar :all wildcard to be used for typical builds, in which the building of _deploy.jar and .par targets is not desired.

In addition, Bazel allows a slash to be used instead of the colon required by the label syntax; this is often convenient when using Bash filename expansion. For example, foo/bar/wiz is equivalent to //foo/bar:wiz (if there is a package foo/bar) or to //foo:bar/wiz (if there is a package foo).

Many Bazel commands accept a list of target patterns as arguments, and they all honor the prefix negation operator `-'. This can be used to subtract a set of targets from the set specified by the preceding arguments. For example,

  bazel build foo/... bar/...

means "build all targets beneath foo and all targets beneath bar", whereas

  bazel build -- foo/... -foo/baz/...

means "build all targets beneath foo except those beneath foo/baz". (The -- argument is required to prevent the subsequent arguments starting with - from being interpreted as additional options.)

Targets with obsolete=1 or tags=["manual"] will be ignored by all command line wildcards (..., :*, :all, etc). The only way to run such targets is to specify them explicitly on the command line.

Bash completion of Bazel commands

If you use Bash, and source /etc/bash_completion, Bash's command-completion is augmented to understand Bazel's options, command set, and target syntax. For example, hitting TAB after typing a package name followed by a colon will expand the names of rules defined in that package:

  % source /etc/bash_completion
  % bazel build bar:<TAB>
  aardvark
  alpha
  chestnut
  walnut
  ...
  % bazel build bar:a<TAB>
  aardvark
  alpha
  % bazel build bar:al<TAB>
  % bazel build bar:alpha

Similarly, hitting TAB after bazel test package: will expand the names of just the test rules in that package.

The completion script will additionally attempt to expand --key=value options too.

Correct incremental rebuilds

One of the primary goals of the Bazel project is to ensure correct incremental rebuilds. Previous build tools, especially those based on Make, make several unsound assumptions in their implementation of incremental builds.

Firstly, that timestamps of files increase monotonically. While this is the typical case, it is very easy to fall afoul of this assumption; syncing to an earlier revision of a file causes that file's modification time to decrease; Make-based systems will not rebuild. A similar situation may arise when switching to a source-control view of an earlier milestone.

More generally, while Make detects changes to files, it does not detect changes to commands. If you alter the options passed to the compiler in a given build step, Make will not re-run the compiler, and it is necessary to manually discard the invalid outputs of the previous build using make clean.

Also, Make is not robust against the unsuccessful termination of one of its subprocesses after that subprocess has started writing to its output file. While the current execution of Make will fail, the subsequent invocation of Make will blindly assume that the truncated output file is valid (because it is newer than its inputs), and it will not be rebuilt. Similarly, if the Make process is killed, a similar situation can occur.

Bazel avoids these assumptions, and others. Bazel maintains a database of all work previously done, and will only omit a build step if it finds that the set of input files (and their timestamps) to that build step, and the compilation command for that build step, exactly match one in the database, and, that the set of output files (and their timestamps) for the database entry exactly match the timestamps of the files on disk. Any change to the input files or output files, or to the command itself, will cause re-execution of the build step.

The benefit to users of correct incremental builds is: less time wasted due to confusion. (Also, less time spent waiting for rebuilds caused by use of make clean, whether necessary or pre-emptive.)

Build consistency and incremental builds

Formally, we define the state of a build as consistent when all the expected output files exist, and their contents are correct, as specified by the steps or rules required to create them. When you edit a source file, the state of the build is said to be inconsistent, and remains inconsistent until you next run the build tool to successful completion. We describe this situation as unstable inconsistency, because it is only temporary, and consistency is restored by running the build tool.

There is another kind of inconsistency that is pernicious: stable inconsistency. If the build reaches a stable inconsistent state, then repeated successful invocation of the build tool does not restore consistency: the build has gotten "stuck", and the outputs remain incorrect. Stable inconsistent states are the main reason why users of Make (and other build tools) type make clean. Discovering that the build tool has failed in this manner (and then recovering from it) can be time consuming and very frustrating.

Conceptually, the simplest way to achieve a consistent build is to throw away all the previous build outputs and start again: make every build a clean build. This approach is obviously too time-consuming to be practical (except perhaps for release engineers), and therefore to be useful, the build tool must be able to perform incremental builds without compromising consistency.

Correct incremental dependency analysis is hard, and as described above, many other build tools do a poor job of avoiding stable inconsistent states during incremental builds. In contrast, Bazel offers the following guarantee: after a successful invocation of the build tool during which you made no edits, the build will be in a consistent state. (If you edit your source files during a build, Bazel makes no guarantee about the consistency of the result of the current build. But it does guarantee that the results of the next build will restore consistency.)

As with all guarantees, there comes some fine print: there are some known ways of getting into a stable inconsistent state with Bazel. We won't guarantee to investigate such problems arising from deliberate attempts to find bugs in the incremental dependency analysis, but we will investigate and do our best to fix all stable inconsistent states arising from normal or "reasonable" use of the build tool.

Deleting the outputs of a build

bazel clean

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.

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 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, however, that 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. However, we recognize that Bazel's incremental rebuilds are not perfect; clean may be used to recover a consistent state when problems arise.

Bazel's design is such that these problems are fixable; we consider such bugs a high priority, and will do our best fix them. We encourage developers to get out of the habit of using clean and into that of reporting bugs in the tools.

Phases of a build

In Bazel, a build occurs in three distinct phases; as a user, understanding the difference between them provides insight into the options which control a build (see below).

Loading phase

The first is loading during which all the necessary BUILD files for the initial targets, and their transitive closure of dependencies, are loaded, parsed, evaluated and cached.

For the first build after a Bazel server is started, the loading phase can take many seconds if many BUILD files are loaded from high-latency / remotely hosted filesystems. In subsequent builds, especially if no BUILD files have changed, loading occurs very quickly.

Errors reported during this phase include: package not found, target not found, lexical and grammatical errors in a BUILD file, and evaluation errors.

Analysis phase

The second phase, analysis, involves the semantic analysis and validation of each build rule, the construction of a build dependency graph, and the determination of exactly what work is to be done in each step of the build.

Like loading, analysis also takes several seconds when computed in its entirety. However, Bazel can cache the dependency graph from one build to the next, as an optimization; see --cache_analysis). This option makes this step extremely fast in the case where the packages haven't changed since the previous build.

Errors reported at this stage include: inappropriate dependencies, invalid inputs to a rule, and all rule-specific error messages.

The loading and analysis phases are generally very vast; this is partly because Bazel avoids unnecessary file I/O at this stage, reading only BUILD files in order to determine the work to be done. This is by design, and makes Bazel a good foundation for analysis tools, such as Bazel's query command, which is implemented atop the loading phase.

Execution phase

The third and final phase of the build is execution. This phase ensures that the outputs of each step in the build are consistent with its inputs, re-running external compilation tools as necessary. This step is where the build spends the majority of its time, ranging from a few seconds to over an hour for a large build. Errors reported during this phase include: missing source files, errors in an external compilation tool, or failure of a tool to produce the expected set of outputs.

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'.

Options that affect how packages are located

See also the --show_package_location option.

--package_path

This option specifies the set of directories that are searched to find the BUILD file for a given package; see Setting up a Bazel workspace above for a complete explanation.

--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.

if you use a workspace layout that maps the entire source tree into some readonly path while mapping writable subsections into another path, you may need to use this option to solve the following problem: when you have a pending deletion of a package in your Bazel workspace, but there is still a BUILD file for this package somewhere on your package path, Bazel will consider the package existent unless this option tells it not to.

Consider the following scenario: you have two packages, x and x/y (a subpackage). When you populate your client, both packages exist beneath both package-path roots:

  ~/src/$WORKSPACE_WRITABLE_ROOT/
               /x/BUILD
               /x/y/BUILD            <-- about to delete this
               /x/y/foo.txt

  ~/src/$WORKSPACE_READONLY_ROOT/
                        /x/BUILD
                        /x/y/BUILD
                        /x/y/foo.txt

Now you delete ~/src/$WORKSPACE_WRITABLE_ROOT/x/y/BUILD, intending to merge the contents of package x/y into x, and now when x's BUILD file refers to the file x/y/foo.txt, it uses the label //x:y/txt.

However, x/y may have been deleted in the read/write workspace, but the package still exists elsewhere on the package-path. In this situation, Bazel will issue an error, saying that //x:y/txt is an invalid label because package x/y still exists (beneath $WORKSPACE_READONLY_ROOT). The solution is to specify --deleted_packages x/y.

Error checking options

These options control Bazel's error-checking and/or warnings.

--check_constraint constraint

This option takes an argument that specifies which constraint should be checked.

Bazel performs special checks on each rule that is annotated with the given constraint.

The supported constraints and their checks are as follows:

--[no]check_licenses

This option causes Bazel to analyze the licenses and distribs clauses in BUILD files to identify uses of third party code that are incompatible with how a product is going to be distributed.

  % bazel build --check_licenses //foo:bar

will check the licensing of all packages used by "//foo:bar", to ensure that they are compatible with how bar is distributed. If the licensing check finds no errors, then bar will be built.

--[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. This option is intended to be used to help focus efforts on fixing warnings in packages under development. Here are some typical values for this option:

--output_filter= Show all output.
--output_filter='^//(first/project|second/project):' Show the output for the specified packages.
--output_filter=DONT_MATCH_ANYTHING Don't show output.

If this option is not given, a default filter will be created according to the --auto_output_filter option.

--auto_output_filter (none|packages|subpackages)

If no --output_filter option is given, Bazel creates an output filter from the targets listed on the command line:

--[no]analysis_warnings_as_errors

When this option is enabled, visible analysis warnings (as specified by the output filter) are treated as errors, effectively preventing the build phase from starting. This feature can be used to enable strict builds that do not allow new warnings to creep into a project.

Flags options

These options control which options Bazel will pass to other tools.

--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:

  % bazel build --jvmopt="-server -Xms256m" java/com/myorg/foo/bar:all

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:

  % bazel build --javacopt="-g:source,lines" //myprojects:prog

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:

  -g -source 7 -target 7 -encoding UTF-8 -Xlint:all,-serial,-processing,-fallthrough,-deprecation,-sunapi,-rawtypes,-try,-cast,-varargs,-finally,-static,-dep-ann,-overrides,-unchecked -Werror:+divzero,+empty

Note that 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.

-Werror:(+|-)warning[,(+|-)warning]*

This javac option enables selective treating of warnings as errors. To specify all or none of the warnings, use +all or -all. The last specification for any warning wins. A typical value that enables all warnings as errors except those that may be caused upstream is:

  -Werror:+all,-deprecation,-unchecked

The divzero and empty javac warnings are promoted to errors by default. These errors cannot be disabled from the Bazel command line or the BUILD file. However, in extreme cases they may be disabled by adding a @SuppressWarnings({"divzero", "empty"}) annotation to your Java source.

-extra_checks[:(off|on)]

This javac option enables extra correctness checks. Any problems found will be presented as errors. Either -extra_checks or -extra_checks:on may be used to force the checks to be turned on. -extra_checks:off completely disables the analysis. When this option is not specified, the default behavior is used.

--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.

--javawarn (all|cast|deprecation|empty|unchecked|fallthrough|path|rawtypes|serial|finally|overrides)

This option is used to enable Java warnings across an entire build. It takes an argument which is a javac warning to be enabled, overriding any other Java options that disable the given warning. The arguments to this option are appended to the "-Xlint:" flag to javac, and must be exactly one of the listed warnings.

For example:

  % bazel build --javawarn="deprecation" --javawarn="unchecked" //java/...

Note that changing --javawarn settings will force a recompilation of all affected classes.

Semantics options

These options affect the build commands and/or the output file contents.

--java_cpu cpu

This option specifies the name of the CPU architecture that should be used to build libraries dynamically loaded by the JVM.

--android_cpu cpu

This option specifies the name of the CPU architecture that should be used to build libraries dynamically loaded by the Android applications.

--define name=value

This option takes an argument which is a variable definition of the form "name=value". The defined variable is integrated into the build environment as if they were declared in the BUILD file using a vardef statement. This option can occur multiple times on the command-line. If the same variable is declared more than once, the last definition is the one which is used.

  % bazel build --define "INCLUDE_X=1" --define "LINK_Y=no" foo:bar

will build target "foo:bar", and all its prerequisites, with the variable assignments INCLUDE_X=1, and LINK_Y=no in the "Make" environment.

Definitions specified in this way are global: they apply to all packages. The order of precedence for definitions of "Make" variables, highest first, is: --define k=..., vardef('k', ...), then the global defaults.

--[no]translations

The --notranslations option can be used to disable the bundling of translated Java messages into the jar for each affected rule. By default, Bazel will locate the Java message translations on the package path using the targets defined by --message_translations and use the resulting files for translating the messages for each java_library. If no targets are specified, Bazel does not bundle translations.

--message_translations translation-targets

This option specifies the targets containing the Java message translations. These targets are used to find the Java message translations for each locale. This option can be used multiple times to specify a list of translations. The targets are specified using standard label syntax. Rules that output directories, such as Fileset and misbehaving genrules, cannot be used with this flag.

Typically translations will increase build times significantly.

  % bazel build \
        --message_translations=//some/package/client:translations \
        --message_translations=//some/package/server:translations \
        java/com/myorg/myapp:Myapp_deploy.jar

will build the Myapp_deploy.jar including translations. The translations will be retrieved from the project-specific translations in //some/package/client:translations and //some/package/server:translations

Version options

These options select which versions Bazel will use for the other tools that Bazel invokes.

--android_sdk version

This option specifies the version of the Android SDK/platform toolchain and Android runtime library that will be used to build any Android-related rule.

--java_langtools label

This option specifies the label of the Java langtools jar (used by Java compilation tools).

--javabase path

This option specifies the value of the JAVABASE "Make" variable which is passed to all subprocesses (e.g. external Java programs) during a build.

This does not select the Java compiler that is used to compile Java source files. There is currently no way to do that, but you can use --javacopt="-source 5 -target 5" (for example) to select a different version of the source language (Java) or target language (JVM) during compilation.

--javac_bootclasspath label

This option specifies the label of the bootclasspath that should be used by the Java compiler. This lets you compile against different versions of the Java class library, for example, version 7 instead of version 6.

Build strategy options

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 on the build.

--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. The default is 200.

Setting this to -1 means "no limit": use as many threads as possible.

Note that 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 --ram_utilization_factor option.

--progress_report_interval n

Bazel periodically prints a progress report on jobs that are not finished yet (e.g. 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.

--ram_utilization_factor percentage

This option, which takes an integer argument, specifies what percentage of the system's RAM Bazel should try to use for its subprocesses. This option affects how many processes Bazel will try to run in parallel. The default value is 67. If you run several Bazel builds in parallel, using a lower value for this option may avoid thrashing and thus improve overall throughput. Using a value higher than the default is NOT recommended. Note that Bazel's estimates are very coarse, so the actual RAM usage may be much higher or much lower than specified. Note also that this option does not affect the amount of memory that the Bazel server itself will use.

This option has no effect if --resource_autosense is enabled.

--local_resources availableRAM,availableCPU,availableIO

This option, which takes three comma-separated floating point arguments, specifies the amount of local resources that Bazel can take into consideration when scheduling build and test activities. Option expects amount of available RAM (in MB), number of CPU cores (with 1.0 representing single full core) and workstation I/O capability (with 1.0 representing average workstation). By default Bazel will estimate amount of RAM and number of CPU cores directly from system configuration and will assume 1.0 I/O resource.

If this option is used, Bazel will ignore both --ram_utilization_factor and --resource_autosense options.

This option, which is currently enabled by default, specifies whether the runfiles symlinks for tests should be built on the local machine. Using --nobuild_runfile_links can be useful to validate if all targets build without incurring the overhead for building the runfiles trees.Within Bazel's output tree, the runfiles symlink tree is typically rooted as a sibling of the corresponding binary or test.

When Bazel tests are executed, their run-time data dependencies are gathered together in one place, and may be accessed by the test using paths of the form $TEST_SRCDIR/bazel/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 requires its own runfiles tree.

--[no]cache_analysis

This option enables an optimization: caching of the results of the analysis phase from one build to the next. The dependency graph from the previous build will be re-used if no build packages have been re-loaded due to changes, and no configuration options have changed. The optimization is enabled by default, but can be disabled via --nocache_analysis; this may be useful during fault isolation.

Typically, this option speeds up the analysis phase by a factor of at least a hundred, making analysis time a negligible fraction of total build time.

--[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. The drawback is that further incremental builds will be slower.

--[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 effects 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]resource_autosense

Bazel's default scheduling algorithm is based on fixed estimates of the available CPU/memory resources of the workstation. It does not account for the load of any unrelated jobs that happen to be running on your machine, such as another Bazel build in a different workspace.

The --resource_autosense option enables a different scheduling algorithm for the execution of build steps. It causes Bazel to poll the system CPU load and available memory periodically. This data is used to limit the number of commands executed simultaneously on the workstation, ensuring that the system remains responsive, especially when other jobs are running on the machine.

(Note, neither algorithm takes into account the actual (dynamic) cost of each build step.)

Output selection options

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, timeout, tag, or language. 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]compile_only

This option forces Bazel to execute only "lightweight" compilation steps related to the specified targets. At this time such steps only include compilation of sources for java_* rules without building dependencies.

This option can be useful to quickly validate a given Java target for compilation errors. In particular, it might be especially useful when specified together with the --compile_one_dependency option.

--[no]compilation_prerequisites_only

Given this option, Bazel will only build files that are prerequisites for compilation of the given target (for example, generated source files), but will not build the target itself.

This option can be useful to quickly validate a given Java target for compilation errors. In particular, it might be especially useful when specified together with the --compile_one_dependency option.

--[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 (e.g. for pre-submit checks) without incurring the cost of a build.

See also --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: for each source filename, one rule that depends on it will be built. 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.

--[no]source_jars

By default, this option is disabled. If enabled, Bazel will also build all source jars in the transitive closure of the targets specified on the command line.

--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 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_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.

Examples:

    :my_junit3_test --test_filter=com.myorg.myproj.MyClass#testMyStuff
                                                 # class or method (multiple
                                                 # values OK, separate w/commas)
    :my_junit4_test --test_filter=Frob.*ate      # regexp

Verbosity options: options that control what Bazel prints

These options control the verbosity of Bazel's output, either to the terminal, or to additional log files.

--dump_makefile

If this option is specified, Bazel will dump a representation of the action graph for the current build request in (pseudo) make syntax to the file Makefile.bazel in the execution root directory.

This is for debugging purposes only. The format of the output file might change in future Bazel releases.

--dump_action_graph

If this option is specified, Bazel will dump a representation of the action graph for the current build request in GraphViz syntax to the file 'BazelActionGraph.dot' in the workspace root.

This is for debugging purposes only. The format of the output file might change in future Bazel releases.

--dump_action_graph_for_package=package

This option restricts the parts shown in an action graph to the given packages. This is only useful in conjunction with specifying --dump_action_graph.

--dump_action_graph_with_middlemen

This flag selects whether middlemen are shown in an action graph or not. Middlemen could be considered an implementation detail and tend to make graphs much larger. This is only usful in conjuction with specifying --dump_action_graph.

--dump_targets=(inputs|rules|all|packages)

If this option is specified, Bazel will dump the targets touched by the current build request to the file BazelTargets.txt.

--dump_to_stdout

If this option is specified, the options --dump_action_graph, --dump_makefile and --dump_targets will not dump to the files specified above but to stdout.

--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 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 data then can be analyzed or parsed using the bazel analyze-profile command. The Build profile can be useful in understanding where Bazel's build command is spending its time.

--[no]show_package_location

This option causes Bazel to display, as each package is loaded, the directory on the package path beneath which the package's BUILD file was found. This can be useful as a diagnostic aid. Nothing is printed if the directory was the Bazel workspace (%workspace%). For example:

INFO Loading package: foo/bar/scripts
INFO Loading package: foo/bar/main
INFO Loading package: baz from ../$WORKSPACE_READONLY_ROOT

--[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 only one progress message per n seconds. If n is -1, all progress messages will be displayed. The default value for this option is -1.

--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 (e.g. 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 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.

--show_builder_stats

This option will enable parallel builder to output several internal statistics after each completed action. Statistic includes following sections:

  time since the start of execution phase;
  queue:   cumulative number of queued and dequeued actions. At the end of the
           build those two numbers should be equal to the number of actions.
  threads: number of scheduled tasks, number of active threads in the pool,
           number of threads not waiting on resources and number of threads
           executing action payload;
  actions: number of actions waiting on single remaining unbuilt dependency
           before they can get scheduled and number of total actions in the
           build;
  locked:  number of threads being blocked by resource (ram, cpu, etc) locks.

  >>> [action name]: for actions that are potentially on the critical build path
                     (at the time of action completion there were no actions
                     awaiting execution).

Examples:

  ____13.5 s, queue: 400 / 262, threads: 138 / 20 / 19 / 18, actions: 47 (608), locked: 1

  ____22.8 s, queue: 464 / 453, threads: 11 / 11 / 3 / 3, actions: 16 (608), locked: 8 >>> action 'Building foo/bar/Myapp_deploy.jar'

Please, note, that this flag is mostly intended for internal Bazel profiling and can change or disappear at any time.

--subcommands (-s)

This option causes Bazel's execution phase to print the full command line for each command prior to executing it.

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!) All commands output by --subcommands are executable by /bin/sh or bash.

See also --verbose_failures, below.

--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.

Miscellaneous options

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 another user's client, or a read-only directory. 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:

Running tests with Bazel

To build and run tests with Bazel, type bazel test followed by the name of the test targets using embedded test runner.

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, especially when using a distributed environment.

Options for bazel test

--cache_test_results=(yes|no|auto) (-t)

If this option is set to yes then Bazel will only rerun a test if any of the following conditions apply:

If 'auto' (the default), the caching behavior will be the same as 'yes' except that Bazel will never cache test failures and never cache multiple test runs that were requested with --runs_per_test.

If 'no', all tests will be always executed unconditionally.

Note that 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.

--test_result_expiration=<seconds>

Specifies interval (in seconds) during which test results from the previous test execution will be considered valid. This option is applicable only when used with 'yes' or default ('auto') value of the --cache_test_results option. Otherwise, it is ignored. Setting option to 0 expires cached results immediately and, as such, is the same as --nocache_test_results. Setting the option to -1 results in never expiring the cached result.

--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 (e.g. 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 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 then 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. Bazel can generate a warning if the stated timeout is much too generous based on the results of the test run. This option is useful to help users decide on a good timeout value or sanity check existing timeout values.

Note that 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 (e.g. 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 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 (e.g. "--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.

--test_output output_style

Specifies how test output should be displayed:

--java_debug

This option causes the Java virtual machine of a java test to wait for a connection from a JDWP-compliant debugger (such as jdb or Eclipse) 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 executed locally. Each test will be executed in a separate subdirectory inside this directory. The directory will be cleaned at the beginning of the each bazel test command. By default, Bazel will place this directory under Bazel output base directory. Note that 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. By default, Bazel will use Test Encyclopedia 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 the test (not to the test runner). This option can be used multiple times to pass several arguments, e.g. --test_arg=--logtostderr --test_arg=--v=3.

--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),

--test_sharding_strategy strategy

Specifies one of the following strategies to be used for test sharding. With test sharding, each shard will run as a separate process and will execute approximately (1/N)th of the total number of tests methods. This can result in significant test latency improvements.

The default is explicit.

--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 (i.e. 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:

Examples:

        --run_under=/usr/bin/valgrind
        --run_under=/usr/bin/strace
        --run_under='/usr/bin/strace -c'
        --run_under='/usr/bin/valgrind --quiet --num-callers=20'
        --run_under=//testing/valgrind:tsan
        --run_under='//testing/valgrind:memcheck --gen-suppressions=all -v'

Test selection

As documented under Output selection options, you can filter tests by size, timeout, tag, or language. A convenience general name 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.

Test rule tags attribute keywords and other common attributes

Bazel modifies test behavior if it finds the following keywords in the tags attribute of the test rule:

There are also several other attributes that affect test behavior:

Running executables with Bazel

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:

  % bazel run -- java/myapp:myapp --arg1 --arg2
  Welcome to Bazel
  INFO: Loading package: java/myapp
  INFO: Loading package: foo/bar
  INFO: Loading complete.  Analyzing...
  INFO: Building 1 target...
  [0%] Building java/myapp/myapp
  [0%] Creating runfiles directory java/myapp/myapp.runfiles
  ...
  Target //java/myapp:myappp up-to-date:
    bazel-bin/java/myapp:myapp
  INFO: Elapsed time: 5.072s

  Hello there
  $EXEC_ROOT/java/myapp/myapp
  --arg1
  --arg2

Note the use of the --. This 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.

Options for bazel run

--run_under=command-prefix

This has the same effect as the --run_under option for bazel test (see above), 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.

Querying the dependency graph with Bazel

Bazel includes a query language for asking questions about the dependency graph used during the build. The query tool is 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 Language, revision 2. 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]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 ABC tree."

  bazel query --output location 'kind(genrule, deps(kind(".*_test rule", foo/bar/pebl/...)))'

Miscellaneous Bazel commands and options

The help command

The help command provides on-line help. By default, it shows a summary of available commands and help topics, as shown in the Bazel Concepts section above. Specifying an argument displays detailed help for a particular topic. Most topics are Bazel commands, e.g. 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.

The shutdown command

Bazel server processes (see Client/server implementation) may be stopped by using the shutdown command. This command causes the Bazel server to exit as soon as it becomes idle (i.e. after the completion of any builds or other commands that are currently in progress). 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. 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.

The info command

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

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 --define. 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.

The version command

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. Some of the interesting values are:

The analyze-profile command

The analyze-profile command analyzes data previously gathered during the build using --profile option. It provides several options to either perform analysis of the build execution or export data in the specified format.

The canonicalize-flags command

The canonicalize-flags 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, i.e., 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 that a small number of options cannot be reordered, because Bazel cannot ensure that the effect is identical.

Bazel 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.

--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: /usr/local/_bazel_myname/d41d8cd98f00b204e9800998ecf8427e. Note that 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 bazel workspace by varying the output base:

  % bazel --output_base /tmp/1 build //foo  &  bazel --output_base /tmp/2 build //bar

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: a foo build first, followed by an incremental build of bar.

We recommend you do not use NFS locations for the output base, as the higher access latency of NFS will cause noticeably slower builds. Also, this places unnecessary loads on the NFS filers.

--output_user_root=dir

By default, the output_base value is chosen to as to avoid conflicts between multiple users building in the same client. In some situations, though, it is desirable to build from a client shared between multiple users; release engineers may do this. In those cases it may be useful to deliberately override the default so as to ensure "conflicts" (i.e., sharing) between multiple users. Use the --output_user_root option to achieve this: the output base is placed in a subdirectory of the output user root, with a unique name based on the workspace, so the result of using an output user root that is not a function of $USER is sharing. Of course, it is important to ensure (via umask and group membership) that all the cooperating users can read/write each others files.

If the --output_base option is specified, it overrides using --output_user_root to calculate the output base.

The install base location is also calculated based on --output_user_root, plus the MD5 identity of the Bazel embedded binaries.

You can also 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.

--host_jvm_args=string

Specifies a space-separated list of startup options 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 //base

This option can be used multiple times with individual arguments. Note that setting this flag should rarely be needed. Default heap size values passed to the JVM from Bazel are set aggressively in both the 32-bit and 64-bit case (3000MB and 10GB, respectively).

(Please note that this does not affect any JVMs used by subprocesses of Bazel: applications, tests, tools, etc. 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 (such as jdb or Eclipse) before calling the main method of Bazel itself. This is primarily intended for use by Bazel developers.

(Please note that this does not affect any JVMs used by subprocesses of Bazel: applications, tests, tools, etc.)

--batch

This switch will cause Bazel to be run in batch mode, instead of the standard client/server mode described above. Doing so provides more predictable semantics with respect to signal handling, job control, and environment variable inheritance.

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, compared to client/server mode. 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.

--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).

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, an automated 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 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]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 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 the options read from the bazelrc file 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 sections from the rc files; for the current command, it also pulls in the options from command:name if such a section exists. Note that it is currently only possible to provide these options on the command line, not in the rc files.

--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.

--logging n

This option controls the level of logging output produced by Bazel. The default level of logging is 3 (INFO log level); higher numbers mean more output. The most detailed output is produced at level = 6. A value of 0 turns logging off.

Note, the logging output is highly technical and not intended for consumption by Bazel users. Instead, we recommend using one of the following more user-friendly options to control the diagnostic information printed by Bazel.

--[no]show_timestamps

If specified, a timestamp is added to each message generated by Bazel specifying the time at which the message was displayed.

Calling Bazel from scripts

Bazel can be called from scripts in order to perform a build, run tests or query the dependency graph. Bazel has been designed to enable effective scripting, but this section lists some details to bear in mind to make your scripts more robust.

Choosing the output base

The --output_base option controls where the Bazel process should write the outputs of a build to, as well as various working files used internally by Bazel, one of which is a lock that guards against concurrent mutation of the output base by multiple Bazel processes.

Choosing the correct output base directory for your script depends on several factors. If you need to put the build outputs in a specific location, this will dictate the output base you need to use. If you are making a "read only" call to Bazel (e.g. bazel query), the locking factors will be more important. In particular, if you need to run multiple instances of your script concurrently, you will need to give each one a different (or random) output base.

If you use the default output base value, you will be contending for the same lock used by the user's interactive Bazel commands. If the user issues long-running commands such as builds, your script will have to wait for those commands to complete before it can continue.

Server or no server?

By default, Bazel uses a long-running server process as an optimization; this behavior can be disabled using the --batch option. There's no hard and fast rule about whether or not your script should use a server, but in general, the trade-off is between performance and reliability. The server mode makes a sequence of builds, especially incremental builds, faster, but its behavior is more complex and prone to failure. We recommend in most cases that you use batch mode unless the performance advantage is critical.

If you do use the server, don't forget to call shutdown when you're finished with it, or, specify --max_idle_secs=5 so that idle servers shut themselves down promptly.

What exit code will I get?

Bazel attempts to differentiate failures due to the source code under consideration from external errors that prevent Bazel from executing properly. Bazel execution can result in following exit codes:

Exit Codes common to all commands: Return codes for commands bazel build, bazel test. For bazel run: For bazel query:

Future Bazel versions may add additional exit codes, replacing generic failure exit code 1 with a different non-zero value with a particular meaning. However, all non-zero exit values will always constitute an error.

Reading the .bazelrc file

By default, Bazel will read the .bazelrc file from the workspace directory or the user's home directory. Whether or not this is desirable is a choice for your script; if your script needs to be perfectly hermetic (e.g. when doing release builds), you should disable reading the .bazelrc file by using the option --bazelrc=/dev/null. If you want to perform a build using the user's preferred settings, the default behavior is better.

Using the Bazel master log

On each build, test, analyze, or coverage command, Bazel will write a readily-parseable summary log. The output is in the form of a line-based grammar, familiar to standard unix tools (grep, sed, sort, awk, etc.).

The master log contains information on the result of each target and test. You'll be able to determine, for instance, if a given target passed the loading phase, but not the analysis phase. We also provide references to test log files and test time information. You can find the master log file with the following command:

% bazel info master-log

Say you were interested in seeing the three longest-running tests in your most recent test command. Here's how you could do it:

% grep '^test ' $(bazel info master-log 2>/dev/null) | awk '{print $5,$2}' | sort -nr | head -n 3
2404 //foo:foo_test
713 //bar:bar_test
624 //baz:baz_test

Master log format

Line ordering is generally unspecified (exceptions are handled on a case-by-case basis), but the file will contain the following contents:

Command log

The Bazel output is also available in a command log file which you can find with the following command:

% bazel info command_log

The command log file 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.

Parsing output

The Bazel output is quite easy to parse for many purposes. Two options that may be helpful for your script are --noshow_progress which suppresses progress messages, and --show_result n, which controls whether or not "build up-to-date" messages are printed; these messages may be parsed to discover which targets were successfully built, and the location of the output files they created. Be sure to specify a very large value of n if you rely on these messages.

Note that it often makes sense to use the master log instead of parsing Bazel output directly.