 INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured). INFO: Found 1 target... Target //foo:foo up-to-date: bazel-bin/foo/foo INFO: Elapsed time: 9.905s, Critical Path: 3.25s INFO: Build completed successfully, 6 total actions INFO: Analyzed target //foo:foo (0 packages loaded, 0 targets configured). INFO: Found 1 target... Target //foo:foo up-to-date: bazel-bin/foo/foo INFO: Elapsed time: 0.144s, Critical Path: 0.00s INFO: Build completed successfully, 1 total action
We see a “null” build: in this case, there are no packages to re-load, since nothing has changed, and no build steps to execute. (If something had changed in “foo” or some of its dependencies, resulting in the re-execution.
Once it has been run, you should not need to run it again until the WORKSPACE file changes.
The distribution directory is another Bazel mechanism to avoid unnecessary downloads. Bazel searches distribution directories before the repository cache. The primary difference is that the distribution directory requires manual preparation.
Using the
--distdir=/path/to-directory. This only works if the
file hash is specified in the WORKSPACE declaration.
While the condition on the file name is not necessary for correctness, it reduces the number of candidate files to one per specified directory. In this way, specifying distribution files directories remains efficient, even if the number of files in such a directory grows large.
Running Bazel in an airgapped environment
To keep Bazel’s binary size small, Bazel’s implicit dependencies are fetched over the network while running for the first time. These implicit dependencies contain toolchains and rules that may not be necessary for everyone. For example, Android tools are unbundled and fetched only when building Android projects.
However, these implicit dependencies may cause problems when running Bazel in an airgapped environment, even if you have vendored all of your WORKSPACE dependencies. To solve that, you can prepare a distribution directory containing these dependencies on a machine with network access, and then transfer them to the airgapped environment with an offline approach.
To prepare the distribution directory, use the
--distdir
flag. You will need to do this once for every new Bazel binary version, since
the implicit dependencies can be different for every release.
To build these dependencies outside of your airgapped environment, first checkout the Bazel source tree at the right version:
git clone "$BAZEL_DIR" cd "$BAZEL_DIR" git checkout "$BAZEL_VERSION"
Then, build the tarball containing the implicit runtime dependencies for that specific Bazel version:
bazel build @additional_distfiles//:archives.tar
Export this tarball to a directory that can be copied into your airgapped
environment. Note the
--strip-components flag, because
--distdir can be
quite finicky with the directory nesting level:
tar xvf bazel-bin/external/additional_distfiles/archives.tar \ -C "$NEW_DIRECTORY" --strip-components=3
Finally, when you use Bazel in your airgapped environment, pass the
--distdir
flag pointing to the directory. For convenience, you can add it as an
.bazelrc
entry:
build --distdir=path/to/directory
We do not recommend this option.
- If you frequently make changes to your request configuration, such as alternating between
-c optand
-c dbgbuilds, or between simple- and cross-compilation, you will typically rebuild the majority of your codebase each time you switch.
When this option is false, the host and request configurations are identical: all tools required during the build will be built in exactly the same way as target programs. This setting means that no libraries need to be built twice during a single build.-executed, and so on, resulting in a very large rebuild. Also, please note: if your host architecture is not capable of running your target binaries, your build will not work.
-, and.
1: Hermeticity means that the action only uses its declared input files and no other files in the filesystem, and it only produces its declared output files.rc, the Bazel configuration file
Bazel accepts many options. Some options are varied frequently (for example,
--subcommands) while others stay the same across several builds (such as
--package_path). To avoid specifying these unchanged options for every build
(and other commands), you can specify options in a configuration file.
Where are the
.bazelrc files?
Bazel looks for optional configuration files in the following locations,
in the order shown below. The options are interpreted in this order, so
options in later files can override a value from an earlier file if a
conflict arises. All options that control which of these files are loaded are
startup options, which means they must occur after
bazel and
before the command (
build,
test, etc).
The system RC file, unless
--nosystem_rcis present.
Path:
- On Linux/macOS/Unixes:
/etc/bazel.bazelrc
- On Windows:
%ProgramData%\bazel.bazelrc
It is not an error if this file does not exist.
If another system-specified location is required, you must build a custom Bazel binary, overriding the
BAZEL_SYSTEM_BAZELRC_PATHvalue in
//src/main/cpp:option_processor. The system-specified location may contain environment variable references, such as
${VAR_NAME}on Unix or
%VAR_NAME%on Windows.
The workspace RC file, unless
--noworkspace_rcis present.
Path:
.bazelrcin your workspace directory (next to the main
WORKSPACEfile).
It is not an error if this file does not exist.
The home RC file, unless
--nohome_rcis present.
Path:
- On Linux/macOS/Unixes:
$HOME/.bazelrc
- On Windows:
%USERPROFILE%\.bazelrcif exists, or
%HOME%/.bazelrc
It is not an error if this file does not exist.
The user-specified RC file, if specified with
--bazelrc=file
This flag is optional. However, if the flag is specified, then the file must exist.
In addition to this optional configuration file, Bazel looks for a global rc file. For more details, see the global bazelrc section.
.bazelrc syntax and semantics
Like all UNIX “rc” files, the
.bazelrc file is a text file with a line-based
grammar. Empty lines and lines starting with
line contains a sequence of words, which are tokenized according to the same
rules as the Bourne shell.
Imports
Lines that start with
import or
try-import are special: use these to load
other “rc” files. To specify a path that is relative to the workspace root,
write
import %workspace%/path/to/bazelrc.
The difference between
import and
try-import is that Bazel fails if the
import‘ed file is missing (or can’t be read), but not so for a
try-import‘ed
file.
Import precedence:
- Options in the imported file take precedence over options specified before the import statement.
- Options specified after the import statement take precedence over the options in the imported file.
- Options in files imported later take precedence over files imported earlier..) For example, the lines:
build --test_tmpdir=/tmp/foo --verbose_failures build --test_tmpdir=/tmp/bar
are combined as:
build --test_tmpdir=/tmp/foo --verbose_failures --test_tmpdir=/tmp/bar
so the effective flags are
--verbose_failures and
--test_tmpdir=/tmp/bar.
Option precedence:
- Options on the command line always take precedence over those in rc files. For example, if a rc file says
build -c optbut the command line flag is
-c dbg, the command line flag takes precedence.
Within the rc file, precedence is governed by specificity: lines for a more specific command take precedence over lines for a less specific command.
Specificity is defined by inheritance. Some commands inherit options from other commands, making the inheriting command more specific than the base command. For example
testinherits from the
buildcommand, so all
bazel buildflags are valid for
bazel test, and all
buildlines apply also to
bazel testunless there’s a
testline for the same option. If the rc file says:
test -c dbg --test_env=PATH build -c opt --verbose_failures
then
bazel build //foowill use
-c opt --verbose_failures, and
bazel test //foowill use
--verbose_failures -c dbg --test_env=PATH.
The inheritance (specificity) graph is:
- Every command inherits from
common
- The following commands inherit from (and are more specific than)
build:
test,
run,
clean,
mobile-install,
info,
print_action,
config,
cquery, and
aquery
coverageinherits from
test
Two lines specifying options for the same command at equal specificity are parsed in the order in which they appear within the file.
- Because this precedence rule does not match the file order, it helps readability if you follow the precedence order within rc files: start with
commonoptions at the top, and end with the most-specific commands at the bottom of the file..
This syntax does not extend to the use of
startup to set
startup options, e.g. setting
startup:config-name --some_startup_option in the .bazelrc will be ignored..
The global bazelrc file
In addition to your personal
.bazelrc file, Bazel reads global bazelrc
files in this order:
$workspace/tools/bazel.rc,
.bazelrc next to the
Bazel binary, and
/etc/bazel.bazelrc. (It’s fine if any are missing.)
You can make Bazel ignore the global bazelrcs by passing the
--nomaster_bazelrc startup option..
41-44- Reserved for Google-internal use.
45- Error publishing results to the Build Event Service.
Return codes for commands
bazel build,
bazel test:
1- Build failed.
3- Build OK, but some tests failed or timed out.
4- Build successful but no tests were found even though testing was requested.
For
bazel run:
1- Build failed.
- If the build succeeds but the executed subprocess returns a non-zero exit code it will be the exit code of the command as well.
For reads
See the Performance Profiling section.